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