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