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