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