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