]> git.ipfire.org Git - thirdparty/openssl.git/blame - Configure
Copyright year updates
[thirdparty/openssl.git] / Configure
CommitLineData
de17db91 1#! /usr/bin/env perl
f4d8f037 2# -*- mode: perl; -*-
b6461792 3# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
ac3d0e13 4#
402dd558 5# Licensed under the Apache License 2.0 (the "License"). You may not use
ac3d0e13
RS
6# this file except in compliance with the License. You can obtain a copy
7# in the file LICENSE in the source distribution or at
8# https://www.openssl.org/source/license.html
de17db91 9
a4ed5532 10## Configure -- OpenSSL source tree configuration script
1641cb60 11
d83112b7 12use 5.10.0;
1641cb60 13use strict;
141d7325 14use Config;
cb6afcd6
RL
15use FindBin;
16use lib "$FindBin::Bin/util/perl";
f09e7ca9 17use File::Basename;
7f73eafe 18use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs splitdir/;
dca99383 19use File::Path qw/mkpath/;
1935a586 20use OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt";
8d2214c0 21use OpenSSL::Glob;
1f86b822 22use OpenSSL::Template;
e39795af 23use OpenSSL::config;
1641cb60 24
f828ba03 25# see INSTALL.md for instructions.
462ba4f6 26
8937a4ed
RL
27my $orig_death_handler = $SIG{__DIE__};
28$SIG{__DIE__} = \&death_handler;
29
12e96a23 30my $usage="Usage: Configure [no-<feature> ...] [enable-<feature> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
462ba4f6 31
d0364dcc
RS
32my $banner = <<"EOF";
33
34**********************************************************************
35*** ***
36*** OpenSSL has been successfully configured ***
37*** ***
38*** If you encounter a problem while building, please open an ***
39*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
40*** and include the output from the following command: ***
41*** ***
42*** perl configdata.pm --dump ***
43*** ***
44*** (If you are new to OpenSSL, you might want to consult the ***
45*** 'Troubleshooting' section in the INSTALL.md file first) ***
46*** ***
47**********************************************************************
48EOF
49
434c5dd3 50# Options:
e5f3045f 51#
f09e7ca9
RS
52# --config add the given configuration file, which will be read after
53# any "Configurations*" files that are found in the same
54# directory as this script.
d74dfafd
RL
55# --prefix prefix for the OpenSSL installation, which includes the
56# directories bin, lib, include, share/man, share/doc/openssl
57# This becomes the value of INSTALLTOP in Makefile
58# (Default: /usr/local)
59# --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys.
60# If it's a relative directory, it will be added on the directory
61# given with --prefix.
62# This becomes the value of OPENSSLDIR in Makefile and in C.
63# (Default: PREFIX/ssl)
d0364dcc 64# --banner=".." Output specified text instead of default completion banner
e5f3045f 65#
ecb09baf
RS
66# -w Don't wait after showing a Configure warning
67#
cbfb39d1
AP
68# --cross-compile-prefix Add specified prefix to binutils components.
69#
a6a4d0ac
RL
70# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0
71# Define the public APIs as they were for that version
72# including patch releases. If 'no-deprecated' is also
73# given, do not compile support for interfaces deprecated
74# up to and including the specified OpenSSL version.
98186eb4 75#
5270e702
RL
76# no-hw-xxx do not compile support for specific crypto hardware.
77# Generic OpenSSL-style methods relating to this support
78# are always compiled but return NULL if the hardware
79# support isn't compiled.
80# no-hw do not compile support for any crypto hardware.
5f8d5c96
BM
81# [no-]threads [don't] try to create a library that is suitable for
82# multithreaded applications (default is "threads" if we
83# know how to do it)
fdb11e1b
ČK
84# [no-]thread-pool
85# [don't] allow thread pool functionality
86# [no-]default-thread-pool
87# [don't] allow default thread pool functionality
84f32c84 88# [no-]shared [don't] try to create shared libraries when supported.
ae48242c 89# [no-]pic [don't] try to build position independent code when supported.
45b71abe 90# If disabled, it also disables shared and dynamic-engine.
a723979d 91# no-asm do not use assembler
0423f812 92# no-egd do not compile support for the entropy-gathering daemon APIs
e452de9d 93# [no-]zlib [don't] compile support for zlib compression.
84f32c84 94# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
12e96a23 95# library and will be loaded at run-time by the OpenSSL library.
7e159e01 96# sctp include SCTP support
8a764202 97# no-quic disable QUIC support
5ded1ca6 98# no-uplink Don't build support for UPLINK interface.
8b1a5af3 99# enable-weak-ssl-ciphers
edcdf38b 100# Enable weak ciphers that are disabled by default.
5ae5dc96
AP
101# 386 generate 80386 code in assembly modules
102# no-sse2 disables IA-32 SSE2 code in assembly modules, the above
103# mentioned '386' option implies this one
3a1ee3c1 104# no-<cipher> build without specified algorithm (dsa, idea, rc5, ...)
f246f54f
DMSP
105# -<xxx> +<xxx> All options which are unknown to the 'Configure' script are
106# /<xxx> passed through to the compiler. Unix-style options beginning
107# with a '-' or '+' are recognized, as well as Windows-style
108# options beginning with a '/'. If the option contains arguments
109# separated by spaces, then the URL-style notation %20 can be
110# used for the space character in order to avoid having to quote
111# the option. For example, -opt%20arg gets expanded to -opt arg.
112# In fact, any ASCII character can be encoded as %xx using its
113# hexadecimal encoding.
047d97af
AP
114# -static while -static is also a pass-through compiler option (and
115# as such is limited to environments where it's actually
116# meaningful), it triggers a number configuration options,
31b6ed76 117# namely no-pic, no-shared and no-threads. It is
047d97af
AP
118# argued that the only reason to produce statically linked
119# binaries (and in context it means executables linked with
120# -static flag, and not just executables linked with static
121# libcrypto.a) is to eliminate dependency on specific run-time,
122# a.k.a. libc version. The mentioned config options are meant
123# to achieve just that. Unfortunately on Linux it's impossible
124# to eliminate the dependency completely for openssl executable
125# because of getaddrinfo and gethostbyname calls, which can
126# invoke dynamically loadable library facility anyway to meet
127# the lookup requests. For this reason on Linux statically
128# linked openssl executable has rather debugging value than
129# production quality.
e41c8d6a 130#
84f32c84
DMSP
131# BN_LLONG use the type 'long long' in crypto/bn/bn.h
132# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
d0590fe6
AP
133# Following are set automatically by this script
134#
84f32c84
DMSP
135# MD5_ASM use some extra md5 assembler,
136# SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86
137# RMD160_ASM use some extra ripemd160 assembler,
138# SHA256_ASM sha256_block is implemented in assembler
139# SHA512_ASM sha512_block is implemented in assembler
140# AES_ASM AES_[en|de]crypt is implemented in assembler
d02b48c6 141
3b437400
RL
142# Minimum warning options... any contributions to OpenSSL should at least
143# get past these. Note that we only use these with C compilers, not with
144# C++ compilers.
363bd0b4 145
77305338
RS
146# -DPEDANTIC complements -pedantic and is meant to mask code that
147# is not strictly standard-compliant and/or implementation-specific,
148# e.g. inline assembly, disregards to alignment requirements, such
149# that -pedantic would complain about. Incidentally -DPEDANTIC has
150# to be used even in sanitized builds, because sanitizer too is
151# supposed to and does take notice of non-standard behaviour. Then
152# -pedantic with pre-C9x compiler would also complain about 'long
153# long' not being supported. As 64-bit algorithms are common now,
154# it grew impossible to resolve this without sizeable additional
155# code, so we just tell compiler to be pedantic about everything
156# but 'long long' type.
157
3b437400 158my @gcc_devteam_warn = qw(
a935791d 159 -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG
3b437400 160 -Wall
a935791d 161 -Wmissing-declarations
3b437400
RL
162 -Wextra
163 -Wno-unused-parameter
164 -Wno-missing-field-initializers
165 -Wswitch
166 -Wsign-compare
167 -Wshadow
168 -Wformat
f71ae05a
HL
169 -Wno-type-limits
170 -Wno-tautological-constant-out-of-range-compare
3b437400
RL
171 -Wundef
172 -Werror
173 -Wmissing-prototypes
174 -Wstrict-prototypes
175);
363bd0b4 176
190c8c60
BL
177# These are used in addition to $gcc_devteam_warn when the compiler is clang.
178# TODO(openssl-team): fix problems and investigate if (at least) the
480405e4 179# following warnings can also be enabled:
8bccbce5 180# -Wcast-align
77305338 181# -Wunreachable-code -- no, too ugly/compiler-specific
a773b52a
RS
182# -Wlanguage-extension-token -- no, we use asm()
183# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
184# -Wextended-offsetof -- no, needed in CMS ASN1 code
3b437400 185my @clang_devteam_warn = qw(
03e56683 186 -Wno-unknown-warning-option
3b437400
RL
187 -Wswitch-default
188 -Wno-parentheses-equality
189 -Wno-language-extension-token
190 -Wno-extended-offsetof
d848520a 191 -Wno-missing-braces
3b437400
RL
192 -Wconditional-uninitialized
193 -Wincompatible-pointer-types-discards-qualifiers
3b437400
RL
194 -Wmissing-variable-declarations
195);
cb2bc054 196
b4a7b4ec
RL
197my @cl_devteam_warn = qw(
198 /WX
199);
200
0c28f277
DSH
201my $strict_warnings = 0;
202
b7efa56a 203# As for $BSDthreads. Idea is to maintain "collective" set of flags,
fce0ba5f 204# which would cover all BSD flavors. -pthread applies to them all,
b7efa56a
AP
205# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
206# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
207# which has to be accompanied by explicit -D_THREAD_SAFE and
208# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
209# seems to be sufficient?
9c62a279 210our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
d02b48c6 211
98186eb4 212#
f430ba31 213# API compatibility name to version number mapping.
98186eb4 214#
98186eb4 215my $apitable = {
a6a4d0ac
RL
216 # This table expresses when API additions or changes can occur.
217 # The numbering used changes from 3.0 and on because we updated
218 # (solidified) our version numbering scheme at that point.
219
55affcad 220 # From 3.0 and on, we internalise the given version number in decimal
a6a4d0ac
RL
221 # as MAJOR * 10000 + MINOR * 100 + 0
222 "3.0.0" => 30000,
223 "3.0" => 30000,
224
225 # Note that before 3.0, we didn't have the same version number scheme.
226 # Still, the numbering we use here covers what we need.
227 "1.1.1" => 10101,
228 "1.1.0" => 10100,
229 "1.0.2" => 10002,
230 "1.0.1" => 10001,
231 "1.0.0" => 10000,
232 "0.9.8" => 908,
98186eb4
VD
233};
234
18062615
RL
235# For OpenSSL::config::get_platform
236my %guess_opts = ();
237
238my $dryrun = 0;
239
9e0724a1 240our %table = ();
291e94df 241our %config = ();
98fdbce0 242our %withargs = ();
f770d75b
AP
243our $now_printing; # set to current entry's name in print_table_entry
244 # (todo: right thing would be to encapsulate name
245 # into %target [class] and make print_table_entry
246 # a method)
3e83e686 247
bd5192b1 248# Forward declarations ###############################################
7ead0c89 249
bd5192b1
RL
250# read_config(filename)
251#
252# Reads a configuration file and populates %table with the contents
253# (which the configuration file places in %targets).
254sub read_config;
7d46b942 255
bd5192b1
RL
256# resolve_config(target)
257#
8483a003 258# Resolves all the late evaluations, inheritances and so on for the
bd5192b1
RL
259# chosen target and any target it inherits from.
260sub resolve_config;
7d46b942 261
15c7adb0 262
107b5792
RL
263# Information collection #############################################
264
9fe2bb77 265# Unified build supports separate build dir
ec182ef0
RL
266my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
267my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
610e2b3b
RL
268
269# File::Spec::Unix doesn't detect case insensitivity, so we make sure to
270# check if the source and build directory are really the same, and make
271# them so. This avoids all kinds of confusion later on.
272# We must check @File::Spec::ISA rather than using File::Spec->isa() to
273# know if File::Spec ended up loading File::Spec::Unix.
274$srcdir = $blddir
275 if (grep(/::Unix$/, @File::Spec::ISA)
276 && samedir($srcdir, $blddir));
277
9fe2bb77
RL
278my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
279
b5293d4c
RL
280my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
281
610e2b3b
RL
282$config{sourcedir} = abs2rel($srcdir, $blddir);
283$config{builddir} = abs2rel($blddir, $blddir);
31214258
RS
284# echo -n 'holy hand grenade of antioch' | openssl sha256
285$config{FIPSKEY} =
286 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
9fe2bb77 287
ee4cdb7f
RL
288# Collect reconfiguration information if needed
289my @argvcopy=@ARGV;
290
291if (grep /^reconf(igure)?$/, @argvcopy) {
99aeeecb
RL
292 die "reconfiguring with other arguments present isn't supported"
293 if scalar @argvcopy > 1;
ee4cdb7f 294 if (-f "./configdata.pm") {
84f32c84
DMSP
295 my $file = "./configdata.pm";
296 unless (my $return = do $file) {
297 die "couldn't parse $file: $@" if $@;
ee4cdb7f
RL
298 die "couldn't do $file: $!" unless defined $return;
299 die "couldn't run $file" unless $return;
84f32c84 300 }
ee4cdb7f 301
84f32c84
DMSP
302 @argvcopy = defined($configdata::config{perlargv}) ?
303 @{$configdata::config{perlargv}} : ();
304 die "Incorrect data to reconfigure, please do a normal configuration\n"
305 if (grep(/^reconf/,@argvcopy));
306 $config{perlenv} = $configdata::config{perlenv} // {};
ee4cdb7f 307 } else {
84f32c84 308 die "Insufficient data to reconfigure, please do a normal configuration\n";
ee4cdb7f
RL
309 }
310}
311
312$config{perlargv} = [ @argvcopy ];
313
b16654a2
RL
314# Historical: if known directories in crypto/ have been removed, it means
315# that those sub-systems are disabled.
316# (the other option would be to removed them from the SUBDIRS statement in
317# crypto/build.info)
318# We reverse the input list for cosmetic purely reasons, to compensate that
319# 'unshift' adds at the front of the list (i.e. in reverse input order).
320foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh',
321 'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2',
3a1ee3c1 322 'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha',
b16654a2
RL
323 'sm2', 'sm3', 'sm4') ) {
324 unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_);
325}
326
107b5792 327# Collect version numbers
20551b2e 328my %version = ();
107b5792
RL
329
330collect_information(
036cbb6b 331 collect_from_file(catfile($srcdir,'VERSION.dat')),
20551b2e
RL
332 qr/\s*(\w+)\s*=\s*(.*?)\s*$/ =>
333 sub {
334 # Only define it if there is a value at all
6a960a94
RL
335 if ($2 ne '') {
336 my $k = $1;
337 my $v = $2;
338 # Some values are quoted. Trim the quotes
339 $v = $1 if $v =~ /^"(.*)"$/;
340 $version{uc $k} = $v;
341 }
20551b2e
RL
342 },
343 "OTHERWISE" =>
036cbb6b 344 sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" },
107b5792 345 );
20551b2e
RL
346
347$config{major} = $version{MAJOR} // 'unknown';
348$config{minor} = $version{MINOR} // 'unknown';
349$config{patch} = $version{PATCH} // 'unknown';
350$config{prerelease} =
351 defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : '';
352$config{build_metadata} =
353 defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : '';
354$config{shlib_version} = $version{SHLIB_VERSION} // 'unknown';
355$config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx';
107b5792 356
16942e08
DMSP
357$config{version} = "$config{major}.$config{minor}.$config{patch}";
358$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
359
036cbb6b 360die "erroneous version information in VERSION.dat: ",
20551b2e
RL
361 "$config{version}, $config{shlib_version}\n"
362 unless (defined $version{MAJOR}
363 && defined $version{MINOR}
364 && defined $version{PATCH}
365 && defined $version{SHLIB_VERSION});
366
107b5792
RL
367# Collect target configurations
368
85152ca4 369my $pattern = catfile(dirname($0), "Configurations", "*.conf");
97855556 370foreach (sort glob($pattern)) {
f09e7ca9
RS
371 &read_config($_);
372}
d02b48c6 373
7ecdf18d 374if (defined env($local_config_envname)) {
b5293d4c
RL
375 if ($^O eq 'VMS') {
376 # VMS environment variables are logical names,
377 # which can be used as is
378 $pattern = $local_config_envname . ':' . '*.conf';
379 } else {
7ecdf18d 380 $pattern = catfile(env($local_config_envname), '*.conf');
b5293d4c
RL
381 }
382
97855556 383 foreach (sort glob($pattern)) {
b5293d4c
RL
384 &read_config($_);
385 }
386}
387
0a22436e
WS
388# Fail if no configuration is apparent
389if (!%table) {
390 print "Failed to find any os/compiler configurations. Please make sure the Configurations directory is included.\n";
391 &usage;
392}
393
d5fa7035
RL
394# Save away perl command information
395$config{perl_cmd} = $^X;
396$config{perl_version} = $Config{version};
397$config{perl_archname} = $Config{archname};
398
291e94df
RL
399$config{prefix}="";
400$config{openssldir}="";
7d130f68 401$config{processor}="";
107b5792 402$config{libdir}="";
9c62a279 403my $auto_threads=1; # enable threads automatically? true by default
0396479d 404my $default_ranlib;
107b5792 405
6b01bed2 406# Known TLS and DTLS protocols
84a68336 407my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
6b01bed2
VD
408my @dtls = qw(dtls1 dtls1_2);
409
8483a003 410# Explicitly known options that are possible to disable. They can
8b527be2
RL
411# be regexps, and will be used like this: /^no-${option}$/
412# For developers: keep it sorted alphabetically
413
414my @disablables = (
38230e30 415 "acvp-tests",
c91a0a83 416 "afalgeng",
ff88545e 417 "apps",
6dfa998f 418 "argon2",
d42d0a4d 419 "aria",
c38bb727 420 "asan",
8b527be2 421 "asm",
52739e40 422 "async",
99fb31c1 423 "atexit",
b184e3ef 424 "autoalginit",
498abff0 425 "autoerrinit",
dbabc862 426 "autoload-config",
8b527be2 427 "bf",
2d0b4412 428 "blake2",
12e96a23
TS
429 "brotli",
430 "brotli-dynamic",
ac4033d6 431 "buildtest-c++",
06f81af8 432 "bulk",
1eaf1fc3 433 "cached-fetch",
8b527be2
RL
434 "camellia",
435 "capieng",
606e0426 436 "winstore",
8b527be2 437 "cast",
48f14845 438 "chacha",
8b527be2 439 "cmac",
538f38db 440 "cmp",
8b527be2
RL
441 "cms",
442 "comp",
3e45d393 443 "crypto-mdebug",
8b527be2 444 "ct",
fdb11e1b 445 "default-thread-pool",
8b527be2
RL
446 "deprecated",
447 "des",
619eb33a 448 "devcryptoeng",
8b527be2
RL
449 "dgram",
450 "dh",
956b4c75 451 "docs",
8b527be2 452 "dsa",
3b2f8c77 453 "dso",
a5ecdc6a 454 "dtls",
343ec2b0 455 "dynamic-engine",
8b527be2
RL
456 "ec",
457 "ec2m",
afa0a13c 458 "ec_nistp_64_gcc_128",
6b01bed2
VD
459 "ecdh",
460 "ecdsa",
4032cd9a 461 "ecx",
b31feae6 462 "egd",
8b527be2 463 "engine",
1288f26f 464 "err",
ce2596d4 465 "external-tests",
02f7114a 466 "filenames",
e7545517 467 "fips",
7a810fac 468 "fips-securitychecks",
f59d0131 469 "fuzz-afl",
afa0a13c 470 "fuzz-libfuzzer",
168c3b73 471 "gost",
3ca28c9e 472 "http",
8b527be2 473 "idea",
742ccab3 474 "ktls",
d0308923 475 "legacy",
4b2981f1 476 "loadereng",
09aa263a 477 "makedepend",
8b527be2
RL
478 "md2",
479 "md4",
8b527be2 480 "mdc2",
34786bde 481 "module",
29df3061 482 "msan",
fa22f98f 483 "multiblock",
8b527be2
RL
484 "nextprotoneg",
485 "ocb",
486 "ocsp",
469ce8ff 487 "padlockeng",
ae48242c 488 "pic",
afa0a13c 489 "pinshared",
48f14845 490 "poly1305",
8b527be2
RL
491 "posix-io",
492 "psk",
30b01329 493 "quic",
c0af01f3 494 "unstable-qlog",
8b527be2
RL
495 "rc2",
496 "rc4",
497 "rc5",
498 "rdrand",
499 "rfc3779",
8b527be2 500 "rmd160",
8b527be2 501 "scrypt",
8b527be2 502 "sctp",
6943335e 503 "secure-memory",
8b527be2 504 "seed",
8b527be2 505 "shared",
3f5616d7 506 "siphash",
b1ceb439 507 "siv",
1bf2cc23 508 "sm2",
6399d785 509 "sm2-precomp",
a0c3e4fa 510 "sm3",
f19a5ff9 511 "sm4",
8b527be2
RL
512 "sock",
513 "srp",
514 "srtp",
515 "sse2",
516 "ssl",
8b527be2
RL
517 "ssl-trace",
518 "static-engine",
519 "stdio",
93880ce1 520 "tests",
a3e53d56 521 "tfo",
fdb11e1b 522 "thread-pool",
8b527be2
RL
523 "threads",
524 "tls",
16a9d374 525 "trace",
1288f26f 526 "ts",
c38bb727 527 "ubsan",
48feaceb 528 "ui-console",
8b527be2 529 "unit-test",
5ded1ca6 530 "uplink",
8b1a5af3 531 "weak-ssl-ciphers",
afa0a13c 532 "whirlpool",
8b527be2
RL
533 "zlib",
534 "zlib-dynamic",
caf9317d
TS
535 "zstd",
536 "zstd-dynamic",
8b527be2 537 );
6b01bed2 538foreach my $proto ((@tls, @dtls))
84f32c84
DMSP
539 {
540 push(@disablables, $proto);
541 push(@disablables, "$proto-method") unless $proto eq "tls1_3";
542 }
8b527be2 543
538f38db
RL
544# Internal disablables, for aliasing purposes. They serve no special
545# purpose here, but allow scripts to get to know them through configdata.pm,
546# where these are merged with @disablables.
547# The actual aliasing mechanism is done via %disable_cascades
548my @disablables_int = qw(
549 crmf
550 );
551
2b1343b9
MC
552my %deprecated_disablables = (
553 "ssl2" => undef,
554 "buf-freelists" => undef,
14611382 555 "crypto-mdebug-backtrace" => undef,
469ce8ff
RL
556 "hw" => "hw", # causes cascade, but no macro
557 "hw-padlock" => "padlockeng",
48feaceb
RL
558 "ripemd" => "rmd160",
559 "ui" => "ui-console",
0b45d8ee 560 "heartbeats" => undef,
e80381e1
RL
561 );
562
094925de 563# All of the following are disabled by default:
c9a112f5 564
9e04edf2 565our %disabled = ( # "what" => "comment"
b2d8c7b6 566 "fips" => "default",
84f32c84 567 "asan" => "default",
12e96a23
TS
568 "brotli" => "default",
569 "brotli-dynamic" => "default",
84f32c84
DMSP
570 "buildtest-c++" => "default",
571 "crypto-mdebug" => "default",
572 "crypto-mdebug-backtrace" => "default",
573 "devcryptoeng" => "default",
574 "ec_nistp_64_gcc_128" => "default",
575 "egd" => "default",
576 "external-tests" => "default",
84f32c84 577 "fuzz-afl" => "default",
afa0a13c
DMSP
578 "fuzz-libfuzzer" => "default",
579 "ktls" => "default",
84f32c84 580 "md2" => "default",
29df3061 581 "msan" => "default",
84f32c84
DMSP
582 "rc5" => "default",
583 "sctp" => "default",
84f32c84
DMSP
584 "ssl3" => "default",
585 "ssl3-method" => "default",
a3e53d56 586 "tfo" => "default",
84f32c84
DMSP
587 "trace" => "default",
588 "ubsan" => "default",
589 "unit-test" => "default",
590 "weak-ssl-ciphers" => "default",
591 "zlib" => "default",
592 "zlib-dynamic" => "default",
caf9317d
TS
593 "zstd" => "default",
594 "zstd-dynamic" => "default",
84f32c84 595 );
c9a112f5 596
c569e206
RL
597# Note: => pair form used for aesthetics, not to truly make a hash table
598my @disable_cascades = (
84f32c84 599 # "what" => [ "cascade", ... ]
e3577add 600 "bulk" => [ "shared", "dso",
99fb31c1 601 "aria", "async", "atexit", "autoload-config",
06f81af8
DDO
602 "blake2", "bf", "camellia", "cast", "chacha",
603 "cmac", "cms", "cmp", "comp", "ct",
604 "des", "dgram", "dh", "dsa",
605 "ec", "engine",
606 "filenames",
607 "idea", "ktls",
608 "md4", "multiblock", "nextprotoneg",
609 "ocsp", "ocb", "poly1305", "psk",
610 "rc2", "rc4", "rmd160",
611 "seed", "siphash", "siv",
612 "sm3", "sm4", "srp",
726f92e0 613 "srtp", "ssl3-method", "ssl-trace",
a3e53d56 614 "tfo",
06f81af8
DDO
615 "ts", "ui-console", "whirlpool",
616 "fips-securitychecks" ],
7d130f68 617 sub { $config{processor} eq "386" }
84f32c84
DMSP
618 => [ "sse2" ],
619 "ssl" => [ "ssl3" ],
620 "ssl3-method" => [ "ssl3" ],
621 "zlib" => [ "zlib-dynamic" ],
12e96a23 622 "brotli" => [ "brotli-dynamic" ],
caf9317d 623 "zstd" => [ "zstd-dynamic" ],
84f32c84 624 "des" => [ "mdc2" ],
4032cd9a 625 "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost", "ecx" ],
30b01329 626 "dgram" => [ "dtls", "quic", "sctp" ],
a3e53d56 627 "sock" => [ "dgram", "tfo" ],
84f32c84 628 "dtls" => [ @dtls ],
343a7467 629 sub { 0 == scalar grep { !$disabled{$_} } @dtls }
84f32c84 630 => [ "dtls" ],
c569e206 631
84f32c84 632 "tls" => [ @tls ],
343a7467 633 sub { 0 == scalar grep { !$disabled{$_} } @tls }
84f32c84 634 => [ "tls" ],
0e94bba0 635 "tls1_3" => [ "quic" ],
c0af01f3 636 "quic" => [ "unstable-qlog" ],
c569e206 637
ef8ca6bd 638 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
343ec2b0 639
3d2f96e2 640 "module" => [ "dynamic-engine", "fips" ],
34786bde
RL
641
642 # Without shared libraries, dynamic engines aren't possible.
643 # This is due to them having to link with libcrypto and register features
644 # using the ENGINE functionality, and since that relies on global tables,
e304aa87 645 # those *have* to be exactly the same as the ones accessed from the app,
34786bde
RL
646 # which cannot be guaranteed if shared libraries aren't present.
647 # (note that even with shared libraries, both the app and dynamic engines
648 # must be linked with the same library)
5ded1ca6 649 "shared" => [ "dynamic-engine", "uplink" ],
3b2f8c77 650 "dso" => [ "dynamic-engine", "module" ],
34786bde
RL
651 # Other modules don't necessarily have to link with libcrypto, so shared
652 # libraries do not have to be a condition to produce those.
653
654 # Without position independent code, there can be no shared libraries
655 # or modules.
656 "pic" => [ "shared", "module" ],
469ce8ff 657
b8fa02e8 658 "engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ],
86ff7cf2 659 "dynamic-engine" => [ "loadereng" ],
469ce8ff 660 "hw" => [ "padlockeng" ],
d90a6beb
MC
661
662 # no-autoalginit is only useful when building non-shared
9c11e8ec 663 "autoalginit" => [ "shared", "apps", "fips" ],
d90a6beb 664
15a1bd0a 665 "stdio" => [ "apps", "capieng", "egd" ],
d90a6beb 666 "apps" => [ "tests" ],
302eba3f 667 "tests" => [ "external-tests" ],
caf9317d 668 "comp" => [ "zlib", "brotli", "zstd" ],
98020023 669 "sm3" => [ "sm2" ],
b612799a 670 sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
29df3061
EK
671
672 sub { !$disabled{"msan"} } => [ "asm" ],
b1ceb439 673
6d2a1eff
MC
674 "cmac" => [ "siv" ],
675 "legacy" => [ "md2" ],
538f38db
RL
676
677 "cmp" => [ "crmf" ],
c72fa255 678
c3c00c7a 679 "fips" => [ "fips-securitychecks", "acvp-tests" ],
ccdfcf07 680
4574a7fd
ČK
681 "threads" => [ "thread-pool" ],
682 "thread-pool" => [ "default-thread-pool" ],
683
6dfa998f
ČK
684 "blake2" => [ "argon2" ],
685
3ca28c9e
VK
686 "deprecated-3.0" => [ "engine", "srp" ],
687
688 "http" => [ "ocsp" ]
c569e206
RL
689 );
690
691# Avoid protocol support holes. Also disable all versions below N, if version
692# N is disabled while N+1 is enabled.
693#
694my @list = (reverse @tls);
695while ((my $first, my $second) = (shift @list, shift @list)) {
696 last unless @list;
697 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
84f32c84 698 => [ @list ] );
c569e206
RL
699 unshift @list, $second;
700}
701my @list = (reverse @dtls);
702while ((my $first, my $second) = (shift @list, shift @list)) {
703 last unless @list;
704 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
84f32c84 705 => [ @list ] );
c569e206
RL
706 unshift @list, $second;
707}
708
7a762197 709# Explicit "no-..." options will be collected in %disabled along with the defaults.
e4ef2e25 710# To remove something from %disabled, use "enable-foo".
7a762197
BM
711# For symmetry, "disable-foo" is a synonym for "no-foo".
712
bbe486cf 713# For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with
5b18235a
RL
714# platform specific list separators. Users from those platforms should
715# recognise those separators from how you set up the PATH to find executables.
716# The default is the Unix like separator, :, but as an exception, we also
717# support the space as separator.
718my $list_separator_re =
719 { VMS => qr/(?<!\^),/,
720 MSWin32 => qr/(?<!\\);/ } -> {$^O} // qr/(?<!\\)[:\s]/;
721# All the "make variables" we support
f5846179
RL
722# Some get pre-populated for the sake of backward compatibility
723# (we supported those before the change to "make variable" support.
5b18235a 724my %user = (
f5846179 725 AR => env('AR'),
5b18235a
RL
726 ARFLAGS => [],
727 AS => undef,
728 ASFLAGS => [],
f5846179 729 CC => env('CC'),
8e7984e5 730 CFLAGS => [ env('CFLAGS') || () ],
f5846179 731 CXX => env('CXX'),
8e7984e5 732 CXXFLAGS => [ env('CXXFLAGS') || () ],
5b18235a 733 CPP => undef,
8e7984e5 734 CPPFLAGS => [ env('CPPFLAGS') || () ], # -D, -I, -Wp,
5b18235a
RL
735 CPPDEFINES => [], # Alternative for -D
736 CPPINCLUDES => [], # Alternative for -I
f5846179
RL
737 CROSS_COMPILE => env('CROSS_COMPILE'),
738 HASHBANGPERL=> env('HASHBANGPERL') || env('PERL'),
5b18235a 739 LD => undef,
8e7984e5
RL
740 LDFLAGS => [ env('LDFLAGS') || () ], # -L, -Wl,
741 LDLIBS => [ env('LDLIBS') || () ], # -l
5b18235a
RL
742 MT => undef,
743 MTFLAGS => [],
9e265322 744 PERL => env('PERL') || ($^O ne "VMS" ? $^X : "perl"),
f5846179
RL
745 RANLIB => env('RANLIB'),
746 RC => env('RC') || env('WINDRES'),
0c4e984d 747 RCFLAGS => [ env('RCFLAGS') || () ],
5b18235a
RL
748 RM => undef,
749 );
f729ba55
RL
750# Info about what "make variables" may be prefixed with the cross compiler
751# prefix. This should NEVER mention any such variable with a list for value.
752my @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC );
5b18235a
RL
753# The same but for flags given as Configure options. These are *additional*
754# input, as opposed to the VAR=string option that override the corresponding
755# config target attributes
756my %useradd = (
d9b811dc 757 ASFLAGS => [],
5b18235a
RL
758 CPPDEFINES => [],
759 CPPINCLUDES => [],
760 CPPFLAGS => [],
761 CFLAGS => [],
762 CXXFLAGS => [],
763 LDFLAGS => [],
764 LDLIBS => [],
0c4e984d 765 RCFLAGS => [],
5b18235a
RL
766 );
767
768my %user_synonyms = (
769 HASHBANGPERL=> 'PERL',
770 RC => 'WINDRES',
771 );
abe256e7
RL
772
773# Some target attributes have been renamed, this is the translation table
774my %target_attr_translate =(
775 ar => 'AR',
776 as => 'AS',
777 cc => 'CC',
778 cxx => 'CXX',
779 cpp => 'CPP',
780 hashbangperl => 'HASHBANGPERL',
781 ld => 'LD',
782 mt => 'MT',
783 ranlib => 'RANLIB',
784 rc => 'RC',
785 rm => 'RM',
5b18235a 786 );
5b18235a 787
2ab92ae9 788# Initialisers coming from 'config' scripts
ff455d99
AP
789$config{defines} = [ split(/$list_separator_re/, env('__CNF_CPPDEFINES')) ];
790$config{includes} = [ split(/$list_separator_re/, env('__CNF_CPPINCLUDES')) ];
791$config{cppflags} = [ env('__CNF_CPPFLAGS') || () ];
792$config{cflags} = [ env('__CNF_CFLAGS') || () ];
793$config{cxxflags} = [ env('__CNF_CXXFLAGS') || () ];
794$config{lflags} = [ env('__CNF_LDFLAGS') || () ];
795$config{ex_libs} = [ env('__CNF_LDLIBS') || () ];
2ab92ae9 796
7d130f68 797$config{openssl_api_defines}=[];
7d130f68 798$config{openssl_sys_defines}=[];
e0bf7c01 799$config{openssl_feature_defines}=[];
3fa04f0d 800$config{options}="";
8864f0de 801$config{build_type} = "release";
5b18235a 802my $target="";
c59cb511 803
ac6ae8a9 804my %cmdvars = (); # Stores FOO='blah' type arguments
fe05264e 805my %unsupported_options = ();
e80381e1 806my %deprecated_options = ();
8389ec4b
RS
807# If you change this, update apps/version.c
808my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
809my @seed_sources = ();
fad599f7 810while (@argvcopy)
84f32c84
DMSP
811 {
812 $_ = shift @argvcopy;
813
814 # Support env variable assignments among the options
815 if (m|^(\w+)=(.+)?$|)
816 {
817 $cmdvars{$1} = $2;
818 # Every time a variable is given as a configuration argument,
819 # it acts as a reset if the variable.
820 if (exists $user{$1})
821 {
822 $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef;
823 }
824 #if (exists $useradd{$1})
825 # {
826 # $useradd{$1} = [];
827 # }
828 next;
829 }
830
831 # VMS is a case insensitive environment, and depending on settings
832 # out of our control, we may receive options uppercased. Let's
833 # downcase at least the part before any equal sign.
834 if ($^O eq "VMS")
835 {
836 s/^([^=]*)/lc($1)/e;
837 }
838
839 # some people just can't read the instructions, clang people have to...
840 s/^-no-(?!integrated-as)/no-/;
841
842 # rewrite some options in "enable-..." form
843 s /^-?-?shared$/enable-shared/;
844 s /^sctp$/enable-sctp/;
845 s /^threads$/enable-threads/;
846 s /^zlib$/enable-zlib/;
847 s /^zlib-dynamic$/enable-zlib-dynamic/;
cc9f9b98 848 s /^fips$/enable-fips/;
c9a112f5 849
e4ef2e25 850 if (/^(no|disable|enable)-(.+)$/)
2b1343b9
MC
851 {
852 my $word = $2;
469ce8ff
RL
853 if ($word !~ m|hw(?:-.+)| # special treatment for hw regexp opt
854 && !exists $deprecated_disablables{$word}
855 && !grep { $word eq $_ } @disablables)
2b1343b9
MC
856 {
857 $unsupported_options{$_} = 1;
858 next;
859 }
860 }
861 if (/^no-(.+)$/ || /^disable-(.+)$/)
862 {
e4ef2e25
RS
863 foreach my $proto ((@tls, @dtls))
864 {
865 if ($1 eq "$proto-method")
866 {
867 $disabled{"$proto"} = "option($proto-method)";
868 last;
869 }
870 }
871 if ($1 eq "dtls")
872 {
873 foreach my $proto (@dtls)
874 {
875 $disabled{$proto} = "option(dtls)";
876 }
c5c7700c 877 $disabled{"dtls"} = "option(dtls)";
e4ef2e25
RS
878 }
879 elsif ($1 eq "ssl")
880 {
881 # Last one of its kind
882 $disabled{"ssl3"} = "option(ssl)";
883 }
884 elsif ($1 eq "tls")
885 {
886 # XXX: Tests will fail if all SSL/TLS
887 # protocols are disabled.
888 foreach my $proto (@tls)
889 {
890 $disabled{$proto} = "option(tls)";
891 }
892 }
343ec2b0
RL
893 elsif ($1 eq "static-engine")
894 {
19ab5790 895 delete $disabled{"dynamic-engine"};
343ec2b0
RL
896 }
897 elsif ($1 eq "dynamic-engine")
898 {
19ab5790 899 $disabled{"dynamic-engine"} = "option";
343ec2b0 900 }
2b1343b9
MC
901 elsif (exists $deprecated_disablables{$1})
902 {
903 $deprecated_options{$_} = 1;
904 if (defined $deprecated_disablables{$1})
905 {
906 $disabled{$deprecated_disablables{$1}} = "option";
907 }
908 }
469ce8ff
RL
909 elsif ($1 =~ m|hw(?:-.+)|) # deprecate hw options in regexp form
910 {
911 $deprecated_options{$_} = 1;
912 }
e4ef2e25
RS
913 else
914 {
915 $disabled{$1} = "option";
916 }
84f32c84
DMSP
917 # No longer an automatic choice
918 $auto_threads = 0 if ($1 eq "threads");
919 }
920 elsif (/^enable-(.+)$/)
921 {
343ec2b0
RL
922 if ($1 eq "static-engine")
923 {
19ab5790 924 $disabled{"dynamic-engine"} = "option";
343ec2b0
RL
925 }
926 elsif ($1 eq "dynamic-engine")
927 {
19ab5790 928 delete $disabled{"dynamic-engine"};
343ec2b0 929 }
25004db7
RL
930 elsif ($1 eq "zlib-dynamic")
931 {
932 delete $disabled{"zlib"};
933 }
12e96a23
TS
934 elsif ($1 eq "brotli-dynamic")
935 {
936 delete $disabled{"brotli"};
937 }
caf9317d
TS
938 elsif ($1 eq "zstd-dynamic")
939 {
940 delete $disabled{"zstd"};
941 }
84f32c84
DMSP
942 my $algo = $1;
943 delete $disabled{$algo};
944
945 # No longer an automatic choice
946 $auto_threads = 0 if ($1 eq "threads");
947 }
18062615
RL
948 elsif (/^-d$/) # From older 'config'
949 {
950 $config{build_type} = "debug";
951 }
952 elsif (/^-v$/) # From older 'config'
953 {
954 $guess_opts{verbose} = 1;
955 }
ecb09baf 956 elsif (/^-w$/)
18062615
RL
957 {
958 $guess_opts{nowait} = 1;
959 }
960 elsif (/^-t$/) # From older 'config'
961 {
962 $dryrun = 1;
963 }
84f32c84
DMSP
964 elsif (/^--strict-warnings$/)
965 {
966 # Pretend that our strict flags is a C flag, and replace it
967 # with the proper flags later on
968 push @{$useradd{CFLAGS}}, '--ossl-strict-warnings';
84f32c84
DMSP
969 $strict_warnings=1;
970 }
971 elsif (/^--debug$/)
972 {
973 $config{build_type} = "debug";
974 }
975 elsif (/^--release$/)
976 {
977 $config{build_type} = "release";
978 }
979 elsif (/^386$/)
980 { $config{processor}=386; }
84f32c84
DMSP
981 elsif (/^rsaref$/)
982 {
983 # No RSAref support any more since it's not needed.
984 # The check for the option is there so scripts aren't
985 # broken
986 }
f246f54f 987 elsif (m|^[-+/]|)
84f32c84
DMSP
988 {
989 if (/^--prefix=(.*)$/)
990 {
991 $config{prefix}=$1;
84f32c84
DMSP
992 }
993 elsif (/^--api=(.*)$/)
994 {
a6a4d0ac
RL
995 my $api = $1;
996 die "Unknown API compatibility level $api"
997 unless defined $apitable->{$api};
998 $config{api}=$apitable->{$api};
84f32c84
DMSP
999 }
1000 elsif (/^--libdir=(.*)$/)
1001 {
1002 $config{libdir}=$1;
1003 }
1004 elsif (/^--openssldir=(.*)$/)
1005 {
1006 $config{openssldir}=$1;
1007 }
1008 elsif (/^--with-zlib-lib=(.*)$/)
1009 {
1010 $withargs{zlib_lib}=$1;
1011 }
1012 elsif (/^--with-zlib-include=(.*)$/)
1013 {
1014 $withargs{zlib_include}=$1;
1015 }
12e96a23
TS
1016 elsif (/^--with-brotli-lib=(.*)$/)
1017 {
1018 $withargs{brotli_lib}=$1;
1019 }
1020 elsif (/^--with-brotli-include=(.*)$/)
1021 {
1022 $withargs{brotli_include}=$1;
1023 }
caf9317d
TS
1024 elsif (/^--with-zstd-lib=(.*)$/)
1025 {
1026 $withargs{zstd_lib}=$1;
1027 }
1028 elsif (/^--with-zstd-include=(.*)$/)
1029 {
1030 $withargs{zstd_include}=$1;
1031 }
84f32c84
DMSP
1032 elsif (/^--with-fuzzer-lib=(.*)$/)
1033 {
1034 $withargs{fuzzer_lib}=$1;
1035 }
1036 elsif (/^--with-fuzzer-include=(.*)$/)
1037 {
1038 $withargs{fuzzer_include}=$1;
1039 }
1040 elsif (/^--with-rand-seed=(.*)$/)
1041 {
1042 foreach my $x (split(m|,|, $1))
1043 {
1044 die "Unknown --with-rand-seed choice $x\n"
1045 if ! grep { $x eq $_ } @known_seed_sources;
1046 push @seed_sources, $x;
1047 }
1048 }
31214258
RS
1049 elsif (/^--fips-key=(.*)$/)
1050 {
1051 $user{FIPSKEY}=lc($1);
1052 die "Non-hex character in FIPS key\n"
1053 if $user{FIPSKEY} =~ /[^a-f0-9]/;
1054 die "FIPS key must have even number of characters\n"
1055 if length $1 & 1;
1056 die "FIPS key too long (64 bytes max)\n"
1057 if length $1 > 64;
1058 }
d0364dcc
RS
1059 elsif (/^--banner=(.*)$/)
1060 {
1061 $banner = $1 . "\n";
1062 }
84f32c84
DMSP
1063 elsif (/^--cross-compile-prefix=(.*)$/)
1064 {
1065 $user{CROSS_COMPILE}=$1;
1066 }
1067 elsif (/^--config=(.*)$/)
1068 {
1069 read_config $1;
1070 }
1071 elsif (/^-l(.*)$/)
1072 {
1073 push @{$useradd{LDLIBS}}, $_;
1074 }
1075 elsif (/^-framework$/)
1076 {
1077 push @{$useradd{LDLIBS}}, $_, shift(@argvcopy);
1078 }
1079 elsif (/^-L(.*)$/ or /^-Wl,/)
1080 {
1081 push @{$useradd{LDFLAGS}}, $_;
1082 }
1083 elsif (/^-rpath$/ or /^-R$/)
1084 # -rpath is the OSF1 rpath flag
1085 # -R is the old Solaris rpath flag
1086 {
1087 my $rpath = shift(@argvcopy) || "";
1088 $rpath .= " " if $rpath ne "";
1089 push @{$useradd{LDFLAGS}}, $_, $rpath;
1090 }
1091 elsif (/^-static$/)
1092 {
1093 push @{$useradd{LDFLAGS}}, $_;
84f32c84 1094 }
f246f54f 1095 elsif (m|^[-/]D(.*)$|)
84f32c84
DMSP
1096 {
1097 push @{$useradd{CPPDEFINES}}, $1;
1098 }
f246f54f 1099 elsif (m|^[-/]I(.*)$|)
84f32c84
DMSP
1100 {
1101 push @{$useradd{CPPINCLUDES}}, $1;
1102 }
1103 elsif (/^-Wp,$/)
1104 {
1105 push @{$useradd{CPPFLAGS}}, $1;
1106 }
1107 else # common if (/^[-+]/), just pass down...
1108 {
f246f54f
DMSP
1109 # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1110 # This provides a simple way to pass options with arguments separated
1111 # by spaces without quoting (e.g. -opt%20arg translates to -opt arg).
84f32c84
DMSP
1112 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1113 push @{$useradd{CFLAGS}}, $_;
1114 push @{$useradd{CXXFLAGS}}, $_;
8389ec4b 1115 }
84f32c84 1116 }
f246f54f
DMSP
1117 elsif (m|^/|)
1118 {
1119 # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1120 # This provides a simple way to pass options with arguments separated
1121 # by spaces without quoting (e.g. /opt%20arg translates to /opt arg).
1122 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1123 push @{$useradd{CFLAGS}}, $_;
1124 push @{$useradd{CXXFLAGS}}, $_;
1125 }
84f32c84
DMSP
1126 else
1127 {
1128 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
1129 $target=$_;
1130 }
1131 unless ($_ eq $target || /^no-/ || /^disable-/)
1132 {
1133 # "no-..." follows later after implied deactivations
1134 # have been derived. (Don't take this too seriously,
1135 # we really only write OPTIONS to the Makefile out of
1136 # nostalgia.)
1137
1138 if ($config{options} eq "")
1139 { $config{options} = $_; }
1140 else
1141 { $config{options} .= " ".$_; }
1142 }
1143 }
489eb740 1144
ddbe700e 1145if (keys %deprecated_options)
84f32c84
DMSP
1146 {
1147 warn "***** Deprecated options: ",
1148 join(", ", keys %deprecated_options), "\n";
1149 }
ddbe700e 1150if (keys %unsupported_options)
84f32c84
DMSP
1151 {
1152 die "***** Unsupported options: ",
1153 join(", ", keys %unsupported_options), "\n";
1154 }
b6e4dac2 1155
ac6ae8a9
RL
1156# If any %useradd entry has been set, we must check that the "make
1157# variables" haven't been set. We start by checking of any %useradd entry
fb174faa 1158# is set.
b9201360 1159if (grep { scalar @$_ > 0 } values %useradd) {
fb174faa 1160 # Hash of env / make variables names. The possible values are:
ac6ae8a9 1161 # 1 - "make vars"
fb174faa
RL
1162 # 2 - %useradd entry set
1163 # 3 - both set
ac6ae8a9 1164 my %detected_vars =
fb174faa 1165 map { my $v = 0;
ac6ae8a9 1166 $v += 1 if $cmdvars{$_};
fb174faa
RL
1167 $v += 2 if @{$useradd{$_}};
1168 $_ => $v }
1169 keys %useradd;
1170
ac6ae8a9
RL
1171 # If any of the corresponding "make variables" is set, we error
1172 if (grep { $_ & 1 } values %detected_vars) {
1173 my $names = join(', ', grep { $detected_vars{$_} > 0 }
1174 sort keys %detected_vars);
b9201360 1175 die <<"_____";
ac6ae8a9 1176***** Mixing make variables and additional compiler/linker flags as
b9201360 1177***** configure command line option is not permitted.
ac6ae8a9 1178***** Affected make variables: $names
b9201360
RL
1179_____
1180 }
1181}
1182
ac6ae8a9
RL
1183# Check through all supported command line variables to see if any of them
1184# were set, and canonicalise the values we got. If no compiler or linker
1185# flag or anything else that affects %useradd was set, we also check the
1186# environment for values.
1187my $anyuseradd =
1188 grep { defined $_ && (ref $_ ne 'ARRAY' || @$_) } values %useradd;
5b18235a 1189foreach (keys %user) {
ac6ae8a9
RL
1190 my $value = $cmdvars{$_};
1191 $value //= env($_) unless $anyuseradd;
1192 $value //=
1193 defined $user_synonyms{$_} ? $cmdvars{$user_synonyms{$_}} : undef;
1194 $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef
1195 unless $anyuseradd;
5b18235a
RL
1196
1197 if (defined $value) {
1198 if (ref $user{$_} eq 'ARRAY') {
bbe486cf
RL
1199 if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') {
1200 $user{$_} = [ split /$list_separator_re/, $value ];
1201 } else {
1202 $user{$_} = [ $value ];
1203 }
5b18235a
RL
1204 } elsif (!defined $user{$_}) {
1205 $user{$_} = $value;
1206 }
1207 }
1208}
1209
07e4dc34 1210if (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ())
342a1a23
RL
1211 && !$disabled{shared}
1212 && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
1213 die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
84f32c84 1214 "***** any of asan, msan or ubsan\n";
342a1a23
RL
1215}
1216
e39795af
RL
1217# If no target was given, try guessing.
1218unless ($target) {
18062615 1219 my %system_config = OpenSSL::config::get_platform(%guess_opts, %user);
e39795af
RL
1220
1221 # The $system_config{disable} is used to populate %disabled with
1222 # entries that aren't already there.
1223 foreach ( @{$system_config{disable} // []} ) {
1224 $disabled{$_} = 'system' unless defined $disabled{$_};
1225 }
1226 delete $system_config{disable};
1227
1228 # Override config entries with stuff from the guesser.
1229 # It's assumed that this really is nothing new.
1230 %config = ( %config, %system_config );
1231 $target = $system_config{target};
1232}
1233
71ef78d7
RL
1234sub disable {
1235 my $disable_type = shift;
1236
1237 for (@_) {
1238 $disabled{$_} = $disable_type;
1239 }
1240
1241 my @tocheckfor = (@_ ? @_ : keys %disabled);
1242 while (@tocheckfor) {
1243 my %new_tocheckfor = ();
1244 my @cascade_copy = (@disable_cascades);
1245 while (@cascade_copy) {
1246 my ($test, $descendents) =
1247 (shift @cascade_copy, shift @cascade_copy);
1248 if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
1249 foreach (grep { !defined($disabled{$_}) } @$descendents) {
1250 $new_tocheckfor{$_} = 1; $disabled{$_} = "cascade";
1251 }
84f32c84
DMSP
1252 }
1253 }
71ef78d7 1254 @tocheckfor = (keys %new_tocheckfor);
c569e206 1255 }
c569e206 1256}
71ef78d7 1257disable(); # First cascade run
edc032b5 1258
d63c12c6 1259our $die = sub { die @_; };
436a376b 1260if ($target eq "TABLE") {
d63c12c6 1261 local $die = sub { warn @_; };
00ae96ca 1262 foreach (sort keys %table) {
84f32c84 1263 print_table_entry($_, "TABLE");
00ae96ca
RL
1264 }
1265 exit 0;
436a376b
BM
1266}
1267
10a926c1 1268if ($target eq "LIST") {
00ae96ca 1269 foreach (sort keys %table) {
84f32c84 1270 print $_,"\n" unless $table{$_}->{template};
00ae96ca
RL
1271 }
1272 exit 0;
10a926c1
UM
1273}
1274
aaf878cc 1275if ($target eq "HASH") {
d63c12c6 1276 local $die = sub { warn @_; };
00ae96ca
RL
1277 print "%table = (\n";
1278 foreach (sort keys %table) {
84f32c84 1279 print_table_entry($_, "HASH");
00ae96ca
RL
1280 }
1281 exit 0;
aaf878cc
RL
1282}
1283
16942e08
DMSP
1284print "Configuring OpenSSL version $config{full_version} ";
1285print "for target $target\n";
64119271 1286
51cf8e0b
RL
1287if (scalar(@seed_sources) == 0) {
1288 print "Using os-specific seed configuration\n";
1289 push @seed_sources, 'os';
1290}
ddec332f
BE
1291if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) {
1292 delete $disabled{'egd'};
1293}
2805ee1e
RL
1294if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
1295 die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
1296 warn <<_____ if scalar(@seed_sources) == 1;
2805ee1e 1297
caa85952
DMSP
1298============================== WARNING ===============================
1299You have selected the --with-rand-seed=none option, which effectively
1300disables automatic reseeding of the OpenSSL random generator.
1301All operations depending on the random generator such as creating keys
1302will not work unless the random generator is seeded manually by the
1303application.
1304
1305Please read the 'Note on random number generation' section in the
f828ba03
RL
1306INSTALL.md instructions and the RAND_DRBG(7) manual page for more
1307details.
caa85952
DMSP
1308============================== WARNING ===============================
1309
2805ee1e
RL
1310_____
1311}
e0bf7c01 1312push @{$config{openssl_feature_defines}},
51cf8e0b 1313 map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
84f32c84 1314 @seed_sources;
51cf8e0b 1315
00ae96ca 1316# Backward compatibility?
49e04548 1317if ($target =~ m/^CygWin32(-.*)$/) {
00ae96ca 1318 $target = "Cygwin".$1;
49e04548
RL
1319}
1320
906eb3d0
RL
1321# Support for legacy targets having a name starting with 'debug-'
1322my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
1323if ($d) {
1324 $config{build_type} = "debug";
1325
1326 # If we do not find debug-foo in the table, the target is set to foo.
1327 if (!$table{$target}) {
84f32c84 1328 $target = $t;
906eb3d0
RL
1329 }
1330}
4e360445 1331
081436bf
RL
1332if ($target) {
1333 # It's possible that we have different config targets for specific
1334 # toolchains, so we try to detect them, and go for the plain config
1335 # target if not.
1336 my $found;
1337 foreach ( ( "$target-$user{CC}", "$target", undef ) ) {
1338 $found=$_ if $table{$_} && !$table{$_}->{template};
1339 last if $found;
1340 }
1341 $target = $found;
1342} else {
1343 # If we don't have a config target now, we try the C compiler as we
1344 # fallback
1345 my $cc = $user{CC} // 'cc';
1346 $target = $cc if $table{$cc} && !$table{$cc}->{template};
1347}
1348
1349&usage unless $target;
4e360445 1350
18062615
RL
1351exit 0 if $dryrun; # From older 'config'
1352
906eb3d0
RL
1353$config{target} = $target;
1354my %target = resolve_config($target);
1355
abe256e7
RL
1356foreach (keys %target_attr_translate) {
1357 $target{$target_attr_translate{$_}} = $target{$_}
1358 if $target{$_};
1359 delete $target{$_};
1360}
1361
793077d0
RL
1362%target = ( %{$table{DEFAULTS}}, %target );
1363
906eb3d0
RL
1364my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
1365$config{conf_files} = [ sort keys %conf_files ];
906eb3d0 1366
71ef78d7
RL
1367# Using sub disable within these loops may prove fragile, so we run
1368# a cascade afterwards
906eb3d0
RL
1369foreach my $feature (@{$target{disable}}) {
1370 if (exists $deprecated_disablables{$feature}) {
1371 warn "***** config $target disables deprecated feature $feature\n";
1372 } elsif (!grep { $feature eq $_ } @disablables) {
1373 die "***** config $target disables unknown feature $feature\n";
1374 }
1375 $disabled{$feature} = 'config';
1376}
1377foreach my $feature (@{$target{enable}}) {
7a8a35ff 1378 if ("default" eq ($disabled{$feature} // "")) {
906eb3d0
RL
1379 if (exists $deprecated_disablables{$feature}) {
1380 warn "***** config $target enables deprecated feature $feature\n";
1381 } elsif (!grep { $feature eq $_ } @disablables) {
1382 die "***** config $target enables unknown feature $feature\n";
1383 }
7a8a35ff 1384 delete $disabled{$feature};
906eb3d0
RL
1385 }
1386}
b19fe714
RL
1387
1388# If uplink_arch isn't defined, disable uplink
1389$disabled{uplink} = 'no uplink_arch' unless (defined $target{uplink_arch});
e6f98ae4
RL
1390# If asm_arch isn't defined, disable asm
1391$disabled{asm} = 'no asm_arch' unless (defined $target{asm_arch});
b19fe714 1392
71ef78d7 1393disable(); # Run a cascade now
906eb3d0 1394
abe256e7
RL
1395$target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX};
1396$target{cxxflags}//=$target{cflags} if $target{CXX};
9dd4ed28 1397$target{exe_extension}=".exe" if ($config{target} eq "DJGPP");
107b5792 1398$target{exe_extension}=".pm" if ($config{target} =~ /vos/);
e987f9f2 1399
9e265322
RL
1400# Fill %config with values from %user, and in case those are undefined or
1401# empty, use values from %target (acting as a default).
5b18235a 1402foreach (keys %user) {
5b18235a
RL
1403 my $ref_type = ref $user{$_};
1404
1405 # Temporary function. Takes an intended ref type (empty string or "ARRAY")
1406 # and a value that's to be coerced into that type.
1407 my $mkvalue = sub {
1408 my $type = shift;
1409 my $value = shift;
1410 my $undef_p = shift;
1411
1412 die "Too many arguments for \$mkvalue" if @_;
1413
1414 while (ref $value eq 'CODE') {
1415 $value = $value->();
1416 }
1417
1418 if ($type eq 'ARRAY') {
1419 return undef unless defined $value;
1420 return undef if ref $value ne 'ARRAY' && !$value;
1421 return undef if ref $value eq 'ARRAY' && !@$value;
1422 return [ $value ] unless ref $value eq 'ARRAY';
1423 }
1424 return undef unless $value;
1425 return $value;
1426 };
1427
abe256e7 1428 $config{$_} =
5b18235a 1429 $mkvalue->($ref_type, $user{$_})
abe256e7
RL
1430 || $mkvalue->($ref_type, $target{$_});
1431 delete $config{$_} unless defined $config{$_};
5b18235a 1432}
aaf878cc 1433
c1a09254
RL
1434# Finish up %config by appending things the user gave us on the command line
1435# apart from "make variables"
1436foreach (keys %useradd) {
1437 # The must all be lists, so we assert that here
1438 die "internal error: \$useradd{$_} isn't an ARRAY\n"
1439 unless ref $useradd{$_} eq 'ARRAY';
1440
1441 if (defined $config{$_}) {
1442 push @{$config{$_}}, @{$useradd{$_}};
1443 } else {
1444 $config{$_} = [ @{$useradd{$_}} ];
1445 }
1446}
1447# At this point, we can forget everything about %user and %useradd,
1448# because it's now all been merged into the corresponding $config entry
1449
4ea75299
VS
1450if ($config{prefix} && !$config{CROSS_COMPILE}) {
1451 die "Directory given with --prefix MUST be absolute\n"
1452 unless file_name_is_absolute($config{prefix});
1453}
1454
0221b080
TC
1455if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) {
1456 disable('static', 'pic', 'threads');
1457}
1458
8b5156d1 1459# Allow overriding the build file name
5b18235a 1460$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
bd5192b1 1461
291e94df
RL
1462# Make sure build_scheme is consistent.
1463$target{build_scheme} = [ $target{build_scheme} ]
1464 if ref($target{build_scheme}) ne "ARRAY";
1465
ddf1847d
RL
1466my ($builder, $builder_platform, @builder_opts) =
1467 @{$target{build_scheme}};
1468
aa2d7e0e 1469foreach my $checker (($builder_platform."-".$config{build_file}."-checker.pm",
d192a3aa
RL
1470 $builder_platform."-checker.pm")) {
1471 my $checker_path = catfile($srcdir, "Configurations", $checker);
1472 if (-f $checker_path) {
1473 my $fn = $ENV{CONFIGURE_CHECKER_WARN}
1474 ? sub { warn $@; } : sub { die $@; };
1475 if (! do $checker_path) {
1476 if ($@) {
1477 $fn->($@);
1478 } elsif ($!) {
1479 $fn->($!);
1480 } else {
1481 $fn->("The detected tools didn't match the platform\n");
1482 }
1483 }
1484 last;
1485 }
1486}
1487
488e2b0f
RL
1488push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
1489
abe256e7 1490if ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m)
84f32c84
DMSP
1491 {
1492 push @{$config{cflags}}, "-mno-cygwin";
1493 push @{$config{cxxflags}}, "-mno-cygwin" if $config{CXX};
1494 push @{$config{shared_ldflag}}, "-mno-cygwin";
1495 }
cbecd29a 1496
5b18235a 1497if ($target =~ /linux.*-mips/ && !$disabled{asm}
8b399c5e 1498 && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) {
84f32c84
DMSP
1499 # minimally required architecture flags for assembly modules
1500 my $value;
1501 $value = '-mips2' if ($target =~ /mips32/);
1502 $value = '-mips3' if ($target =~ /mips64/);
1503 unshift @{$config{cflags}}, $value;
1504 unshift @{$config{cxxflags}}, $value if $config{CXX};
63d8834c
AP
1505}
1506
9c62a279
RL
1507# If threads aren't disabled, check how possible they are
1508unless ($disabled{threads}) {
1509 if ($auto_threads) {
1510 # Enabled by default, disable it forcibly if unavailable
1511 if ($target{thread_scheme} eq "(unknown)") {
71ef78d7 1512 disable("unavailable", 'threads');
9c62a279
RL
1513 }
1514 } else {
8483a003 1515 # The user chose to enable threads explicitly, let's see
9c62a279
RL
1516 # if there's a chance that's possible
1517 if ($target{thread_scheme} eq "(unknown)") {
1518 # If the user asked for "threads" and we don't have internal
1519 # knowledge how to do it, [s]he is expected to provide any
1520 # system-dependent compiler options that are necessary. We
1521 # can't truly check that the given options are correct, but
1522 # we expect the user to know what [s]He is doing.
c1a09254 1523 if (!@{$config{CFLAGS}} && !@{$config{CPPDEFINES}}) {
9c62a279
RL
1524 die "You asked for multi-threading support, but didn't\n"
1525 ,"provide any system-specific compiler options\n";
1526 }
1527 }
1528 }
1529}
1530
bacc3081
RL
1531# Find out if clang's sanitizers have been enabled with -fsanitize
1532# flags and ensure that the corresponding %disabled elements area
1533# removed to reflect that the sanitizers are indeed enabled.
1534my %detected_sanitizers = ();
1535foreach (grep /^-fsanitize=/, @{$config{CFLAGS} || []}) {
1536 (my $checks = $_) =~ s/^-fsanitize=//;
1537 foreach (split /,/, $checks) {
1538 my $d = { address => 'asan',
1539 undefined => 'ubsan',
1540 memory => 'msan' } -> {$_};
1541 next unless defined $d;
1542
1543 $detected_sanitizers{$d} = 1;
1544 if (defined $disabled{$d}) {
1545 die "***** Conflict between disabling $d and enabling $_ sanitizer"
1546 if $disabled{$d} ne "default";
1547 delete $disabled{$d};
1548 }
1549 }
1550}
1551
9c62a279
RL
1552# If threads still aren't disabled, add a C macro to ensure the source
1553# code knows about it. Any other flag is taken care of by the configs.
1554unless($disabled{threads}) {
e0bf7c01 1555 push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
9c62a279 1556}
e452de9d 1557
c0af01f3
HL
1558if ($disabled{"unstable-qlog"}) {
1559 $disabled{"qlog"} = 1;
1560}
1561
8c3bc594 1562my $no_shared_warn=0;
e1f5a92d 1563if (($target{shared_target} // '') eq "")
84f32c84
DMSP
1564 {
1565 $no_shared_warn = 1
1566 if (!$disabled{shared} || !$disabled{"dynamic-engine"});
71ef78d7 1567 disable('no-shared-target', 'pic');
84f32c84 1568 }
b436a982 1569
19ab5790 1570if ($disabled{"dynamic-engine"}) {
343ec2b0 1571 $config{dynamic_engines} = 0;
19ab5790 1572} else {
19ab5790 1573 $config{dynamic_engines} = 1;
343ec2b0 1574}
ecd45314 1575
bacc3081 1576unless ($disabled{asan} || defined $detected_sanitizers{asan}) {
5b18235a 1577 push @{$config{cflags}}, "-fsanitize=address";
c38bb727
BL
1578}
1579
bacc3081 1580unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) {
83529f07 1581 push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC";
c38bb727
BL
1582}
1583
bacc3081 1584unless ($disabled{msan} || defined $detected_sanitizers{msan}) {
5b18235a 1585 push @{$config{cflags}}, "-fsanitize=memory";
29df3061
EK
1586}
1587
65cc6d5c 1588unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
29df3061 1589 && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
5b18235a 1590 push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g";
abe256e7 1591 push @{$config{cxxflags}}, "-fno-omit-frame-pointer", "-g" if $config{CXX};
c38bb727 1592}
c313e32a
AP
1593#
1594# Platform fix-ups
1595#
ae48242c
RL
1596
1597# This saves the build files from having to check
1598if ($disabled{pic})
84f32c84
DMSP
1599 {
1600 foreach (qw(shared_cflag shared_cxxflag shared_cppflag
1601 shared_defines shared_includes shared_ldflag
1602 module_cflags module_cxxflags module_cppflags
1603 module_defines module_includes module_lflags))
1604 {
1605 delete $config{$_};
1606 $target{$_} = "";
1607 }
1608 }
4f16039e 1609else
84f32c84
DMSP
1610 {
1611 push @{$config{lib_defines}}, "OPENSSL_PIC";
1612 }
ae48242c 1613
291e94df 1614if ($target{sys_id} ne "")
84f32c84
DMSP
1615 {
1616 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1617 }
cf1b7d96 1618
e373c70a
RL
1619my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC});
1620my %predefined_CXX = $config{CXX}
1621 ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX})
1622 : ();
54cf3b98 1623
09840412
AP
1624unless ($disabled{asm}) {
1625 # big endian systems can use ELFv2 ABI
f5485b97 1626 if ($target eq "linux-ppc64" || $target eq "BSD-ppc64") {
09840412
AP
1627 $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2);
1628 }
1629}
1630
fe191b49 1631# Check for makedepend capabilities.
6d75a83c 1632if (!$disabled{makedepend}) {
2e535eb5
RL
1633 # If the attribute makedep_scheme is defined, then we assume that the
1634 # config target and its associated build file are programmed to deal
1635 # with it.
1636 # If makedep_scheme is undefined, we go looking for GCC compatible
1637 # dependency making, and if that's not available, we try to fall back
1638 # on 'makedepend'.
1639 if ($target{makedep_scheme}) {
1640 $config{makedep_scheme} = $target{makedep_scheme};
1641 # If the makedepcmd attribute is defined, copy it. If not, the
1642 # build files will have to fend for themselves.
1643 $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd};
e373c70a 1644 } elsif (($predefined_C{__GNUC__} // -1) >= 3
84f32c84 1645 && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) {
fe191b49 1646 # We know that GNU C version 3 and up as well as all clang
717f308e
TS
1647 # versions support dependency generation, but Xcode did not
1648 # handle $cc -M before clang support (but claims __GNUC__ = 3)
2e535eb5 1649 $config{makedep_scheme} = 'gcc';
6d75a83c 1650 } else {
2e535eb5
RL
1651 # In all other cases, we look for 'makedepend', and set the
1652 # makedep_scheme value if we found it.
1653 $config{makedepcmd} = which('makedepend');
1654 $config{makedep_scheme} = 'makedepend' if $config{makedepcmd};
54cf3b98 1655 }
2e535eb5
RL
1656
1657 # If no depend scheme is set, we disable makedepend
1658 disable('unavailable', 'makedepend') unless $config{makedep_scheme};
f1f07a23 1659}
8ed40b83 1660
e373c70a 1661if (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') {
0ad4078c 1662 # probe for -Wa,--noexecstack option...
e373c70a 1663 if ($predefined_C{__clang__}) {
0ad4078c
AP
1664 # clang has builtin assembler, which doesn't recognize --help,
1665 # but it apparently recognizes the option in question on all
1666 # supported platforms even when it's meaningless. In other words
1667 # probe would fail, but probed option always accepted...
1668 push @{$config{cflags}}, "-Wa,--noexecstack", "-Qunused-arguments";
8e5da579 1669 } else {
0ad4078c
AP
1670 my $cc = $config{CROSS_COMPILE}.$config{CC};
1671 open(PIPE, "$cc -Wa,--help -c -o null.$$.o -x assembler /dev/null 2>&1 |");
1672 while(<PIPE>) {
1673 if (m/--noexecstack/) {
1674 push @{$config{cflags}}, "-Wa,--noexecstack";
1675 last;
1676 }
1677 }
1678 close(PIPE);
1679 unlink("null.$$.o");
1680 }
1681}
7d130f68
RL
1682
1683# Deal with bn_ops ###################################################
1684
84f32c84 1685$config{bn_ll} =0;
7d130f68 1686my $def_int="unsigned int";
84f32c84 1687$config{rc4_int} =$def_int;
b4f35e5e 1688($config{b64l},$config{b64},$config{b32})=(0,0,1);
7d130f68 1689
94af0cd7 1690my $count = 0;
7d130f68 1691foreach (sort split(/\s+/,$target{bn_ops})) {
94af0cd7 1692 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
84f32c84
DMSP
1693 $config{bn_ll}=1 if $_ eq 'BN_LLONG';
1694 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
94af0cd7 1695 ($config{b64l},$config{b64},$config{b32})
84f32c84 1696 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
94af0cd7 1697 ($config{b64l},$config{b64},$config{b32})
84f32c84 1698 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
94af0cd7 1699 ($config{b64l},$config{b64},$config{b32})
84f32c84 1700 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
7d130f68 1701}
94af0cd7
RS
1702die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1703 if $count > 1;
7d130f68 1704
a6a4d0ac
RL
1705$config{api} = $config{major} * 10000 + $config{minor} * 100
1706 unless $config{api};
b05d6327
RL
1707foreach (keys %$apitable) {
1708 $disabled{"deprecated-$_"} = "deprecation"
1709 if $disabled{deprecated} && $config{api} >= $apitable->{$_};
1710}
1711
1712disable(); # Run a cascade now
7d130f68
RL
1713
1714# Hack cflags for better warnings (dev option) #######################
1715
fa153b57
RL
1716# "Stringify" the C and C++ flags string. This permits it to be made part of
1717# a string and works as well on command lines.
5b18235a
RL
1718$config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1719 @{$config{cflags}} ];
fa153b57 1720$config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
abe256e7 1721 @{$config{cxxflags}} ] if $config{CXX};
b436a982 1722
fcd2d5a6 1723$config{openssl_api_defines} = [
b05d6327 1724 "OPENSSL_CONFIGURED_API=".$config{api},
fcd2d5a6 1725];
98186eb4 1726
3b437400 1727my @strict_warnings_collection=();
0c28f277 1728if ($strict_warnings)
84f32c84
DMSP
1729 {
1730 my $wopt;
1731 my $gccver = $predefined_C{__GNUC__} // -1;
6d50589c 1732
b4a7b4ec
RL
1733 if ($gccver >= 4)
1734 {
1735 push @strict_warnings_collection, @gcc_devteam_warn;
1736 push @strict_warnings_collection, @clang_devteam_warn
1737 if (defined($predefined_C{__clang__}));
1738 }
1739 elsif ($config{target} =~ /^VC-/)
1740 {
1741 push @strict_warnings_collection, @cl_devteam_warn;
1742 }
1743 else
1744 {
1745 warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC"
1746 }
84f32c84 1747 }
4650d10f 1748
3b437400
RL
1749$config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings'
1750 ? @strict_warnings_collection
1751 : ( $_ ) }
1752 @{$config{CFLAGS}} ];
ef8ca6bd 1753
c91a0a83
EK
1754unless ($disabled{afalgeng}) {
1755 $config{afalgeng}="";
9e381e8a 1756 if (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
9e1a54f4 1757 push @{$config{engdirs}}, "afalg";
79fff39d 1758 } else {
71ef78d7 1759 disable('not-linux', 'afalgeng');
7f458a48 1760 }
1761}
8da00a38 1762
76d0a74b
RL
1763unless ($disabled{devcryptoeng}) {
1764 if ($target =~ m/^BSD/) {
1765 my $maxver = 5*100 + 7;
1766 my $sysstr = `uname -s`;
1767 my $verstr = `uname -r`;
1768 $sysstr =~ s|\R$||;
1769 $verstr =~ s|\R$||;
1770 my ($ma, $mi, @rest) = split m|\.|, $verstr;
1771 my $ver = $ma*100 + $mi;
1772 if ($sysstr eq 'OpenBSD' && $ver >= $maxver) {
1773 disable('too-new-kernel', 'devcryptoeng');
1774 }
1775 }
1776}
1777
69495e3d
BP
1778unless ($disabled{ktls}) {
1779 $config{ktls}="";
9b25f52a 1780 my $cc = $config{CROSS_COMPILE}.$config{CC};
69495e3d 1781 if ($target =~ m/^linux/) {
9b25f52a
TM
1782 system("printf '#include <sys/types.h>\n#include <linux/tls.h>' | $cc -E - >/dev/null 2>&1");
1783 if ($? != 0) {
71ef78d7 1784 disable('too-old-kernel', 'ktls');
69495e3d 1785 }
2111f5c2 1786 } elsif ($target =~ m/^BSD/) {
2111f5c2
AG
1787 system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1");
1788 if ($? != 0) {
1789 disable('too-old-freebsd', 'ktls');
1790 }
69495e3d 1791 } else {
2111f5c2 1792 disable('not-linux-or-freebsd', 'ktls');
69495e3d
BP
1793 }
1794}
1795
606e0426
HL
1796unless ($disabled{winstore}) {
1797 unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) {
1798 disable('not-windows', 'winstore');
1799 }
1800}
1801
69495e3d
BP
1802push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
1803
8f0dd6d9
RL
1804# Get the extra flags used when building shared libraries and modules. We
1805# do this late because some of them depend on %disabled.
1806
1807# Make the flags to build DSOs the same as for shared libraries unless they
1808# are already defined
1809$target{module_cflags} = $target{shared_cflag} unless defined $target{module_cflags};
1810$target{module_cxxflags} = $target{shared_cxxflag} unless defined $target{module_cxxflags};
1811$target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_ldflags};
1812{
1813 my $shared_info_pl =
1814 catfile(dirname($0), "Configurations", "shared-info.pl");
1815 my %shared_info = read_eval_file($shared_info_pl);
1816 push @{$target{_conf_fname_int}}, $shared_info_pl;
1817 my $si = $target{shared_target};
1818 while (ref $si ne "HASH") {
1819 last if ! defined $si;
1820 if (ref $si eq "CODE") {
1821 $si = $si->();
1822 } else {
1823 $si = $shared_info{$si};
1824 }
1825 }
1826
1827 # Some of the 'shared_target' values don't have any entries in
1828 # %shared_info. That's perfectly fine, AS LONG AS the build file
1829 # template knows how to handle this. That is currently the case for
1830 # Windows and VMS.
1831 if (defined $si) {
1832 # Just as above, copy certain shared_* attributes to the corresponding
1833 # module_ attribute unless the latter is already defined
1834 $si->{module_cflags} = $si->{shared_cflag} unless defined $si->{module_cflags};
1835 $si->{module_cxxflags} = $si->{shared_cxxflag} unless defined $si->{module_cxxflags};
1836 $si->{module_ldflags} = $si->{shared_ldflag} unless defined $si->{module_ldflags};
1837 foreach (sort keys %$si) {
1838 $target{$_} = defined $target{$_}
1839 ? add($si->{$_})->($target{$_})
1840 : $si->{$_};
1841 }
1842 }
1843}
1844
1845# ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON
5b18235a 1846
8c06d719
RL
1847######################################################################
1848# Build up information for skipping certain directories depending on disabled
1849# features, as well as setting up macros for disabled features.
1850
1851# This is a tentative database of directories to skip. Some entries may not
1852# correspond to anything real, but that's ok, they will simply be ignored.
1853# The actual processing of these entries is done in the build.info lookup
1854# loop further down.
1855#
1856# The key is a Unix formatted path in the source tree, the value is an index
1857# into %disabled_info, so any existing path gets added to a corresponding
1858# 'skipped' entry in there with the list of skipped directories.
1859my %skipdir = ();
1860my %disabled_info = (); # For configdata.pm
1861foreach my $what (sort keys %disabled) {
1862 # There are deprecated disablables that translate to themselves.
e304aa87 1863 # They cause disabling cascades, but should otherwise not register.
8c06d719 1864 next if $deprecated_disablables{$what};
b05d6327
RL
1865 # The generated $disabled{"deprecated-x.y"} entries are special
1866 # and treated properly elsewhere
1867 next if $what =~ m|^deprecated-|;
8c06d719
RL
1868
1869 $config{options} .= " no-$what";
1870
1871 if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
1872 'module', 'pic', 'dynamic-engine', 'makedepend',
59d21298 1873 'sse2', 'legacy' )) {
8c06d719
RL
1874 (my $WHAT = uc $what) =~ s|-|_|g;
1875 my $skipdir = $what;
1876
1877 # fix-up crypto/directory name(s)
1878 $skipdir = "ripemd" if $what eq "rmd160";
1879 $skipdir = "whrlpool" if $what eq "whirlpool";
1880
1881 my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT";
1882 push @{$config{openssl_feature_defines}}, $macro;
1883
1884 $skipdir{engines} = $what if $what eq 'engine';
1885 $skipdir{"crypto/$skipdir"} = $what
1886 unless $what eq 'async' || $what eq 'err' || $what eq 'dso';
1887 }
1888}
1889
1890if ($disabled{"dynamic-engine"}) {
1891 push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1892} else {
1893 push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE";
1894}
1895
9fe2bb77
RL
1896# If we use the unified build, collect information from build.info files
1897my %unified_info = ();
1898
2b6b606c 1899my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
ddf1847d 1900if ($builder eq "unified") {
1935a586 1901 use Text::Template 1.46;
9fe2bb77 1902
9fe2bb77 1903 sub cleandir {
2e963849 1904 my $base = shift;
9fe2bb77 1905 my $dir = shift;
2e963849 1906 my $relativeto = shift || ".";
504ff2a4 1907 my $no_mkpath = shift // 0;
2e963849
RL
1908
1909 $dir = catdir($base,$dir) unless isabsolute($dir);
9fe2bb77 1910
ec182ef0 1911 # Make sure the directories we're building in exists
504ff2a4 1912 mkpath($dir) unless $no_mkpath;
ec182ef0 1913
2e963849 1914 my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
9fe2bb77
RL
1915 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1916 return $res;
1917 }
1918
1919 sub cleanfile {
2e963849 1920 my $base = shift;
9fe2bb77 1921 my $file = shift;
2e963849 1922 my $relativeto = shift || ".";
504ff2a4 1923 my $no_mkpath = shift // 0;
2e963849
RL
1924
1925 $file = catfile($base,$file) unless isabsolute($file);
1926
9fe2bb77
RL
1927 my $d = dirname($file);
1928 my $f = basename($file);
1929
ec182ef0 1930 # Make sure the directories we're building in exists
504ff2a4 1931 mkpath($d) unless $no_mkpath;
ec182ef0 1932
2e963849 1933 my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
9fe2bb77
RL
1934 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1935 return $res;
1936 }
1937
1967a42e
RL
1938 # Store the name of the template file we will build the build file from
1939 # in %config. This may be useful for the build file itself.
1940 my @build_file_template_names =
aa2d7e0e
RL
1941 ( $builder_platform."-".$config{build_file}.".tmpl",
1942 $config{build_file}.".tmpl" );
1967a42e
RL
1943 my @build_file_templates = ();
1944
1945 # First, look in the user provided directory, if given
7ecdf18d 1946 if (defined env($local_config_envname)) {
84f32c84
DMSP
1947 @build_file_templates =
1948 map {
1949 if ($^O eq 'VMS') {
1950 # VMS environment variables are logical names,
1951 # which can be used as is
1952 $local_config_envname . ':' . $_;
1953 } else {
1954 catfile(env($local_config_envname), $_);
1955 }
1956 }
1957 @build_file_template_names;
1967a42e
RL
1958 }
1959 # Then, look in our standard directory
1960 push @build_file_templates,
504ff2a4 1961 ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir, 1) }
84f32c84 1962 @build_file_template_names );
1967a42e
RL
1963
1964 my $build_file_template;
1965 for $_ (@build_file_templates) {
84f32c84 1966 $build_file_template = $_;
1967a42e
RL
1967 last if -f $build_file_template;
1968
1969 $build_file_template = undef;
1970 }
1971 if (!defined $build_file_template) {
84f32c84 1972 die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1967a42e
RL
1973 }
1974 $config{build_file_templates}
8258975c 1975 = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"),
504ff2a4 1976 $blddir, 1),
2660b7cf 1977 $build_file_template ];
1967a42e 1978
7f73eafe 1979 my @build_dirs = ( [ ] ); # current directory
9fe2bb77 1980
2e0956ba
RL
1981 $config{build_infos} = [ ];
1982
507f8380
RL
1983 # We want to detect configdata.pm in the source tree, so we
1984 # don't use it if the build tree is different.
504ff2a4 1985 my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir, 1);
507f8380
RL
1986
1987 # Any source file that we recognise is placed in this hash table, with
1988 # the list of its intended destinations as value. When everything has
1989 # been collected, there's a routine that checks that these source files
1990 # exist, or if they are generated, that the generator exists.
1991 my %check_exist = ();
1992 my %check_generate = ();
1993
d201dbc9 1994 my %ordinals = ();
7f73eafe
RL
1995 while (@build_dirs) {
1996 my @curd = @{shift @build_dirs};
1997 my $sourced = catdir($srcdir, @curd);
1998 my $buildd = catdir($blddir, @curd);
9fe2bb77 1999
75d47db4
RL
2000 my $unixdir = join('/', @curd);
2001 if (exists $skipdir{$unixdir}) {
2002 my $what = $skipdir{$unixdir};
2003 push @{$disabled_info{$what}->{skipped}}, catdir(@curd);
2004 next;
2005 }
2006
dca99383 2007 mkpath($buildd);
9fe2bb77 2008
7f73eafe 2009 my $f = 'build.info';
9fe2bb77
RL
2010 # The basic things we're trying to build
2011 my @programs = ();
2012 my @libraries = ();
1842f369 2013 my @modules = ();
9fe2bb77 2014 my @scripts = ();
9fe2bb77 2015
9fe2bb77 2016 my %sources = ();
2a08d1a0 2017 my %shared_sources = ();
9fe2bb77 2018 my %includes = ();
b96ab5e6 2019 my %defines = ();
9fe2bb77 2020 my %depends = ();
ae4c7450 2021 my %generate = ();
d594d2e1 2022 my %imagedocs = ();
829f86bb
RL
2023 my %htmldocs = ();
2024 my %mandocs = ();
9fe2bb77 2025
26fe9b07
RL
2026 # Support for $variablename in build.info files.
2027 # Embedded perl code is the ultimate master, still. If its output
2028 # contains a dollar sign, it had better be escaped, or it will be
2029 # taken for a variable name prefix.
2030 my %variables = ();
e4292179
RL
2031 # Variable name syntax
2032 my $variable_name_re = qr/(?P<VARIABLE>[[:alpha:]][[:alnum:]_]*)/;
2033 # Value modifier syntaxes
2034 my $variable_subst_re = qr/\/(?P<RE>(?:\\\/|.)*?)\/(?P<SUBST>.*?)/;
4975e8b4
RL
2035 # Variable reference
2036 my $variable_simple_re = qr/(?<!\\)\$${variable_name_re}/;
2037 my $variable_w_mod_re =
2038 qr/(?<!\\)\$\{${variable_name_re}(?P<MOD>(?:\\\/|.)*?)\}/;
2039 # Tie it all together
2040 my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/;
2041
26fe9b07
RL
2042 my $expand_variables = sub {
2043 my $value = '';
2044 my $value_rest = shift;
2045
03f30c55
RL
2046 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2047 print STDERR
e4292179 2048 "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n"
03f30c55 2049 }
e4292179 2050
4975e8b4
RL
2051 while ($value_rest =~ /${variable_re}/) {
2052 # We must save important regexp values, because the next
2053 # regexp clears them
2054 my $mod = $+{MOD};
e4292179
RL
2055 my $variable_value = $variables{$+{VARIABLE}};
2056
4975e8b4
RL
2057 $value_rest = $';
2058 $value .= $`;
2059
e4292179 2060 # Process modifier expressions, if present
4975e8b4
RL
2061 if (defined $mod) {
2062 if ($mod =~ /^${variable_subst_re}$/) {
2063 my $re = $+{RE};
2064 my $subst = $+{SUBST};
2065
2066 $variable_value =~ s/\Q$re\E/$subst/g;
2067
2068 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2069 print STDERR
2070 "DEBUG[\$expand_variables] ... and substituted ",
2071 "'$re' with '$subst'\n";
2072 }
e4292179
RL
2073 }
2074 }
2075
2076 $value .= $variable_value;
26fe9b07 2077 }
03f30c55
RL
2078 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2079 print STDERR
e4292179 2080 "DEBUG[\$expand_variables] ... into: '$value$value_rest'\n";
03f30c55 2081 }
26fe9b07
RL
2082 return $value . $value_rest;
2083 };
2084
285daccd
RL
2085 # Support for attributes in build.info files
2086 my %attributes = ();
2087 my $handle_attributes = sub {
2088 my $attr_str = shift;
2089 my $ref = shift;
2090 my @goals = @_;
2091
2092 return unless defined $attr_str;
2093
2094 my @a = tokenize($attr_str, qr|\s*,\s*|);
2095 foreach my $a (@a) {
2096 my $ac = 1;
2097 my $ak = $a;
2098 my $av = 1;
ea4ee152 2099 if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) {
285daccd 2100 $ac = ! $1;
ea4ee152
RL
2101 $ak = $2;
2102 $av = $3;
285daccd
RL
2103 }
2104 foreach my $g (@goals) {
2105 if ($ac) {
2106 $$ref->{$g}->{$ak} = $av;
2107 } else {
2108 delete $$ref->{$g}->{$ak};
2109 }
2110 }
2111 }
2112 };
2113
ad5be194
RL
2114 # Support for pushing values on multiple indexes of a given hash
2115 # array.
2116 my $push_to = sub {
2117 my $valueref = shift;
2118 my $index_str = shift; # May be undef or empty
2119 my $attrref = shift; # May be undef
2120 my $attr_str = shift;
2121 my @values = @_;
2122
2123 if (defined $index_str) {
2124 my @indexes = ( '' );
2125 if ($index_str !~ m|^\s*$|) {
2126 @indexes = tokenize($index_str);
2127 }
2128 foreach (@indexes) {
2129 push @{$valueref->{$_}}, @values;
2130 if (defined $attrref) {
2131 $handle_attributes->($attr_str, \$$attrref->{$_},
2132 @values);
2133 }
2134 }
2135 } else {
2136 push @$valueref, @values;
2137 $handle_attributes->($attr_str, $attrref, @values)
2138 if defined $attrref;
2139 }
2140 };
2141
829f86bb
RL
2142 if ($buildinfo_debug) {
2143 print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n";
2144 }
2e0956ba 2145 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
cb6afcd6
RL
2146 my $template =
2147 Text::Template->new(TYPE => 'FILE',
2148 SOURCE => catfile($sourced, $f),
2149 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
9fe2bb77
RL
2150 die "Something went wrong with $sourced/$f: $!\n" unless $template;
2151 my @text =
2152 split /^/m,
2153 $template->fill_in(HASH => { config => \%config,
2154 target => \%target,
9e04edf2 2155 disabled => \%disabled,
f59d0131 2156 withargs => \%withargs,
9fe2bb77
RL
2157 builddir => abs2rel($buildd, $blddir),
2158 sourcedir => abs2rel($sourced, $blddir),
2159 buildtop => abs2rel($blddir, $blddir),
2160 sourcetop => abs2rel($srcdir, $blddir) },
2161 DELIMITERS => [ "{-", "-}" ]);
2162
2163 # The top item of this stack has the following values
2164 # -2 positive already run and we found ELSE (following ELSIF should fail)
2165 # -1 positive already run (skip until ENDIF)
2166 # 0 negatives so far (if we're at a condition, check it)
2167 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
2168 # 2 positive ELSE (following ELSIF should fail)
2169 my @skip = ();
285daccd
RL
2170
2171 # A few useful generic regexps
2172 my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/;
2173 my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/;
2174 my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/;
4a739387 2175 my $value_re = qr/(?P<VALUE>.*?)/;
9fe2bb77
RL
2176 collect_information(
2177 collect_from_array([ @text ],
2178 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
2179 $l1 =~ s/\\$//; $l1.$l2 }),
2180 # Info we're looking for
285daccd 2181 qr/^\s* IF ${cond_re} \s*$/x
635bd409 2182 => sub {
c5798e0e 2183 if (! @skip || $skip[$#skip] > 0) {
285daccd 2184 push @skip, !! $expand_variables->($+{COND});
635bd409
RL
2185 } else {
2186 push @skip, -1;
2187 }
2188 },
285daccd 2189 qr/^\s* ELSIF ${cond_re} \s*$/x
9fe2bb77
RL
2190 => sub { die "ELSIF out of scope" if ! @skip;
2191 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
2192 $skip[$#skip] = -1 if $skip[$#skip] != 0;
285daccd 2193 $skip[$#skip] = !! $expand_variables->($+{COND})
9fe2bb77 2194 if $skip[$#skip] == 0; },
285daccd 2195 qr/^\s* ELSE \s*$/x
9fe2bb77
RL
2196 => sub { die "ELSE out of scope" if ! @skip;
2197 $skip[$#skip] = -2 if $skip[$#skip] != 0;
2198 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
285daccd 2199 qr/^\s* ENDIF \s*$/x
9fe2bb77
RL
2200 => sub { die "ENDIF out of scope" if ! @skip;
2201 pop @skip; },
4a739387 2202 qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x
26fe9b07
RL
2203 => sub {
2204 if (!@skip || $skip[$#skip] > 0) {
285daccd 2205 $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE});
26fe9b07
RL
2206 }
2207 },
4a739387 2208 qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x
7f73eafe
RL
2209 => sub {
2210 if (!@skip || $skip[$#skip] > 0) {
285daccd 2211 foreach (tokenize($expand_variables->($+{VALUE}))) {
7f73eafe
RL
2212 push @build_dirs, [ @curd, splitdir($_, 1) ];
2213 }
2214 }
2215 },
4a739387 2216 qr/^\s* PROGRAMS ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2217 => sub { $push_to->(\@programs, undef,
2218 \$attributes{programs}, $+{ATTRIBS},
2219 tokenize($expand_variables->($+{VALUE})))
2220 if !@skip || $skip[$#skip] > 0; },
4a739387 2221 qr/^\s* LIBS ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2222 => sub { $push_to->(\@libraries, undef,
2223 \$attributes{libraries}, $+{ATTRIBS},
2224 tokenize($expand_variables->($+{VALUE})))
2225 if !@skip || $skip[$#skip] > 0; },
4a739387 2226 qr/^\s* MODULES ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2227 => sub { $push_to->(\@modules, undef,
2228 \$attributes{modules}, $+{ATTRIBS},
2229 tokenize($expand_variables->($+{VALUE})))
2230 if !@skip || $skip[$#skip] > 0; },
4a739387 2231 qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2232 => sub { $push_to->(\@scripts, undef,
2233 \$attributes{scripts}, $+{ATTRIBS},
2234 tokenize($expand_variables->($+{VALUE})))
2235 if !@skip || $skip[$#skip] > 0; },
4a739387 2236 qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
d594d2e1
P
2237 => sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}),
2238 undef, undef,
2239 tokenize($expand_variables->($+{VALUE})))
2240 if !@skip || $skip[$#skip] > 0; },
4a739387 2241 qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2242 => sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}),
2243 undef, undef,
2244 tokenize($expand_variables->($+{VALUE})))
2245 if !@skip || $skip[$#skip] > 0; },
4a739387 2246 qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2247 => sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}),
2248 undef, undef,
2249 tokenize($expand_variables->($+{VALUE})))
2250 if !@skip || $skip[$#skip] > 0; },
4a739387 2251 qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194 2252 => sub { $push_to->(\%sources, $expand_variables->($+{INDEX}),
dd05c793 2253 \$attributes{sources}, $+{ATTRIBS},
ad5be194
RL
2254 tokenize($expand_variables->($+{VALUE})))
2255 if !@skip || $skip[$#skip] > 0; },
4a739387 2256 qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194 2257 => sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}),
dd05c793 2258 \$attributes{sources}, $+{ATTRIBS},
ad5be194
RL
2259 tokenize($expand_variables->($+{VALUE})))
2260 if !@skip || $skip[$#skip] > 0; },
4a739387 2261 qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2262 => sub { $push_to->(\%includes, $expand_variables->($+{INDEX}),
2263 undef, undef,
2264 tokenize($expand_variables->($+{VALUE})))
2265 if !@skip || $skip[$#skip] > 0; },
4a739387 2266 qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2267 => sub { $push_to->(\%defines, $expand_variables->($+{INDEX}),
2268 undef, undef,
2269 tokenize($expand_variables->($+{VALUE})))
2270 if !@skip || $skip[$#skip] > 0; },
4a739387 2271 qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194
RL
2272 => sub { $push_to->(\%depends, $expand_variables->($+{INDEX}),
2273 \$attributes{depends}, $+{ATTRIBS},
2274 tokenize($expand_variables->($+{VALUE})))
2275 if !@skip || $skip[$#skip] > 0; },
4d02d500 2276 qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
ad5be194 2277 => sub { $push_to->(\%generate, $expand_variables->($+{INDEX}),
4d02d500
RL
2278 \$attributes{generate}, $+{ATTRIBS},
2279 $expand_variables->($+{VALUE}))
ad5be194 2280 if !@skip || $skip[$#skip] > 0; },
285daccd 2281 qr/^\s* (?:\#.*)? $/x => sub { },
2b6b606c
RL
2282 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
2283 "BEFORE" => sub {
2284 if ($buildinfo_debug) {
2285 print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
2286 print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2287 }
2288 },
2289 "AFTER" => sub {
2290 if ($buildinfo_debug) {
2291 print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2292 }
2293 },
9fe2bb77
RL
2294 );
2295 die "runaway IF?" if (@skip);
2296
285daccd 2297 if (grep { defined $attributes{modules}->{$_}->{engine} } keys %attributes
1842f369
RL
2298 and !$config{dynamic_engines}) {
2299 die <<"EOF"
19ab5790 2300ENGINES can only be used if configured with 'dynamic-engine'.
9fe2bb77
RL
2301This is usually a fault in a build.info file.
2302EOF
1842f369 2303 }
7f5af797 2304
c91f24d4
RL
2305 {
2306 my %infos = ( programs => [ @programs ],
2307 libraries => [ @libraries ],
1842f369 2308 modules => [ @modules ],
da7e31e0 2309 scripts => [ @scripts ] );
c91f24d4
RL
2310 foreach my $k (keys %infos) {
2311 foreach (@{$infos{$k}}) {
2312 my $item = cleanfile($buildd, $_, $blddir);
2313 $unified_info{$k}->{$item} = 1;
285daccd
RL
2314
2315 # Fix up associated attributes
2316 $unified_info{attributes}->{$k}->{$item} =
2317 $attributes{$k}->{$_}
2318 if defined $attributes{$k}->{$_};
c91f24d4
RL
2319 }
2320 }
8a67946e
RL
2321 }
2322
f5fb6f05
RL
2323 # Check that we haven't defined any library as both shared and
2324 # explicitly static. That is forbidden.
2325 my @doubles = ();
2326 foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
2327 (my $l = $_) =~ s/\.a$//;
2328 push @doubles, $l if defined $unified_info{libraries}->{$l};
9fe2bb77 2329 }
f5fb6f05
RL
2330 die "these libraries are both explicitly static and shared:\n ",
2331 join(" ", @doubles), "\n"
2332 if @doubles;
9fe2bb77 2333
9fe2bb77
RL
2334 foreach (keys %sources) {
2335 my $dest = $_;
2e963849 2336 my $ddest = cleanfile($buildd, $_, $blddir);
9fe2bb77 2337 foreach (@{$sources{$dest}}) {
504ff2a4 2338 my $s = cleanfile($sourced, $_, $blddir, 1);
9fe2bb77 2339
19cf4404
RL
2340 # If it's generated or we simply don't find it in the source
2341 # tree, we assume it's in the build tree.
2342 if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
2e963849 2343 $s = cleanfile($buildd, $_, $blddir);
9fe2bb77 2344 }
dd05c793 2345 my $o = $_;
ea241958
RL
2346 # We recognise C++, C and asm files
2347 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
507f8380 2348 push @{$check_exist{$s}}, $ddest;
ea241958
RL
2349 $o =~ s/\.[csS]$/.o/; # C and assembler
2350 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2e963849 2351 $o = cleanfile($buildd, $o, $blddir);
bec2db18
RL
2352 $unified_info{sources}->{$ddest}->{$o} = -1;
2353 $unified_info{sources}->{$o}->{$s} = -1;
83900628
RS
2354 } elsif ($s =~ /\.rc$/) {
2355 # We also recognise resource files
507f8380 2356 push @{$check_exist{$s}}, $ddest;
83900628 2357 $o =~ s/\.rc$/.res/; # Resource configuration
5e16ac14 2358 $o = cleanfile($buildd, $o, $blddir);
bec2db18
RL
2359 $unified_info{sources}->{$ddest}->{$o} = -1;
2360 $unified_info{sources}->{$o}->{$s} = -1;
9fe2bb77 2361 } else {
507f8380 2362 push @{$check_exist{$s}}, $ddest;
9fe2bb77
RL
2363 $unified_info{sources}->{$ddest}->{$s} = 1;
2364 }
dd05c793
RL
2365 # Fix up associated attributes
2366 if ($o ne $_) {
2367 $unified_info{attributes}->{sources}->{$ddest}->{$o} =
2368 $unified_info{attributes}->{sources}->{$o}->{$s} =
2369 $attributes{sources}->{$dest}->{$_}
2370 if defined $attributes{sources}->{$dest}->{$_};
2371 } else {
2372 $unified_info{attributes}->{sources}->{$ddest}->{$s} =
2373 $attributes{sources}->{$dest}->{$_}
2374 if defined $attributes{sources}->{$dest}->{$_};
2375 }
9fe2bb77
RL
2376 }
2377 }
2378
2a08d1a0
RL
2379 foreach (keys %shared_sources) {
2380 my $dest = $_;
2381 my $ddest = cleanfile($buildd, $_, $blddir);
2a08d1a0 2382 foreach (@{$shared_sources{$dest}}) {
504ff2a4 2383 my $s = cleanfile($sourced, $_, $blddir, 1);
2a08d1a0 2384
19cf4404
RL
2385 # If it's generated or we simply don't find it in the source
2386 # tree, we assume it's in the build tree.
2387 if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
2a08d1a0
RL
2388 $s = cleanfile($buildd, $_, $blddir);
2389 }
ccce3e1d 2390
dd05c793 2391 my $o = $_;
ea241958 2392 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
ccce3e1d 2393 # We recognise C++, C and asm files
507f8380 2394 push @{$check_exist{$s}}, $ddest;
ea241958
RL
2395 $o =~ s/\.[csS]$/.o/; # C and assembler
2396 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2a08d1a0 2397 $o = cleanfile($buildd, $o, $blddir);
bec2db18
RL
2398 $unified_info{shared_sources}->{$ddest}->{$o} = -1;
2399 $unified_info{sources}->{$o}->{$s} = -1;
ccce3e1d
RL
2400 } elsif ($s =~ /\.rc$/) {
2401 # We also recognise resource files
507f8380 2402 push @{$check_exist{$s}}, $ddest;
ccce3e1d 2403 $o =~ s/\.rc$/.res/; # Resource configuration
5e16ac14 2404 $o = cleanfile($buildd, $o, $blddir);
bec2db18
RL
2405 $unified_info{shared_sources}->{$ddest}->{$o} = -1;
2406 $unified_info{sources}->{$o}->{$s} = -1;
ef2dfc99
RL
2407 } elsif ($s =~ /\.ld$/) {
2408 # We also recognise linker scripts (or corresponding)
ccce3e1d 2409 # We know they are generated files
507f8380 2410 push @{$check_exist{$s}}, $ddest;
dd05c793
RL
2411 $o = cleanfile($buildd, $_, $blddir);
2412 $unified_info{shared_sources}->{$ddest}->{$o} = 1;
2a08d1a0
RL
2413 } else {
2414 die "unrecognised source file type for shared library: $s\n";
2415 }
dd05c793
RL
2416 # Fix up associated attributes
2417 if ($o ne $_) {
2418 $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
2419 $unified_info{attributes}->{sources}->{$o}->{$s} =
2420 $attributes{sources}->{$dest}->{$_}
2421 if defined $attributes{sources}->{$dest}->{$_};
2422 } else {
2423 $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
2424 $attributes{sources}->{$dest}->{$_}
2425 if defined $attributes{sources}->{$dest}->{$_};
2426 }
2a08d1a0
RL
2427 }
2428 }
2429
ae4c7450
RL
2430 foreach (keys %generate) {
2431 my $dest = $_;
2432 my $ddest = cleanfile($buildd, $_, $blddir);
ae4c7450 2433 die "more than one generator for $dest: "
cff64af5
RL
2434 ,join(" ", @{$generate{$_}}),"\n"
2435 if scalar @{$generate{$_}} > 1;
ae4c7450 2436 my @generator = split /\s+/, $generate{$dest}->[0];
cff64af5 2437 my $gen = $generator[0];
504ff2a4 2438 $generator[0] = cleanfile($sourced, $gen, $blddir, 1);
cff64af5 2439
19cf4404 2440 # If the generator is itself generated, it's in the build tree
79f47ef5 2441 if ($generate{$gen} || ! -f $generator[0]) {
cff64af5
RL
2442 $generator[0] = cleanfile($buildd, $gen, $blddir);
2443 }
2497e2e7 2444 $check_generate{$ddest}->{$generator[0]}++;
cff64af5 2445
ae4c7450 2446 $unified_info{generate}->{$ddest} = [ @generator ];
4d02d500
RL
2447 # Fix up associated attributes
2448 $unified_info{attributes}->{generate}->{$ddest} =
2449 $attributes{generate}->{$dest}->{$gen}
2450 if defined $attributes{generate}->{$dest}->{$gen};
ae4c7450
RL
2451 }
2452
9fe2bb77
RL
2453 foreach (keys %depends) {
2454 my $dest = $_;
3f399e37
RL
2455 my $ddest = $dest;
2456
2457 if ($dest =~ /^\|(.*)\|$/) {
2458 # Collect the raw target
2459 $unified_info{targets}->{$1} = 1;
2460 $ddest = $1;
2461 } elsif ($dest eq '') {
2462 $ddest = '';
2463 } else {
504ff2a4 2464 $ddest = cleanfile($sourced, $dest, $blddir, 1);
8d34daf0 2465
3f399e37
RL
2466 # If the destination doesn't exist in source, it can only be
2467 # a generated file in the build tree.
2468 if ($ddest eq $src_configdata || ! -f $ddest) {
b684ee2c 2469 $ddest = cleanfile($buildd, $dest, $blddir);
3f399e37 2470 }
9fe2bb77 2471 }
b684ee2c
RL
2472 foreach my $f (@{$depends{$dest}}) {
2473 # If the dependency destination is generated, dependencies
2474 # may have an extra syntax to separate the intended inclusion
2475 # directory from the module to be loaded: a | instead of a
2476 # / as directory separator.
2477 # Do note that this has to be handled in the build file
2478 # template as well.
2479 # $i = inclusion path in source directory
2480 # $i2 = inclusion path in build directory
2481 # $m = module path (within the inclusion path)
2482 # $i = full module path in source directory
2483 # $i2 = full module path in build directory
2484 my $i; my $i2; my $m; my $d; my $d2;
2485 if ($unified_info{generate}->{$ddest}
2486 && $f =~ m/^(.*?)\|(.*)$/) {
2487 $i = $1;
2488 $m = $2;
ecabdf39 2489 # We must be very careful to modify $i last
504ff2a4 2490 $d = cleanfile($sourced, "$i/$m", $blddir, 1);
b684ee2c 2491 $d2 = cleanfile($buildd, "$i/$m", $blddir);
ecabdf39
RL
2492 $i2 = cleandir($buildd, $i, $blddir);
2493 $i = cleandir($sourced, $i, $blddir, 1);
b684ee2c 2494 } else {
504ff2a4 2495 $d = cleanfile($sourced, $f, $blddir, 1);
b684ee2c
RL
2496 $d2 = cleanfile($buildd, $f, $blddir);
2497 }
9fe2bb77 2498
e737d7b1
RL
2499 # If we know it's generated, or assume it is because we can't
2500 # find it in the source tree, we set file we depend on to be
19cf4404 2501 # in the build tree rather than the source tree.
846e4c4d 2502 if ($d eq $src_configdata
2d101b0f
RL
2503 || (grep { $d2 eq $_ }
2504 keys %{$unified_info{generate}})
19cf4404 2505 || ! -f $d) {
2d101b0f 2506 $d = $d2;
b684ee2c
RL
2507 $i = $i2;
2508 }
2509 if ($i) {
2510 # Put together the computed inclusion dir with the
2511 # original module name. Do note that we conserve the
2512 # Unixly path syntax for the module path.
2513 $d = "$i|$m";
9fe2bb77 2514 }
9fe2bb77 2515 $unified_info{depends}->{$ddest}->{$d} = 1;
9eba5933
RL
2516
2517 # Fix up associated attributes
2518 $unified_info{attributes}->{depends}->{$ddest}->{$d} =
b684ee2c
RL
2519 $attributes{depends}->{$dest}->{$f}
2520 if defined $attributes{depends}->{$dest}->{$f};
9fe2bb77
RL
2521 }
2522 }
2523
2524 foreach (keys %includes) {
2525 my $dest = $_;
504ff2a4 2526 my $ddest = cleanfile($sourced, $_, $blddir, 1);
8d34daf0
RL
2527
2528 # If the destination doesn't exist in source, it can only be
2529 # a generated file in the build tree.
846e4c4d 2530 if ($ddest eq $src_configdata || ! -f $ddest) {
8d34daf0 2531 $ddest = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
2532 }
2533 foreach (@{$includes{$dest}}) {
504ff2a4 2534 my $is = cleandir($sourced, $_, $blddir, 1);
4748f890
RL
2535 my $ib = cleandir($buildd, $_, $blddir);
2536 push @{$unified_info{includes}->{$ddest}->{source}}, $is
2537 unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
2538 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
2539 unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
9fe2bb77
RL
2540 }
2541 }
b96ab5e6 2542
ef57f799
RL
2543 foreach my $dest (keys %defines) {
2544 my $ddest;
b96ab5e6 2545
ef57f799 2546 if ($dest ne "") {
504ff2a4 2547 $ddest = cleanfile($sourced, $dest, $blddir, 1);
ef57f799
RL
2548
2549 # If the destination doesn't exist in source, it can only
2550 # be a generated file in the build tree.
2551 if (! -f $ddest) {
2552 $ddest = cleanfile($buildd, $dest, $blddir);
b96ab5e6
RL
2553 }
2554 }
ef57f799
RL
2555 foreach my $v (@{$defines{$dest}}) {
2556 $v =~ m|^([^=]*)(=.*)?$|;
b96ab5e6 2557 die "0 length macro name not permitted\n" if $1 eq "";
ef57f799
RL
2558 if ($dest ne "") {
2559 die "$1 defined more than once\n"
2560 if defined $unified_info{defines}->{$ddest}->{$1};
2561 $unified_info{defines}->{$ddest}->{$1} = $2;
2562 } else {
2563 die "$1 defined more than once\n"
2564 if grep { $v eq $_ } @{$config{defines}};
2565 push @{$config{defines}}, $v;
2566 }
b96ab5e6
RL
2567 }
2568 }
829f86bb 2569
d594d2e1
P
2570 foreach my $section (keys %imagedocs) {
2571 foreach (@{$imagedocs{$section}}) {
2572 my $imagedocs = cleanfile($buildd, $_, $blddir);
2573 $unified_info{imagedocs}->{$section}->{$imagedocs} = 1;
2574 }
2575 }
2576
829f86bb
RL
2577 foreach my $section (keys %htmldocs) {
2578 foreach (@{$htmldocs{$section}}) {
2579 my $htmldocs = cleanfile($buildd, $_, $blddir);
2580 $unified_info{htmldocs}->{$section}->{$htmldocs} = 1;
2581 }
2582 }
2583
2584 foreach my $section (keys %mandocs) {
2585 foreach (@{$mandocs{$section}}) {
2586 my $mandocs = cleanfile($buildd, $_, $blddir);
2587 $unified_info{mandocs}->{$section}->{$mandocs} = 1;
2588 }
2589 }
9fe2bb77
RL
2590 }
2591
d201dbc9
RL
2592 my $ordinals_text = join(', ', sort keys %ordinals);
2593 warn <<"EOF" if $ordinals_text;
2594
2595WARNING: ORDINALS were specified for $ordinals_text
2596They are ignored and should be replaced with a combination of GENERATE,
2597DEPEND and SHARED_SOURCE.
2598EOF
2599
507f8380
RL
2600 # Check that each generated file is only generated once
2601 my $ambiguous_generation = 0;
2602 foreach (sort keys %check_generate) {
2603 my @generators = sort keys %{$check_generate{$_}};
2604 my $generators_txt = join(', ', @generators);
2605 if (scalar @generators > 1) {
2606 warn "$_ is GENERATEd by more than one generator ($generators_txt)\n";
2607 $ambiguous_generation++;
2608 }
2497e2e7
RL
2609 if ($check_generate{$_}->{$generators[0]} > 1) {
2610 warn "INFO: $_ has more than one GENERATE declaration (same generator)\n"
2611 }
507f8380
RL
2612 }
2613 die "There are ambiguous source file generations\n"
2614 if $ambiguous_generation > 0;
2615
2616 # All given source files should exist, or if generated, their
2617 # generator should exist. This loop ensures this is true.
2618 my $missing = 0;
2619 foreach my $orig (sort keys %check_exist) {
2620 foreach my $dest (@{$check_exist{$orig}}) {
2621 if ($orig ne $src_configdata) {
2622 if ($orig =~ /\.a$/) {
2623 # Static library names may be used as sources, so we
2624 # need to detect those and give them special treatment.
2625 unless (grep { $_ eq $orig }
2626 keys %{$unified_info{libraries}}) {
2627 warn "$orig is given as source for $dest, but no such library is built\n";
2628 $missing++;
2629 }
2630 } else {
2631 # A source may be generated, and its generator may be
2632 # generated as well. We therefore loop to dig out the
2633 # first generator.
2634 my $gen = $orig;
2635
2636 while (my @next = keys %{$check_generate{$gen}}) {
2637 $gen = $next[0];
2638 }
2639
2640 if (! -f $gen) {
2641 if ($gen ne $orig) {
2642 $missing++;
2643 warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n";
2644 } else {
2645 $missing++;
2646 warn "$orig is given as source for $dest, but is missing\n";
2647 }
2648 }
2649 }
2650 }
2651 }
2652 }
2653 die "There are files missing\n" if $missing > 0;
51583cb8
RL
2654
2655 # Go through the sources of all libraries and check that the same basename
2656 # doesn't appear more than once. Some static library archivers depend on
2657 # them being unique.
2658 {
2659 my $err = 0;
2660 foreach my $prod (keys %{$unified_info{libraries}}) {
2661 my @prod_sources =
2662 map { keys %{$unified_info{sources}->{$_}} }
2663 keys %{$unified_info{sources}->{$prod}};
2664 my %srccnt = ();
2665
2666 # Count how many times a given each source basename
2667 # appears for each product.
2668 foreach my $src (@prod_sources) {
2669 $srccnt{basename $src}++;
2670 }
2671
2672 foreach my $src (keys %srccnt) {
2673 if ((my $cnt = $srccnt{$src}) > 1) {
2674 print STDERR "$src appears $cnt times for the product $prod\n";
2675 $err++
2676 }
2677 }
2678 }
2679 die if $err > 0;
2680 }
2681
1b5ad51f
RL
2682 # Massage the result
2683
e431bcfa
RL
2684 # If we depend on a header file or a perl module, add an inclusion of
2685 # its directory to allow smoothe inclusion
2686 foreach my $dest (keys %{$unified_info{depends}}) {
2687 next if $dest eq "";
2688 foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
2689 next unless $d =~ /\.(h|pm)$/;
b684ee2c
RL
2690 # Take into account when a dependency uses the inclusion|module
2691 # syntax
2692 my $i = $d =~ m/\|/ ? $` : dirname($d);
906032d5
RL
2693 my $spot =
2694 $d eq "configdata.pm" || defined($unified_info{generate}->{$d})
2695 ? 'build' : 'source';
2696 push @{$unified_info{includes}->{$dest}->{$spot}}, $i
2697 unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{$spot}};
e431bcfa
RL
2698 }
2699 }
2700
ef2dfc99 2701 # Go through all intermediary files and change their names to something that
bec2db18
RL
2702 # reflects what they will be built for. Note that for some source files,
2703 # this leads to duplicate object files because they are used multiple times.
2704 # the goal is to rename all object files according to this scheme:
2705 # {productname}-{midfix}-{origobjname}.[o|res]
2706 # the {midfix} is a keyword indicating the type of product, which is mostly
2707 # valuable for libraries since they come in two forms.
2708 #
2709 # This also reorganises the {sources} and {shared_sources} so that the
2710 # former only contains ALL object files that are supposed to end up in
2711 # static libraries and programs, while the latter contains ALL object files
2712 # that are supposed to end up in shared libraries and DSOs.
2713 # The main reason for having two different source structures is to allow
2714 # the same name to be used for the static and the shared variants of a
2715 # library.
2716 {
2717 # Take copies so we don't get interference from added stuff
2718 my %unified_copy = ();
2719 foreach (('sources', 'shared_sources')) {
2720 $unified_copy{$_} = { %{$unified_info{$_}} }
2721 if defined($unified_info{$_});
2722 delete $unified_info{$_};
2723 }
1842f369 2724 foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) {
bec2db18
RL
2725 # $intent serves multi purposes:
2726 # - give a prefix for the new object files names
2727 # - in the case of libraries, rearrange the object files so static
2728 # libraries use the 'sources' structure exclusively, while shared
2729 # libraries use the 'shared_sources' structure exclusively.
2730 my $intent = {
2731 programs => { bin => { src => [ 'sources' ],
2732 dst => 'sources' } },
2733 libraries => { lib => { src => [ 'sources' ],
2734 dst => 'sources' },
2735 shlib => { prodselect =>
2736 sub { grep !/\.a$/, @_ },
2737 src => [ 'sources',
2738 'shared_sources' ],
2739 dst => 'shared_sources' } },
22b41467
RL
2740 modules => { dso => { src => [ 'sources' ],
2741 dst => 'sources' } },
bec2db18
RL
2742 scripts => { script => { src => [ 'sources' ],
2743 dst => 'sources' } }
2744 } -> {$prodtype};
2745 foreach my $kind (keys %$intent) {
856b1b65
RL
2746 next if ($intent->{$kind}->{dst} eq 'shared_sources'
2747 && $disabled{shared});
2748
bec2db18
RL
2749 my @src = @{$intent->{$kind}->{src}};
2750 my $dst = $intent->{$kind}->{dst};
2751 my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ };
2752 foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) {
2753 # %prod_sources has all applicable objects as keys, and
2754 # their corresponding sources as values
2755 my %prod_sources =
2756 map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] }
2757 map { keys %{$unified_copy{$_}->{$prod}} }
2758 @src;
2759 foreach (keys %prod_sources) {
ef2dfc99
RL
2760 # Only affect object files and resource files,
2761 # the others simply get a new value
2762 # (+1 instead of -1)
bec2db18
RL
2763 if ($_ =~ /\.(o|res)$/) {
2764 (my $prodname = $prod) =~ s|\.a$||;
2765 my $newobj =
2766 catfile(dirname($_),
2767 basename($prodname)
2768 . '-' . $kind
2769 . '-' . basename($_));
2770 $unified_info{$dst}->{$prod}->{$newobj} = 1;
2771 foreach my $src (@{$prod_sources{$_}}) {
2772 $unified_info{sources}->{$newobj}->{$src} = 1;
dd05c793
RL
2773 # Adjust source attributes
2774 my $attrs = $unified_info{attributes}->{sources};
2775 if (defined $attrs->{$prod}
2776 && defined $attrs->{$prod}->{$_}) {
2777 $attrs->{$prod}->{$newobj} =
2778 $attrs->{$prod}->{$_};
2779 delete $attrs->{$prod}->{$_};
2780 }
2781 foreach my $objsrc (keys %{$attrs->{$_} // {}}) {
2782 $attrs->{$newobj}->{$objsrc} =
2783 $attrs->{$_}->{$objsrc};
2784 delete $attrs->{$_}->{$objsrc};
2785 }
bec2db18
RL
2786 }
2787 # Adjust dependencies
2788 foreach my $deps (keys %{$unified_info{depends}->{$_}}) {
2789 $unified_info{depends}->{$_}->{$deps} = -1;
2790 $unified_info{depends}->{$newobj}->{$deps} = 1;
2791 }
2792 # Adjust includes
2793 foreach my $k (('source', 'build')) {
2794 next unless
2795 defined($unified_info{includes}->{$_}->{$k});
2796 my @incs = @{$unified_info{includes}->{$_}->{$k}};
2797 $unified_info{includes}->{$newobj}->{$k} = [ @incs ];
2798 }
2799 } else {
2800 $unified_info{$dst}->{$prod}->{$_} = 1;
2801 }
2802 }
2803 }
2804 }
2805 }
2806 }
51583cb8 2807
bec2db18
RL
2808 # At this point, we have a number of sources with the value -1. They
2809 # aren't part of the local build and are probably meant for a different
2810 # platform, and can therefore be cleaned away. That happens when making
2811 # %unified_info more efficient below.
2812
9fe2bb77
RL
2813 ### Make unified_info a bit more efficient
2814 # One level structures
3f399e37 2815 foreach (("programs", "libraries", "modules", "scripts", "targets")) {
9fe2bb77
RL
2816 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
2817 }
2818 # Two level structures
829f86bb 2819 foreach my $l1 (("sources", "shared_sources", "ldadd", "depends",
d594d2e1 2820 "imagedocs", "htmldocs", "mandocs")) {
9fe2bb77 2821 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
bec2db18
RL
2822 my @items =
2823 sort
2824 grep { $unified_info{$l1}->{$l2}->{$_} > 0 }
2825 keys %{$unified_info{$l1}->{$l2}};
2826 if (@items) {
2827 $unified_info{$l1}->{$l2} = [ @items ];
2828 } else {
2829 delete $unified_info{$l1}->{$l2};
2830 }
9fe2bb77
RL
2831 }
2832 }
b96ab5e6
RL
2833 # Defines
2834 foreach my $dest (sort keys %{$unified_info{defines}}) {
2835 $unified_info{defines}->{$dest}
2836 = [ map { $_.$unified_info{defines}->{$dest}->{$_} }
2837 sort keys %{$unified_info{defines}->{$dest}} ];
2838 }
4748f890
RL
2839 # Includes
2840 foreach my $dest (sort keys %{$unified_info{includes}}) {
2841 if (defined($unified_info{includes}->{$dest}->{build})) {
e431bcfa
RL
2842 my @source_includes = ();
2843 @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} )
2844 if defined($unified_info{includes}->{$dest}->{source});
4748f890
RL
2845 $unified_info{includes}->{$dest} =
2846 [ @{$unified_info{includes}->{$dest}->{build}} ];
2847 foreach my $inc (@source_includes) {
2848 push @{$unified_info{includes}->{$dest}}, $inc
2849 unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
2850 }
609e4be8 2851 } elsif (defined($unified_info{includes}->{$dest}->{source})) {
4748f890
RL
2852 $unified_info{includes}->{$dest} =
2853 [ @{$unified_info{includes}->{$dest}->{source}} ];
609e4be8
RL
2854 } else {
2855 delete $unified_info{includes}->{$dest};
4748f890
RL
2856 }
2857 }
b6e66075
RL
2858
2859 # For convenience collect information regarding directories where
2860 # files are generated, those generated files and the end product
2861 # they end up in where applicable. Then, add build rules for those
2862 # directories
2863 my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ],
1842f369 2864 "dso" => [ @{$unified_info{modules}} ],
b6e66075 2865 "bin" => [ @{$unified_info{programs}} ],
829f86bb 2866 "script" => [ @{$unified_info{scripts}} ],
d594d2e1
P
2867 "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} }
2868 keys %{$unified_info{imagedocs} // {}}),
2869 (map { @{$unified_info{htmldocs}->{$_} // []} }
829f86bb
RL
2870 keys %{$unified_info{htmldocs} // {}}),
2871 (map { @{$unified_info{mandocs}->{$_} // []} }
2872 keys %{$unified_info{mandocs} // {}}) ] );
764cf5b2 2873 foreach my $type (sort keys %loopinfo) {
b6e66075
RL
2874 foreach my $product (@{$loopinfo{$type}}) {
2875 my %dirs = ();
2876 my $pd = dirname($product);
2877
3bed01a0 2878 foreach (@{$unified_info{sources}->{$product} // []},
b6e66075
RL
2879 @{$unified_info{shared_sources}->{$product} // []}) {
2880 my $d = dirname($_);
2881
2882 # We don't want to create targets for source directories
2883 # when building out of source
2884 next if ($config{sourcedir} ne $config{builddir}
2885 && $d =~ m|^\Q$config{sourcedir}\E|);
2886 # We already have a "test" target, and the current directory
2887 # is just silly to make a target for
2888 next if $d eq "test" || $d eq ".";
2889
2890 $dirs{$d} = 1;
2891 push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
2892 if $d ne $pd;
2893 }
764cf5b2 2894 foreach (sort keys %dirs) {
b6e66075
RL
2895 push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
2896 $product;
2897 }
2898 }
2899 }
9fe2bb77
RL
2900}
2901
2902# For the schemes that need it, we provide the old *_obj configs
2903# from the *_asm_obj ones
3a55c92b 2904foreach (grep /_(asm|aux)_src$/, keys %target) {
9fe2bb77 2905 my $src = $_;
3a55c92b 2906 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
ea241958
RL
2907 $target{$obj} = $target{$src};
2908 $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
2909 $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
9fe2bb77
RL
2910}
2911
291e94df
RL
2912# Write down our configuration where it fits #########################
2913
1f86b822
RL
2914my %template_vars = (
2915 config => \%config,
2916 target => \%target,
2917 disablables => \@disablables,
2918 disablables_int => \@disablables_int,
2919 disabled => \%disabled,
2920 withargs => \%withargs,
2921 unified_info => \%unified_info,
2922 tls => \@tls,
2923 dtls => \@dtls,
2924 makevars => [ sort keys %user ],
2925 disabled_info => \%disabled_info,
2926 user_crossable => \@user_crossable,
291e94df 2927);
1f86b822 2928my $configdata_outname = 'configdata.pm';
1f86b822 2929open CONFIGDATA, ">$configdata_outname.new"
2660b7cf 2930 or die "Trying to create $configdata_outname.new: $!";
504ff2a4 2931my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir, 1);
1f86b822
RL
2932my $configdata_tmpl =
2933 OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname);
2934$configdata_tmpl->fill_in(
2935 FILENAME => $configdata_tmplname,
2936 OUTPUT => \*CONFIGDATA,
2937 HASH => { %template_vars,
2938 autowarntext => [
2939 'WARNING: do not edit!',
2940 "Generated by Configure from $configdata_tmplname",
2941 ] }
2942) or die $Text::Template::ERROR;
2943close CONFIGDATA;
764cf5b2 2944
54a84f02
RL
2945rename "$configdata_outname.new", $configdata_outname;
2946if ($builder_platform eq 'unix') {
2947 my $mode = (0755 & ~umask);
2948 chmod $mode, 'configdata.pm'
2949 or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!);
764cf5b2 2950}
54a84f02
RL
2951print "Created $configdata_outname\n";
2952
2953print "Running $configdata_outname\n";
2954my $perlcmd = (quotify("maybeshell", $config{PERL}))[0];
2955my $cmd = "$perlcmd $configdata_outname";
2956#print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2957system($cmd);
2958exit 1 if $? != 0;
fce0ba5f 2959
8937a4ed
RL
2960$SIG{__DIE__} = $orig_death_handler;
2961
9c62a279 2962print <<"EOF" if ($disabled{threads} eq "unavailable");
5f8d5c96
BM
2963
2964The library could not be configured for supporting multi-threaded
2965applications as the compiler options required on this system are not known.
f828ba03 2966See file INSTALL.md for details if you need multi-threading.
ec577822
BM
2967EOF
2968
76ffb43d 2969print <<"EOF" if ($no_shared_warn);
2964ba8c 2970
ae48242c
RL
2971The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2972platform, so we will pretend you gave the option 'no-pic', which also disables
2973'shared' and 'dynamic-engine'. If you know how to implement shared libraries
2974or position independent code, please let us know (but please first make sure
2975you have tried with a current version of OpenSSL).
2e31ef03
RS
2976EOF
2977
d0364dcc 2978print $banner;
820e414d 2979
d02b48c6
RE
2980exit(0);
2981
bd5192b1
RL
2982######################################################################
2983#
2984# Helpers and utility functions
2985#
2986
8937a4ed
RL
2987# Death handler, to print a helpful message in case of failure #######
2988#
2989sub death_handler {
eb807d53 2990 die @_ if $^S; # To prevent the added message in eval blocks
aa2d7e0e 2991 my $build_file = $config{build_file} // "build file";
eb807d53 2992 my @message = ( <<"_____", @_ );
8937a4ed
RL
2993
2994Failure! $build_file wasn't produced.
1dc1ea18 2995Please read INSTALL.md and associated NOTES-* files. You may also have to
f828ba03 2996look over your available compiler tool chain or change your configuration.
8937a4ed
RL
2997
2998_____
eb807d53
RL
2999
3000 # Dying is terminal, so it's ok to reset the signal handler here.
3001 $SIG{__DIE__} = $orig_death_handler;
3002 die @message;
8937a4ed
RL
3003}
3004
bd5192b1
RL
3005# Configuration file reading #########################################
3006
1f2e1cd5
RL
3007# Note: All of the helper functions are for lazy evaluation. They all
3008# return a CODE ref, which will return the intended value when evaluated.
3009# Thus, whenever there's mention of a returned value, it's about that
3010# intended value.
3011
1f2e1cd5
RL
3012# Helper function to implement conditional value variants, with a default
3013# plus additional values based on the value of $config{build_type}.
3014# Arguments are given in hash table form:
3015#
3016# picker(default => "Basic string: ",
3017# debug => "debug",
3018# release => "release")
3019#
3020# When configuring with --debug, the resulting string will be
3021# "Basic string: debug", and when not, it will be "Basic string: release"
3022#
3023# This can be used to create variants of sets of flags according to the
3024# build type:
3025#
3026# cflags => picker(default => "-Wall",
3027# debug => "-g -O0",
3028# release => "-O3")
3029#
3030sub picker {
3031 my %opts = @_;
3032 return sub { add($opts{default} || (),
3033 $opts{$config{build_type}} || ())->(); }
3034}
3035
3036# Helper function to combine several values of different types into one.
3037# This is useful if you want to combine a string with the result of a
3038# lazy function, such as:
3039#
3040# cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
3041#
3042sub combine {
3043 my @stuff = @_;
3044 return sub { add(@stuff)->(); }
3045}
3046
3047# Helper function to implement conditional values depending on the value
3048# of $disabled{threads}. Can be used as follows:
3049#
3050# cflags => combine("-Wall", threads("-pthread"))
3051#
3052sub threads {
3053 my @flags = @_;
3054 return sub { add($disabled{threads} ? () : @flags)->(); }
3055}
3056
60aa6c1a
AP
3057sub shared {
3058 my @flags = @_;
3059 return sub { add($disabled{shared} ? () : @flags)->(); }
3060}
1f2e1cd5 3061
9c62a279 3062our $add_called = 0;
88087414
RL
3063# Helper function to implement adding values to already existing configuration
3064# values. It handles elements that are ARRAYs, CODEs and scalars
3065sub _add {
3066 my $separator = shift;
3067
bcb1977b
RL
3068 # If there's any ARRAY in the collection of values OR the separator
3069 # is undef, we will return an ARRAY of combined values, otherwise a
3070 # string of joined values with $separator as the separator.
3071 my $found_array = !defined($separator);
88087414
RL
3072
3073 my @values =
84f32c84
DMSP
3074 map {
3075 my $res = $_;
3076 while (ref($res) eq "CODE") {
3077 $res = $res->();
3078 }
3079 if (defined($res)) {
3080 if (ref($res) eq "ARRAY") {
3081 $found_array = 1;
3082 @$res;
3083 } else {
3084 $res;
3085 }
3086 } else {
3087 ();
3088 }
88087414
RL
3089 } (@_);
3090
9c62a279
RL
3091 $add_called = 1;
3092
88087414 3093 if ($found_array) {
84f32c84 3094 [ @values ];
88087414 3095 } else {
84f32c84 3096 join($separator, grep { defined($_) && $_ ne "" } @values);
88087414
RL
3097 }
3098}
3099sub add_before {
bdcd83e1
RL
3100 my $separator = " ";
3101 if (ref($_[$#_]) eq "HASH") {
3102 my $opts = pop;
3103 $separator = $opts->{separator};
3104 }
88087414
RL
3105 my @x = @_;
3106 sub { _add($separator, @x, @_) };
3107}
3108sub add {
bdcd83e1
RL
3109 my $separator = " ";
3110 if (ref($_[$#_]) eq "HASH") {
3111 my $opts = pop;
3112 $separator = $opts->{separator};
3113 }
88087414
RL
3114 my @x = @_;
3115 sub { _add($separator, @_, @x) };
3116}
3117
3b6c4b07
RL
3118sub read_eval_file {
3119 my $fname = shift;
3120 my $content;
3121 my @result;
3122
3123 open F, "< $fname" or die "Can't open '$fname': $!\n";
3124 {
3125 undef local $/;
3126 $content = <F>;
3127 }
3128 close F;
3129 {
3130 local $@;
3131
3132 @result = ( eval $content );
3133 warn $@ if $@;
3134 }
3135 return wantarray ? @result : $result[0];
3136}
3137
bd5192b1
RL
3138# configuration reader, evaluates the input file as a perl script and expects
3139# it to fill %targets with target configurations. Those are then added to
3140# %table.
3141sub read_config {
3142 my $fname = shift;
3b6c4b07
RL
3143 my %targets;
3144
bd5192b1 3145 {
84f32c84
DMSP
3146 # Protect certain tables from tampering
3147 local %table = ();
bd5192b1 3148
84f32c84 3149 %targets = read_eval_file($fname);
bd5192b1 3150 }
225f980d
RL
3151 my %preexisting = ();
3152 foreach (sort keys %targets) {
3153 $preexisting{$_} = 1 if $table{$_};
3154 }
3155 die <<"EOF",
3156The following config targets from $fname
3157shadow pre-existing config targets with the same name:
3158EOF
3159 map { " $_\n" } sort keys %preexisting
3160 if %preexisting;
3161
bd5192b1
RL
3162
3163 # For each target, check that it's configured with a hash table.
3164 foreach (keys %targets) {
84f32c84
DMSP
3165 if (ref($targets{$_}) ne "HASH") {
3166 if (ref($targets{$_}) eq "") {
3167 warn "Deprecated target configuration for $_, ignoring...\n";
3168 } else {
3169 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
3170 }
3171 delete $targets{$_};
3172 } else {
ee9b0bbb
RL
3173 $targets{$_}->{_conf_fname_int} = add([ $fname ]);
3174 }
bd5192b1
RL
3175 }
3176
3177 %table = (%table, %targets);
3178
3179}
3180
8483a003
F
3181# configuration resolver. Will only resolve all the lazy evaluation
3182# codeblocks for the chosen target and all those it inherits from,
bd5192b1
RL
3183# recursively
3184sub resolve_config {
3185 my $target = shift;
3186 my @breadcrumbs = @_;
3187
c4718849 3188# my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
9c62a279 3189
bd5192b1 3190 if (grep { $_ eq $target } @breadcrumbs) {
84f32c84
DMSP
3191 die "inherit_from loop! target backtrace:\n "
3192 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
bd5192b1
RL
3193 }
3194
3195 if (!defined($table{$target})) {
84f32c84
DMSP
3196 warn "Warning! target $target doesn't exist!\n";
3197 return ();
bd5192b1
RL
3198 }
3199 # Recurse through all inheritances. They will be resolved on the
3200 # fly, so when this operation is done, they will all just be a
3201 # bunch of attributes with string values.
3202 # What we get here, though, are keys with references to lists of
3203 # the combined values of them all. We will deal with lists after
3204 # this stage is done.
3205 my %combined_inheritance = ();
3206 if ($table{$target}->{inherit_from}) {
84f32c84
DMSP
3207 my @inherit_from =
3208 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
3209 foreach (@inherit_from) {
3210 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
3211
3212 # 'template' is a marker that's considered private to
3213 # the config that had it.
3214 delete $inherited_config{template};
3215
3216 foreach (keys %inherited_config) {
3217 if (!$combined_inheritance{$_}) {
3218 $combined_inheritance{$_} = [];
3219 }
3220 push @{$combined_inheritance{$_}}, $inherited_config{$_};
3221 }
3222 }
bd5192b1
RL
3223 }
3224
3225 # We won't need inherit_from in this target any more, since we've
3226 # resolved all the inheritances that lead to this
3227 delete $table{$target}->{inherit_from};
3228
3229 # Now is the time to deal with those lists. Here's the place to
3230 # decide what shall be done with those lists, all based on the
3231 # values of the target we're currently dealing with.
3232 # - If a value is a coderef, it will be executed with the list of
3233 # inherited values as arguments.
3234 # - If the corresponding key doesn't have a value at all or is the
8483a003 3235 # empty string, the inherited value list will be run through the
bd5192b1
RL
3236 # default combiner (below), and the result becomes this target's
3237 # value.
3238 # - Otherwise, this target's value is assumed to be a string that
3239 # will simply override the inherited list of values.
a26d8be9 3240 my $default_combiner = add();
bd5192b1
RL
3241
3242 my %all_keys =
84f32c84
DMSP
3243 map { $_ => 1 } (keys %combined_inheritance,
3244 keys %{$table{$target}});
b0b92a5b
RL
3245
3246 sub process_values {
84f32c84
DMSP
3247 my $object = shift;
3248 my $inherited = shift; # Always a [ list ]
3249 my $target = shift;
3250 my $entry = shift;
b0b92a5b 3251
9c62a279
RL
3252 $add_called = 0;
3253
b0b92a5b
RL
3254 while(ref($object) eq "CODE") {
3255 $object = $object->(@$inherited);
3256 }
3257 if (!defined($object)) {
3258 return ();
3259 }
3260 elsif (ref($object) eq "ARRAY") {
9c62a279 3261 local $add_called; # To make sure recursive calls don't affect it
b0b92a5b
RL
3262 return [ map { process_values($_, $inherited, $target, $entry) }
3263 @$object ];
3264 } elsif (ref($object) eq "") {
3265 return $object;
3266 } else {
3267 die "cannot handle reference type ",ref($object)
3268 ," found in target ",$target," -> ",$entry,"\n";
3269 }
3270 }
3271
a595e328
AR
3272 foreach my $key (sort keys %all_keys) {
3273 my $previous = $combined_inheritance{$key};
bd5192b1 3274
84f32c84
DMSP
3275 # Current target doesn't have a value for the current key?
3276 # Assign it the default combiner, the rest of this loop body
3277 # will handle it just like any other coderef.
a595e328
AR
3278 if (!exists $table{$target}->{$key}) {
3279 $table{$target}->{$key} = $default_combiner;
84f32c84 3280 }
bd5192b1 3281
a595e328
AR
3282 $table{$target}->{$key} = process_values($table{$target}->{$key},
3283 $combined_inheritance{$key},
3284 $target, $key);
3285 unless(defined($table{$target}->{$key})) {
3286 delete $table{$target}->{$key};
b0b92a5b 3287 }
c4718849 3288# if ($extra_checks &&
a595e328
AR
3289# $previous && !($add_called || $previous ~~ $table{$target}->{$key})) {
3290# warn "$key got replaced in $target\n";
c4718849 3291# }
bd5192b1
RL
3292 }
3293
3294 # Finally done, return the result.
3295 return %{$table{$target}};
3296}
3297
462ba4f6 3298sub usage
84f32c84
DMSP
3299 {
3300 print STDERR $usage;
3301 print STDERR "\npick os/compiler from:\n";
3302 my $j=0;
3303 my $i;
10a926c1 3304 my $k=0;
84f32c84
DMSP
3305 foreach $i (sort keys %table)
3306 {
3307 next if $table{$i}->{template};
3308 next if $i =~ /^debug/;
3309 $k += length($i) + 1;
3310 if ($k > 78)
3311 {
3312 print STDERR "\n";
3313 $k=length($i);
3314 }
3315 print STDERR $i . " ";
3316 }
3317 foreach $i (sort keys %table)
3318 {
3319 next if $table{$i}->{template};
3320 next if $i !~ /^debug/;
3321 $k += length($i) + 1;
3322 if ($k > 78)
3323 {
3324 print STDERR "\n";
3325 $k=length($i);
3326 }
3327 print STDERR $i . " ";
3328 }
84f32c84
DMSP
3329 exit(1);
3330 }
d02b48c6 3331
6d75a83c
RL
3332sub compiler_predefined {
3333 state %predefined;
41d6e0f3 3334 my $cc = shift;
6d75a83c
RL
3335
3336 return () if $^O eq 'VMS';
3337
41d6e0f3
AP
3338 die 'compiler_predefined called without a compiler command'
3339 unless $cc;
6d75a83c 3340
41d6e0f3 3341 if (! $predefined{$cc}) {
6d75a83c 3342
41d6e0f3 3343 $predefined{$cc} = {};
6d75a83c
RL
3344
3345 # collect compiler pre-defines from gcc or gcc-alike...
3346 open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
3347 while (my $l = <PIPE>) {
3348 $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
41d6e0f3 3349 $predefined{$cc}->{$1} = $2 // '';
6d75a83c
RL
3350 }
3351 close(PIPE);
3352 }
3353
41d6e0f3 3354 return %{$predefined{$cc}};
6d75a83c
RL
3355}
3356
656bbdc6
AP
3357sub which
3358{
3359 my ($name)=@_;
3360
3361 if (eval { require IPC::Cmd; 1; }) {
3362 IPC::Cmd->import();
3363 return scalar IPC::Cmd::can_run($name);
3364 } else {
3365 # if there is $directories component in splitpath,
3366 # then it's not something to test with $PATH...
3367 return $name if (File::Spec->splitpath($name))[1];
3368
3369 foreach (File::Spec->path()) {
3370 my $fullpath = catfile($_, "$name$target{exe_extension}");
3371 if (-f $fullpath and -x $fullpath) {
3372 return $fullpath;
3373 }
3374 }
3375 }
3376}
3377
7ecdf18d
RL
3378sub env
3379{
3380 my $name = shift;
ac6ae8a9 3381 my %opts = @_;
7ecdf18d 3382
ac6ae8a9
RL
3383 unless ($opts{cacheonly}) {
3384 # Note that if $ENV{$name} doesn't exist or is undefined,
3385 # $config{perlenv}->{$name} will be created with the value
3386 # undef. This is intentional.
89bea083 3387
ac6ae8a9
RL
3388 $config{perlenv}->{$name} = $ENV{$name}
3389 if ! exists $config{perlenv}->{$name};
3390 }
7ecdf18d
RL
3391 return $config{perlenv}->{$name};
3392}
3393
00ae96ca
RL
3394# Configuration printer ##############################################
3395
3396sub print_table_entry
3397{
f770d75b
AP
3398 local $now_printing = shift;
3399 my %target = resolve_config($now_printing);
00ae96ca
RL
3400 my $type = shift;
3401
3402 # Don't print the templates
3403 return if $target{template};
3404
3405 my @sequence = (
84f32c84
DMSP
3406 "sys_id",
3407 "cpp",
3408 "cppflags",
3409 "defines",
3410 "includes",
3411 "cc",
3412 "cflags",
84f32c84
DMSP
3413 "ld",
3414 "lflags",
3415 "loutflag",
3416 "ex_libs",
3417 "bn_ops",
37fe90ad
RL
3418 "enable",
3419 "disable",
84f32c84
DMSP
3420 "poly1035_asm_src",
3421 "thread_scheme",
3422 "perlasm_scheme",
3423 "dso_scheme",
3424 "shared_target",
3425 "shared_cflag",
3426 "shared_defines",
3427 "shared_ldflag",
3428 "shared_rcflag",
3429 "shared_extension",
3430 "dso_extension",
3431 "obj_extension",
3432 "exe_extension",
3433 "ranlib",
3434 "ar",
3435 "arflags",
3436 "aroutflag",
3437 "rc",
3438 "rcflags",
3439 "rcoutflag",
3440 "mt",
3441 "mtflags",
3442 "mtinflag",
3443 "mtoutflag",
3444 "multilib",
3445 "build_scheme",
3446 );
00ae96ca
RL
3447
3448 if ($type eq "TABLE") {
84f32c84
DMSP
3449 print "\n";
3450 print "*** $now_printing\n";
cb212f23
RL
3451 foreach (@sequence) {
3452 if (ref($target{$_}) eq "ARRAY") {
3453 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
3454 } else {
3455 printf "\$%-12s = %s\n", $_, $target{$_};
3456 }
3457 }
00ae96ca 3458 } elsif ($type eq "HASH") {
84f32c84
DMSP
3459 my $largest =
3460 length((sort { length($a) <=> length($b) } @sequence)[-1]);
3461 print " '$now_printing' => {\n";
3462 foreach (@sequence) {
3463 if ($target{$_}) {
cb212f23
RL
3464 if (ref($target{$_}) eq "ARRAY") {
3465 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
3466 } else {
3467 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
3468 }
84f32c84
DMSP
3469 }
3470 }
3471 print " },\n";
00ae96ca
RL
3472 }
3473}
3474
3475# Utility routines ###################################################
3476
2e963849
RL
3477# On VMS, if the given file is a logical name, File::Spec::Functions
3478# will consider it an absolute path. There are cases when we want a
3479# purely syntactic check without checking the environment.
3480sub isabsolute {
3481 my $file = shift;
3482
3483 # On non-platforms, we just use file_name_is_absolute().
3484 return file_name_is_absolute($file) unless $^O eq "VMS";
3485
69687aa8 3486 # If the file spec includes a device or a directory spec,
2e963849
RL
3487 # file_name_is_absolute() is perfectly safe.
3488 return file_name_is_absolute($file) if $file =~ m|[:\[]|;
3489
3490 # Here, we know the given file spec isn't absolute
3491 return 0;
3492}
3493
ec182ef0
RL
3494# Makes a directory absolute and cleans out /../ in paths like foo/../bar
3495# On some platforms, this uses rel2abs(), while on others, realpath() is used.
3496# realpath() requires that at least all path components except the last is an
3497# existing directory. On VMS, the last component of the directory spec must
3498# exist.
3499sub absolutedir {
3500 my $dir = shift;
3501
3502 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
3503 # will return the volume name for the device, no matter what. Also,
3504 # it will return an incorrect directory spec if the argument is a
3505 # directory that doesn't exist.
3506 if ($^O eq "VMS") {
3507 return rel2abs($dir);
3508 }
3509
3510 # We use realpath() on Unix, since no other will properly clean out
3511 # a directory spec.
3512 use Cwd qw/realpath/;
3513
3514 return realpath($dir);
3515}
3516
610e2b3b
RL
3517# Check if all paths are one and the same, using stat. They must both exist
3518# We need this for the cases when File::Spec doesn't detect case insensitivity
3519# (File::Spec::Unix assumes case sensitivity)
3520sub samedir {
3521 die "samedir expects two arguments\n" unless scalar @_ == 2;
3522
3523 my @stat0 = stat($_[0]); # First argument
3524 my @stat1 = stat($_[1]); # Second argument
3525
3526 die "Couldn't stat $_[0]" unless @stat0;
3527 die "Couldn't stat $_[1]" unless @stat1;
3528
3529 # Compare device number
3530 return 0 unless ($stat0[0] == $stat1[0]);
3531 # Compare "inode". The perl manual recommends comparing as
3532 # string rather than as number.
3533 return 0 unless ($stat0[1] eq $stat1[1]);
3534
3535 return 1; # All the same
3536}
3537
fe05264e
RL
3538sub quotify {
3539 my %processors = (
84f32c84
DMSP
3540 perl => sub { my $x = shift;
3541 $x =~ s/([\\\$\@"])/\\$1/g;
3542 return '"'.$x.'"'; },
3543 maybeshell => sub { my $x = shift;
3544 (my $y = $x) =~ s/([\\\"])/\\$1/g;
3545 if ($x ne $y || $x =~ m|\s|) {
3546 return '"'.$y.'"';
3547 } else {
3548 return $x;
3549 }
3550 },
3551 );
fe05264e
RL
3552 my $for = shift;
3553 my $processor =
84f32c84 3554 defined($processors{$for}) ? $processors{$for} : sub { shift; };
fe05264e 3555
2110febb 3556 return map { $processor->($_); } @_;
fe05264e 3557}
107b5792 3558
9fe2bb77
RL
3559# collect_from_file($filename, $line_concat_cond_re, $line_concat)
3560# $filename is a file name to read from
3561# $line_concat_cond_re is a regexp detecting a line continuation ending
3562# $line_concat is a CODEref that takes care of concatenating two lines
3563sub collect_from_file {
3564 my $filename = shift;
3565 my $line_concat_cond_re = shift;
3566 my $line_concat = shift;
3567
3568 open my $fh, $filename || die "unable to read $filename: $!\n";
3569 return sub {
3570 my $saved_line = "";
3571 $_ = "";
3572 while (<$fh>) {
04f171c0 3573 s|\R$||;
9fe2bb77
RL
3574 if (defined $line_concat) {
3575 $_ = $line_concat->($saved_line, $_);
3576 $saved_line = "";
3577 }
3578 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3579 $saved_line = $_;
3580 next;
3581 }
3582 return $_;
3583 }
3584 die "$filename ending with continuation line\n" if $_;
3585 close $fh;
3586 return undef;
3587 }
3588}
3589
3590# collect_from_array($array, $line_concat_cond_re, $line_concat)
3591# $array is an ARRAYref of lines
3592# $line_concat_cond_re is a regexp detecting a line continuation ending
3593# $line_concat is a CODEref that takes care of concatenating two lines
3594sub collect_from_array {
3595 my $array = shift;
3596 my $line_concat_cond_re = shift;
3597 my $line_concat = shift;
3598 my @array = (@$array);
3599
3600 return sub {
3601 my $saved_line = "";
3602 $_ = "";
3603 while (defined($_ = shift @array)) {
04f171c0 3604 s|\R$||;
9fe2bb77
RL
3605 if (defined $line_concat) {
3606 $_ = $line_concat->($saved_line, $_);
3607 $saved_line = "";
3608 }
3609 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3610 $saved_line = $_;
3611 next;
3612 }
3613 return $_;
3614 }
3615 die "input text ending with continuation line\n" if $_;
3616 return undef;
3617 }
3618}
3619
3620# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
3621# $lineiterator is a CODEref that delivers one line at a time.
107b5792
RL
3622# All following arguments are regex/CODEref pairs, where the regexp detects a
3623# line and the CODEref does something with the result of the regexp.
3624sub collect_information {
9fe2bb77 3625 my $lineiterator = shift;
107b5792
RL
3626 my %collectors = @_;
3627
9fe2bb77 3628 while(defined($_ = $lineiterator->())) {
04f171c0 3629 s|\R$||;
9fe2bb77 3630 my $found = 0;
2b6b606c
RL
3631 if ($collectors{"BEFORE"}) {
3632 $collectors{"BEFORE"}->($_);
3633 }
9fe2bb77 3634 foreach my $re (keys %collectors) {
2b6b606c 3635 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
9fe2bb77
RL
3636 $collectors{$re}->($lineiterator);
3637 $found = 1;
3638 };
3639 }
3640 if ($collectors{"OTHERWISE"}) {
3641 $collectors{"OTHERWISE"}->($lineiterator, $_)
3642 unless $found || !defined $collectors{"OTHERWISE"};
3643 }
2b6b606c
RL
3644 if ($collectors{"AFTER"}) {
3645 $collectors{"AFTER"}->($_);
3646 }
107b5792 3647 }
107b5792 3648}
ce959812
RL
3649
3650# tokenize($line)
5d3af259 3651# tokenize($line,$separator)
ce959812 3652# $line is a line of text to split up into tokens
5d3af259
RL
3653# $separator [optional] is a regular expression that separates the tokens,
3654# the default being spaces. Do not use quotes of any kind as separators,
3655# that will give undefined results.
3656# Returns a list of tokens.
ce959812 3657#
5d3af259
RL
3658# Tokens are divided by separator (spaces by default). If the tokens include
3659# the separators, they have to be quoted with single or double quotes.
3660# Double quotes inside a double quoted token must be escaped. Escaping is done
ce959812
RL
3661# with backslash.
3662# Basically, the same quoting rules apply for " and ' as in any
3663# Unix shell.
3664sub tokenize {
3665 my $line = my $debug_line = shift;
5d3af259 3666 my $separator = shift // qr|\s+|;
ce959812
RL
3667 my @result = ();
3668
5d3af259
RL
3669 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3670 print STDERR "DEBUG[tokenize]: \$separator = $separator\n";
3671 }
3672
3673 while ($line =~ s|^${separator}||, $line ne "") {
ce959812 3674 my $token = "";
5d3af259
RL
3675 again:
3676 $line =~ m/^(.*?)(${separator}|"|'|$)/;
3677 $token .= $1;
3678 $line = $2.$';
3679
3680 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
3681 $token .= $1;
3682 $line = $';
3683 goto again;
3684 } elsif ($line =~ m/^'([^']*)'/) {
3685 $token .= $1;
3686 $line = $';
3687 goto again;
ce959812
RL
3688 }
3689 push @result, $token;
3690 }
3691
3692 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
5d3af259
RL
3693 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
3694 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
ce959812
RL
3695 }
3696 return @result;
3697}