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