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