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