Refactor the ranlib attribute
[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 $config{cross_compile_prefix}="";
291 my $auto_threads=1;    # enable threads automatically? true by default
292 my $default_ranlib;
293
294 # Top level directories to build
295 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
296 # crypto/ subdirectories to build
297 $config{sdirs} = [
298     "objects",
299     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3",
300     "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes",
301     "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
302     "buffer", "bio", "stack", "lhash", "rand", "err",
303     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
304     "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store"
305     ];
306 # test/ subdirectories to build
307 $config{tdirs} = [ "ossl_shim" ];
308
309 # Known TLS and DTLS protocols
310 my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
311 my @dtls = qw(dtls1 dtls1_2);
312
313 # Explicitly known options that are possible to disable.  They can
314 # be regexps, and will be used like this: /^no-${option}$/
315 # For developers: keep it sorted alphabetically
316
317 my @disablables = (
318     "afalgeng",
319     "aria",
320     "asan",
321     "asm",
322     "async",
323     "autoalginit",
324     "autoerrinit",
325     "bf",
326     "blake2",
327     "camellia",
328     "capieng",
329     "cast",
330     "chacha",
331     "cmac",
332     "cms",
333     "comp",
334     "crypto-mdebug",
335     "crypto-mdebug-backtrace",
336     "ct",
337     "deprecated",
338     "des",
339     "devcryptoeng",
340     "dgram",
341     "dh",
342     "dsa",
343     "dso",
344     "dtls",
345     "dynamic-engine",
346     "ec",
347     "ec2m",
348     "ecdh",
349     "ecdsa",
350     "ec_nistp_64_gcc_128",
351     "egd",
352     "engine",
353     "err",
354     "external-tests",
355     "filenames",
356     "fuzz-libfuzzer",
357     "fuzz-afl",
358     "gost",
359     "heartbeats",
360     "hw(-.+)?",
361     "idea",
362     "makedepend",
363     "md2",
364     "md4",
365     "mdc2",
366     "msan",
367     "multiblock",
368     "nextprotoneg",
369     "ocb",
370     "ocsp",
371     "pic",
372     "poly1305",
373     "posix-io",
374     "psk",
375     "rc2",
376     "rc4",
377     "rc5",
378     "rdrand",
379     "rfc3779",
380     "rmd160",
381     "scrypt",
382     "sctp",
383     "seed",
384     "shared",
385     "siphash",
386     "sm3",
387     "sm4",
388     "sock",
389     "srp",
390     "srtp",
391     "sse2",
392     "ssl",
393     "ssl-trace",
394     "static-engine",
395     "stdio",
396     "tests",
397     "threads",
398     "tls",
399     "tls13downgrade",
400     "ts",
401     "ubsan",
402     "ui-console",
403     "unit-test",
404     "whirlpool",
405     "weak-ssl-ciphers",
406     "zlib",
407     "zlib-dynamic",
408     );
409 foreach my $proto ((@tls, @dtls))
410         {
411         push(@disablables, $proto);
412         push(@disablables, "$proto-method") unless $proto eq "tls1_3";
413         }
414
415 my %deprecated_disablables = (
416     "ssl2" => undef,
417     "buf-freelists" => undef,
418     "ripemd" => "rmd160",
419     "ui" => "ui-console",
420     );
421
422 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
423
424 our %disabled = ( # "what"         => "comment"
425                   "asan"                => "default",
426                   "crypto-mdebug"       => "default",
427                   "crypto-mdebug-backtrace" => "default",
428                   "devcryptoeng"        => "default",
429                   "ec_nistp_64_gcc_128" => "default",
430                   "egd"                 => "default",
431                   "external-tests"      => "default",
432                   "fuzz-libfuzzer"      => "default",
433                   "fuzz-afl"            => "default",
434                   "heartbeats"          => "default",
435                   "md2"                 => "default",
436                   "msan"                => "default",
437                   "rc5"                 => "default",
438                   "sctp"                => "default",
439                   "ssl-trace"           => "default",
440                   "ssl3"                => "default",
441                   "ssl3-method"         => "default",
442                   "ubsan"               => "default",
443                   "tls13downgrade"      => "default",
444                   "unit-test"           => "default",
445                   "weak-ssl-ciphers"    => "default",
446                   "zlib"                => "default",
447                   "zlib-dynamic"        => "default",
448                 );
449
450 # Note: => pair form used for aesthetics, not to truly make a hash table
451 my @disable_cascades = (
452     # "what"            => [ "cascade", ... ]
453     sub { $config{processor} eq "386" }
454                         => [ "sse2" ],
455     "ssl"               => [ "ssl3" ],
456     "ssl3-method"       => [ "ssl3" ],
457     "zlib"              => [ "zlib-dynamic" ],
458     "des"               => [ "mdc2" ],
459     "ec"                => [ "ecdsa", "ecdh" ],
460
461     "dgram"             => [ "dtls", "sctp" ],
462     "sock"              => [ "dgram" ],
463     "dtls"              => [ @dtls ],
464     sub { 0 == scalar grep { !$disabled{$_} } @dtls }
465                         => [ "dtls" ],
466
467     "tls"               => [ @tls ],
468     sub { 0 == scalar grep { !$disabled{$_} } @tls }
469                         => [ "tls" ],
470
471     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
472
473     # Without DSO, we can't load dynamic engines, so don't build them dynamic
474     "dso"               => [ "dynamic-engine" ],
475
476     # Without position independent code, there can be no shared libraries or DSOs
477     "pic"               => [ "shared" ],
478     "shared"            => [ "dynamic-engine" ],
479     "engine"            => [ "afalgeng", "devcryptoeng" ],
480
481     # no-autoalginit is only useful when building non-shared
482     "autoalginit"       => [ "shared", "apps" ],
483
484     "stdio"             => [ "apps", "capieng", "egd" ],
485     "apps"              => [ "tests" ],
486     "tests"             => [ "external-tests" ],
487     "comp"              => [ "zlib" ],
488     "ec"                => [ "tls1_3" ],
489     sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
490
491     sub { !$disabled{"msan"} } => [ "asm" ],
492     );
493
494 # Avoid protocol support holes.  Also disable all versions below N, if version
495 # N is disabled while N+1 is enabled.
496 #
497 my @list = (reverse @tls);
498 while ((my $first, my $second) = (shift @list, shift @list)) {
499     last unless @list;
500     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
501                               => [ @list ] );
502     unshift @list, $second;
503 }
504 my @list = (reverse @dtls);
505 while ((my $first, my $second) = (shift @list, shift @list)) {
506     last unless @list;
507     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
508                               => [ @list ] );
509     unshift @list, $second;
510 }
511
512 # Explicit "no-..." options will be collected in %disabled along with the defaults.
513 # To remove something from %disabled, use "enable-foo".
514 # For symmetry, "disable-foo" is a synonym for "no-foo".
515
516 &usage if ($#ARGV < 0);
517
518 # For the "make variables" CINCLUDES and CDEFINES, we support lists with
519 # platform specific list separators.  Users from those platforms should
520 # recognise those separators from how you set up the PATH to find executables.
521 # The default is the Unix like separator, :, but as an exception, we also
522 # support the space as separator.
523 my $list_separator_re =
524     { VMS           => qr/(?<!\^),/,
525       MSWin32       => qr/(?<!\\);/ } -> {$^O} // qr/(?<!\\)[:\s]/;
526 # All the "make variables" we support
527 my %user = (
528     AR          => undef,
529     ARFLAGS     => [],
530     AS          => undef,
531     ASFLAGS     => [],
532     CC          => undef,
533     CFLAGS      => [],
534     CXX         => undef,
535     CXXFLAGS    => [],
536     CPP         => undef,
537     CPPFLAGS    => [],  # -D, -I, -Wp,
538     CPPDEFINES  => [],  # Alternative for -D
539     CPPINCLUDES => [],  # Alternative for -I
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 # The same but for flags given as Configure options.  These are *additional*
552 # input, as opposed to the VAR=string option that override the corresponding
553 # config target attributes
554 my %useradd = (
555     CPPDEFINES  => [],
556     CPPINCLUDES => [],
557     CPPFLAGS    => [],
558     CFLAGS      => [],
559     CXXFLAGS    => [],
560     LDFLAGS     => [],
561     LDLIBS      => [],
562    );
563
564 my %user_synonyms = (
565     HASHBANGPERL=> 'PERL',
566     RC          => 'WINDRES',
567    );
568 my %user_to_target = (
569     # If not given here, the value is the lc of the key
570     CPPDEFINES  => 'defines',
571     CPPINCLUDES => 'includes',
572     LDFLAGS     => 'lflags',
573     LDLIBS      => 'ex_libs',
574    );
575
576 $config{openssl_api_defines}=[];
577 $config{openssl_algorithm_defines}=[];
578 $config{openssl_thread_defines}=[];
579 $config{openssl_sys_defines}=[];
580 $config{openssl_other_defines}=[];
581 $config{options}="";
582 $config{build_type} = "release";
583 my $target="";
584
585 my %unsupported_options = ();
586 my %deprecated_options = ();
587 # If you change this, update apps/version.c
588 my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
589 my @seed_sources = ();
590 while (@argvcopy)
591         {
592         $_ = shift @argvcopy;
593
594         # Support env variable assignments among the options
595         if (m|^(\w+)=(.+)?$|)
596                 {
597                 $config{perlenv}->{$1} = $2;
598                 # Every time a variable is given as a configuration argument,
599                 # it acts as a reset if the variable.
600                 if (exists $user{$1})
601                         {
602                         $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef;
603                         }
604                 if (exists $useradd{$1})
605                         {
606                         $useradd{$1} = [];
607                         }
608                 next;
609                 }
610
611         # VMS is a case insensitive environment, and depending on settings
612         # out of our control, we may receive options uppercased.  Let's
613         # downcase at least the part before any equal sign.
614         if ($^O eq "VMS")
615                 {
616                 s/^([^=]*)/lc($1)/e;
617                 }
618         s /^-no-/no-/; # some people just can't read the instructions
619
620         # rewrite some options in "enable-..." form
621         s /^-?-?shared$/enable-shared/;
622         s /^sctp$/enable-sctp/;
623         s /^threads$/enable-threads/;
624         s /^zlib$/enable-zlib/;
625         s /^zlib-dynamic$/enable-zlib-dynamic/;
626
627         if (/^(no|disable|enable)-(.+)$/)
628                 {
629                 my $word = $2;
630                 if (!exists $deprecated_disablables{$word}
631                         && !grep { $word =~ /^${_}$/ } @disablables)
632                         {
633                         $unsupported_options{$_} = 1;
634                         next;
635                         }
636                 }
637         if (/^no-(.+)$/ || /^disable-(.+)$/)
638                 {
639                 foreach my $proto ((@tls, @dtls))
640                         {
641                         if ($1 eq "$proto-method")
642                                 {
643                                 $disabled{"$proto"} = "option($proto-method)";
644                                 last;
645                                 }
646                         }
647                 if ($1 eq "dtls")
648                         {
649                         foreach my $proto (@dtls)
650                                 {
651                                 $disabled{$proto} = "option(dtls)";
652                                 }
653                         $disabled{"dtls"} = "option(dtls)";
654                         }
655                 elsif ($1 eq "ssl")
656                         {
657                         # Last one of its kind
658                         $disabled{"ssl3"} = "option(ssl)";
659                         }
660                 elsif ($1 eq "tls")
661                         {
662                         # XXX: Tests will fail if all SSL/TLS
663                         # protocols are disabled.
664                         foreach my $proto (@tls)
665                                 {
666                                 $disabled{$proto} = "option(tls)";
667                                 }
668                         }
669                 elsif ($1 eq "static-engine")
670                         {
671                         delete $disabled{"dynamic-engine"};
672                         }
673                 elsif ($1 eq "dynamic-engine")
674                         {
675                         $disabled{"dynamic-engine"} = "option";
676                         }
677                 elsif (exists $deprecated_disablables{$1})
678                         {
679                         $deprecated_options{$_} = 1;
680                         if (defined $deprecated_disablables{$1})
681                                 {
682                                 $disabled{$deprecated_disablables{$1}} = "option";
683                                 }
684                         }
685                 else
686                         {
687                         $disabled{$1} = "option";
688                         }
689                 # No longer an automatic choice
690                 $auto_threads = 0 if ($1 eq "threads");
691                 }
692         elsif (/^enable-(.+)$/)
693                 {
694                 if ($1 eq "static-engine")
695                         {
696                         $disabled{"dynamic-engine"} = "option";
697                         }
698                 elsif ($1 eq "dynamic-engine")
699                         {
700                         delete $disabled{"dynamic-engine"};
701                         }
702                 elsif ($1 eq "zlib-dynamic")
703                         {
704                         delete $disabled{"zlib"};
705                         }
706                 my $algo = $1;
707                 delete $disabled{$algo};
708
709                 # No longer an automatic choice
710                 $auto_threads = 0 if ($1 eq "threads");
711                 }
712         elsif (/^--strict-warnings$/)
713                 {
714                 $strict_warnings = 1;
715                 }
716         elsif (/^--debug$/)
717                 {
718                 $config{build_type} = "debug";
719                 }
720         elsif (/^--release$/)
721                 {
722                 $config{build_type} = "release";
723                 }
724         elsif (/^386$/)
725                 { $config{processor}=386; }
726         elsif (/^fips$/)
727                 {
728                 die "FIPS mode not supported\n";
729                 }
730         elsif (/^rsaref$/)
731                 {
732                 # No RSAref support any more since it's not needed.
733                 # The check for the option is there so scripts aren't
734                 # broken
735                 }
736         elsif (/^nofipscanistercheck$/)
737                 {
738                 die "FIPS mode not supported\n";
739                 }
740         elsif (/^[-+]/)
741                 {
742                 if (/^--prefix=(.*)$/)
743                         {
744                         $config{prefix}=$1;
745                         die "Directory given with --prefix MUST be absolute\n"
746                                 unless file_name_is_absolute($config{prefix});
747                         }
748                 elsif (/^--api=(.*)$/)
749                         {
750                         $config{api}=$1;
751                         }
752                 elsif (/^--libdir=(.*)$/)
753                         {
754                         $config{libdir}=$1;
755                         }
756                 elsif (/^--openssldir=(.*)$/)
757                         {
758                         $config{openssldir}=$1;
759                         }
760                 elsif (/^--with-zlib-lib=(.*)$/)
761                         {
762                         $withargs{zlib_lib}=$1;
763                         }
764                 elsif (/^--with-zlib-include=(.*)$/)
765                         {
766                         $withargs{zlib_include}=$1;
767                         }
768                 elsif (/^--with-fuzzer-lib=(.*)$/)
769                         {
770                         $withargs{fuzzer_lib}=$1;
771                         }
772                 elsif (/^--with-fuzzer-include=(.*)$/)
773                         {
774                         $withargs{fuzzer_include}=$1;
775                         }
776                 elsif (/^--with-rand-seed=(.*)$/)
777                         {
778                         foreach my $x (split(m|,|, $1))
779                             {
780                             die "Unknown --with-rand-seed choice $x\n"
781                                 if ! grep { $x eq $_ } @known_seed_sources;
782                             push @seed_sources, $x;
783                             }
784                         }
785                 elsif (/^--cross-compile-prefix=(.*)$/)
786                         {
787                         $config{cross_compile_prefix}=$1;
788                         }
789                 elsif (/^--config=(.*)$/)
790                         {
791                         read_config $1;
792                         }
793                 elsif (/^-L(.*)$/)
794                         {
795                         push @{$useradd{LDFLAGS}}, $_;
796                         }
797                 elsif (/^-l(.*)$/ or /^-Wl,/)
798                         {
799                         push @{$useradd{LDLIBS}}, $_;
800                         }
801                 elsif (/^-framework$/)
802                         {
803                         push @{$useradd{LDLIBS}}, $_, shift(@argvcopy);
804                         }
805                 elsif (/^-rpath$/ or /^-R$/)
806                         # -rpath is the OSF1 rpath flag
807                         # -R is the old Solaris rpath flag
808                         {
809                         my $rpath = shift(@argvcopy) || "";
810                         $rpath .= " " if $rpath ne "";
811                         push @{$useradd{LDFLAGS}}, $_, $rpath;
812                         }
813                 elsif (/^-static$/)
814                         {
815                         push @{$useradd{LDFLAGS}}, $_;
816                         $disabled{"dso"} = "forced";
817                         $disabled{"pic"} = "forced";
818                         $disabled{"shared"} = "forced";
819                         $disabled{"threads"} = "forced";
820                         }
821                 elsif (/^-D(.*)$/)
822                         {
823                         push @{$useradd{CPPDEFINES}}, $1;
824                         }
825                 elsif (/^-I(.*)$/)
826                         {
827                         push @{$useradd{CPPINCLUDES}}, $1;
828                         }
829                 elsif (/^-Wp,$/)
830                         {
831                         push @{$useradd{CPPFLAGS}}, $1;
832                         }
833                 else    # common if (/^[-+]/), just pass down...
834                         {
835                         $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
836                         push @{$useradd{CFLAGS}}, $_;
837                         push @{$useradd{CXXFLAGS}}, $_;
838                         }
839                 }
840         else
841                 {
842                 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
843                 $target=$_;
844                 }
845         unless ($_ eq $target || /^no-/ || /^disable-/)
846                 {
847                 # "no-..." follows later after implied deactivations
848                 # have been derived.  (Don't take this too seriously,
849                 # we really only write OPTIONS to the Makefile out of
850                 # nostalgia.)
851
852                 if ($config{options} eq "")
853                         { $config{options} = $_; }
854                 else
855                         { $config{options} .= " ".$_; }
856                 }
857
858         if (defined($config{api}) && !exists $apitable->{$config{api}}) {
859                 die "***** Unsupported api compatibility level: $config{api}\n",
860         }
861
862         if (keys %deprecated_options)
863                 {
864                 warn "***** Deprecated options: ",
865                         join(", ", keys %deprecated_options), "\n";
866                 }
867         if (keys %unsupported_options)
868                 {
869                 die "***** Unsupported options: ",
870                         join(", ", keys %unsupported_options), "\n";
871                 }
872         }
873
874 foreach (keys %user) {
875     my $value = env($_);
876     $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef;
877
878     if (defined $value) {
879         if (ref $user{$_} eq 'ARRAY') {
880             $user{$_} = [ split /$list_separator_re/, $value ];
881         } elsif (!defined $user{$_}) {
882             $user{$_} = $value;
883         }
884     }
885 }
886
887 if (grep { $_ =~ /(^|\s)-Wl,-rpath,/ } ($user{LDLIBS} ? @{$user{LDLIBS}} : ())
888     && !$disabled{shared}
889     && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
890     die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
891         "***** any of asan, msan or ubsan\n";
892 }
893
894 my @tocheckfor = (keys %disabled);
895 while (@tocheckfor) {
896     my %new_tocheckfor = ();
897     my @cascade_copy = (@disable_cascades);
898     while (@cascade_copy) {
899         my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
900         if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
901             foreach(grep { !defined($disabled{$_}) } @$descendents) {
902                 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
903             }
904         }
905     }
906     @tocheckfor = (keys %new_tocheckfor);
907 }
908
909 our $die = sub { die @_; };
910 if ($target eq "TABLE") {
911     local $die = sub { warn @_; };
912     foreach (sort keys %table) {
913         print_table_entry($_, "TABLE");
914     }
915     exit 0;
916 }
917
918 if ($target eq "LIST") {
919     foreach (sort keys %table) {
920         print $_,"\n" unless $table{$_}->{template};
921     }
922     exit 0;
923 }
924
925 if ($target eq "HASH") {
926     local $die = sub { warn @_; };
927     print "%table = (\n";
928     foreach (sort keys %table) {
929         print_table_entry($_, "HASH");
930     }
931     exit 0;
932 }
933
934 print "Configuring OpenSSL version $config{version} ($config{version_num}) ";
935 print "for $target\n";
936
937 if (scalar(@seed_sources) == 0) {
938     print "Using os-specific seed configuration\n";
939     push @seed_sources, 'os';
940 }
941 die "Cannot seed with none and anything else"
942     if scalar(grep { $_ eq 'none' } @seed_sources) > 0
943         && scalar(@seed_sources) > 1;
944 push @{$config{openssl_other_defines}},
945      map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
946         @seed_sources;
947
948 # Backward compatibility?
949 if ($target =~ m/^CygWin32(-.*)$/) {
950     $target = "Cygwin".$1;
951 }
952
953 # Support for legacy targets having a name starting with 'debug-'
954 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
955 if ($d) {
956     $config{build_type} = "debug";
957
958     # If we do not find debug-foo in the table, the target is set to foo.
959     if (!$table{$target}) {
960         $target = $t;
961     }
962 }
963 $config{target} = $target;
964 my %target = resolve_config($target);
965
966 &usage if (!%target || $target{template});
967
968 %target = ( %{$table{DEFAULTS}}, %target );
969
970 # Make the flags to build DSOs the same as for shared libraries unless they
971 # are already defined
972 $target{dso_cflags} = $target{shared_cflag} unless defined $target{dso_cflags};
973 $target{dso_cxxflags} = $target{shared_cxxflag} unless defined $target{dso_cxxflags};
974 $target{dso_lflags} = $target{shared_ldflag} unless defined $target{dso_lflags};
975 {
976     my $shared_info_pl =
977         catfile(dirname($0), "Configurations", "shared-info.pl");
978     my %shared_info = read_eval_file($shared_info_pl);
979     push @{$target{_conf_fname_int}}, $shared_info_pl;
980     my $si = $target{shared_target};
981     while (ref $si ne "HASH") {
982         last if ! defined $si;
983         if (ref $si eq "CODE") {
984             $si = $si->();
985         } else {
986             $si = $shared_info{$si};
987         }
988     }
989
990     # Some of the 'shared_target' values don't have any entried in
991     # %shared_info.  That's perfectly fine, AS LONG AS the build file
992     # template knows how to handle this.  That is currently the case for
993     # Windows and VMS.
994     if (defined $si) {
995         # Just as above, copy certain shared_* attributes to the corresponding
996         # dso_ attribute unless the latter is already defined
997         $si->{dso_cflags} = $si->{shared_cflag} unless defined $si->{dso_cflags};
998         $si->{dso_cxxflags} = $si->{shared_cxxflag} unless defined $si->{dso_cxxflags};
999         $si->{dso_lflags} = $si->{shared_ldflag} unless defined $si->{dso_lflags};
1000         foreach (sort keys %$si) {
1001             $target{$_} = defined $target{$_}
1002                 ? add($si->{$_})->($target{$_})
1003                 : $si->{$_};
1004         }
1005     }
1006 }
1007
1008 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
1009 $config{conf_files} = [ sort keys %conf_files ];
1010
1011 foreach my $feature (@{$target{disable}}) {
1012     if (exists $deprecated_disablables{$feature}) {
1013         warn "***** config $target disables deprecated feature $feature\n";
1014     } elsif (!grep { $feature eq $_ } @disablables) {
1015         die "***** config $target disables unknown feature $feature\n";
1016     }
1017     $disabled{$feature} = 'config';
1018 }
1019 foreach my $feature (@{$target{enable}}) {
1020     if ("default" eq ($disabled{$_} // "")) {
1021         if (exists $deprecated_disablables{$feature}) {
1022             warn "***** config $target enables deprecated feature $feature\n";
1023         } elsif (!grep { $feature eq $_ } @disablables) {
1024             die "***** config $target enables unknown feature $feature\n";
1025         }
1026         delete $disabled{$_};
1027     }
1028 }
1029
1030 $target{cxxflags}//=$target{cflags} if $target{cxx};
1031 $target{exe_extension}="";
1032 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
1033                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
1034 $target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
1035
1036 ($target{shared_extension_simple}=$target{shared_extension})
1037     =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||;
1038 $target{dso_extension}=$target{shared_extension_simple};
1039 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
1040     if ($config{target} =~ /^(?:Cygwin|mingw)/);
1041
1042
1043 $config{cross_compile_prefix} = env('CROSS_COMPILE')
1044     if $config{cross_compile_prefix} eq "";
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 "my \%makevars = (\n";
2308 foreach (sort keys %user) {
2309     print OUT '    ',$_,' ' x (20 - length $_),'=> ',
2310         "'",$user_to_target{$_} || lc $_,"',\n";
2311 }
2312 print OUT ");\n";
2313 print OUT "my \%disabled_info = (\n";
2314 foreach my $what (sort keys %disabled_info) {
2315     print OUT "    '$what' => {\n";
2316     foreach my $info (sort keys %{$disabled_info{$what}}) {
2317         if (ref $disabled_info{$what}->{$info} eq 'ARRAY') {
2318             print OUT "        $info => [ ",
2319                 join(', ', map { "'$_'" } @{$disabled_info{$what}->{$info}}),
2320                 " ],\n";
2321         } else {
2322             print OUT "        $info => '", $disabled_info{$what}->{$info},
2323                 "',\n";
2324         }
2325     }
2326     print OUT "    },\n";
2327 }
2328 print OUT ");\n";
2329 print OUT << 'EOF';
2330 # If run directly, we can give some answers, and even reconfigure
2331 unless (caller) {
2332     use Getopt::Long;
2333     use File::Spec::Functions;
2334     use File::Basename;
2335     use Pod::Usage;
2336
2337     my $here = dirname($0);
2338
2339     my $dump = undef;
2340     my $cmdline = undef;
2341     my $options = undef;
2342     my $target = undef;
2343     my $envvars = undef;
2344     my $makevars = undef;
2345     my $buildparams = undef;
2346     my $reconf = undef;
2347     my $verbose = undef;
2348     my $help = undef;
2349     my $man = undef;
2350     GetOptions('dump|d'                 => \$dump,
2351                'command-line|c'         => \$cmdline,
2352                'options|o'              => \$options,
2353                'target|t'               => \$target,
2354                'environment|e'          => \$envvars,
2355                'make-variables|m'       => \$makevars,
2356                'build-parameters|b'     => \$buildparams,
2357                'reconfigure|reconf|r'   => \$reconf,
2358                'verbose|v'              => \$verbose,
2359                'help'                   => \$help,
2360                'man'                    => \$man)
2361         or die "Errors in command line arguments\n";
2362
2363     unless ($dump || $cmdline || $options || $target || $envvars || $makevars
2364             || $buildparams || $reconf || $verbose || $help || $man) {
2365         print STDERR <<"_____";
2366 You must give at least one option.
2367 For more information, do '$0 --help'
2368 _____
2369         exit(2);
2370     }
2371
2372     if ($help) {
2373         pod2usage(-exitval => 0,
2374                   -verbose => 1);
2375     }
2376     if ($man) {
2377         pod2usage(-exitval => 0,
2378                   -verbose => 2);
2379     }
2380     if ($dump || $cmdline) {
2381         print "\nCommand line (with current working directory = $here):\n\n";
2382         print '    ',join(' ',
2383                           $config{perl},
2384                           catfile($config{sourcedir}, 'Configure'),
2385                           @{$config{perlargv}}), "\n";
2386         print "\nPerl information:\n\n";
2387         print '    ',$config{perl_cmd},"\n";
2388         print '    ',$config{perl_version},' for ',$config{perl_archname},"\n";
2389     }
2390     if ($dump || $options) {
2391         my $longest = 0;
2392         my $longest2 = 0;
2393         foreach my $what (@disablables) {
2394             $longest = length($what) if $longest < length($what);
2395             $longest2 = length($disabled{$what})
2396                 if $disabled{$what} && $longest2 < length($disabled{$what});
2397         }
2398         print "\nEnabled features:\n\n";
2399         foreach my $what (@disablables) {
2400             print "    $what\n" unless $disabled{$what};
2401         }
2402         print "\nDisabled features:\n\n";
2403         foreach my $what (@disablables) {
2404             if ($disabled{$what}) {
2405                 print "    $what", ' ' x ($longest - length($what) + 1),
2406                     "[$disabled{$what}]", ' ' x ($longest2 - length($disabled{$what}) + 1);
2407                 print $disabled_info{$what}->{macro}
2408                     if $disabled_info{$what}->{macro};
2409                 print ' (skip ',
2410                     join(', ', @{$disabled_info{$what}->{skipped}}),
2411                     ')'
2412                     if $disabled_info{$what}->{skipped};
2413                 print "\n";
2414             }
2415         }
2416     }
2417     if ($dump || $target) {
2418         print "\nConfig target attributes:\n\n";
2419         foreach (sort keys %target) {
2420             next if $_ =~ m|^_| || $_ eq 'template';
2421             my $quotify = sub {
2422                 map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_;
2423             };
2424             print '    ', $_, ' => ';
2425             if (ref($target{$_}) eq "ARRAY") {
2426                 print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n";
2427             } else {
2428                 print $quotify->($target{$_}), ",\n"
2429             }
2430         }
2431     }
2432     if ($dump || $envvars) {
2433         print "\nRecorded environment:\n\n";
2434         foreach (sort keys %{$config{perlenv}}) {
2435             print '    ',$_,' = ',($config{perlenv}->{$_} || ''),"\n";
2436         }
2437     }
2438     if ($dump || $makevars) {
2439         print "\nMakevars:\n\n";
2440         foreach (sort keys %makevars) {
2441             print '    ',$_,' ' x (16 - length $_),'= ',
2442                 (ref $config{$makevars{$_}} eq 'ARRAY'
2443                  ? join(' ', @{$config{$makevars{$_}}})
2444                  : $config{$makevars{$_}}),
2445                 "\n"
2446                 if defined $config{$makevars{$_}};
2447         }
2448
2449         my @buildfile = ($config{builddir}, $config{build_file});
2450         unshift @buildfile, $here
2451             unless file_name_is_absolute($config{builddir});
2452         my $buildfile = canonpath(catdir(@buildfile));
2453         print <<"_____";
2454
2455 NOTE: These variables only represent the configuration view.  The build file
2456 template may have processed these variables further, please have a look at the
2457 build file for more exact data:
2458     $buildfile
2459 _____
2460     }
2461     if ($dump || $buildparams) {
2462         my @buildfile = ($config{builddir}, $config{build_file});
2463         unshift @buildfile, $here
2464             unless file_name_is_absolute($config{builddir});
2465         print "\nbuild file:\n\n";
2466         print "    ", canonpath(catfile(@buildfile)),"\n";
2467
2468         print "\nbuild file templates:\n\n";
2469         foreach (@{$config{build_file_templates}}) {
2470             my @tmpl = ($_);
2471             unshift @tmpl, $here
2472                 unless file_name_is_absolute($config{sourcedir});
2473             print '    ',canonpath(catfile(@tmpl)),"\n";
2474         }
2475     }
2476     if ($reconf) {
2477         if ($verbose) {
2478             print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n";
2479             foreach (sort keys %{$config{perlenv}}) {
2480                 print '    ',$_,' = ',($config{perlenv}->{$_} || ""),"\n";
2481             }
2482         }
2483
2484         chdir $here;
2485         exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf';
2486     }
2487 }
2488
2489 1;
2490
2491 __END__
2492
2493 =head1 NAME
2494
2495 configdata.pm - configuration data for OpenSSL builds
2496
2497 =head1 SYNOPSIS
2498
2499 Interactive:
2500
2501   perl configdata.pm [options]
2502
2503 As data bank module:
2504
2505   use configdata;
2506
2507 =head1 DESCRIPTION
2508
2509 This module can be used in two modes, interactively and as a module containing
2510 all the data recorded by OpenSSL's Configure script.
2511
2512 When used interactively, simply run it as any perl script, with at least one
2513 option, and you will get the information you ask for.  See L</OPTIONS> below.
2514
2515 When loaded as a module, you get a few databanks with useful information to
2516 perform build related tasks.  The databanks are:
2517
2518     %config             Configured things.
2519     %target             The OpenSSL config target with all inheritances
2520                         resolved.
2521     %disabled           The features that are disabled.
2522     @disablables        The list of features that can be disabled.
2523     %withargs           All data given through --with-THING options.
2524     %unified_info       All information that was computed from the build.info
2525                         files.
2526
2527 =head1 OPTIONS
2528
2529 =over 4
2530
2531 =item B<--help>
2532
2533 Print a brief help message and exit.
2534
2535 =item B<--man>
2536
2537 Print the manual page and exit.
2538
2539 =item B<--dump> | B<-d>
2540
2541 Print all relevant configuration data.  This is equivalent to B<--command-line>
2542 B<--options> B<--target> B<--environment> B<--make-variables>
2543 B<--build-parameters>.
2544
2545 =item B<--command-line> | B<-c>
2546
2547 Print the current configuration command line.
2548
2549 =item B<--options> | B<-o>
2550
2551 Print the features, both enabled and disabled, and display defined macro and
2552 skipped directories where applicable.
2553
2554 =item B<--target> | B<-t>
2555
2556 Print the config attributes for this config target.
2557
2558 =item B<--environment> | B<-e>
2559
2560 Print the environment variables and their values at the time of configuration.
2561
2562 =item B<--make-variables> | B<-m>
2563
2564 Print the main make variables generated in the current configuration
2565
2566 =item B<--build-parameters> | B<-b>
2567
2568 Print the build parameters, i.e. build file and build file templates.
2569
2570 =item B<--reconfigure> | B<--reconf> | B<-r>
2571
2572 Redo the configuration.
2573
2574 =item B<--verbose> | B<-v>
2575
2576 Verbose output.
2577
2578 =back
2579
2580 =cut
2581
2582 EOF
2583 close(OUT);
2584 if ($builder_platform eq 'unix') {
2585     my $mode = (0755 & ~umask);
2586     chmod $mode, 'configdata.pm'
2587         or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!);
2588 }
2589
2590 my %builders = (
2591     unified => sub {
2592         print 'Creating ',$target{build_file},"\n";
2593         run_dofile(catfile($blddir, $target{build_file}),
2594                    @{$config{build_file_templates}});
2595     },
2596     );
2597
2598 $builders{$builder}->($builder_platform, @builder_opts);
2599
2600 # Show a note on the use of configdata.pm, but ONLY for release 1.1.1
2601 # (i.e. this message disappears with the following update, 1.1.1a)
2602 print <<"EOF" if ($config{version_num} =~ m|^0x1010100.L$|);
2603
2604 NOTE: Starting with OpenSSL 1.1.1, 'Configure' doesn't display all the disabled
2605 options or the "make variables" with their values.  Instead, you must use
2606 'configdata.pm' as a script to get a display of the configuration data.  For
2607 help, please do this:
2608
2609         perl configdata.pm --help
2610 EOF
2611 print <<"EOF" if ($disabled{threads} eq "unavailable");
2612
2613 The library could not be configured for supporting multi-threaded
2614 applications as the compiler options required on this system are not known.
2615 See file INSTALL for details if you need multi-threading.
2616 EOF
2617
2618 print <<"EOF" if ($no_shared_warn);
2619
2620 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2621 platform, so we will pretend you gave the option 'no-pic', which also disables
2622 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
2623 or position independent code, please let us know (but please first make sure
2624 you have tried with a current version of OpenSSL).
2625 EOF
2626
2627 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2628
2629 WARNING: there are indications that another build was made in the source
2630 directory.  This build may have picked up artifacts from that build, the
2631 safest course of action is to clean the source directory and redo this
2632 configuration.
2633 EOF
2634
2635 exit(0);
2636
2637 ######################################################################
2638 #
2639 # Helpers and utility functions
2640 #
2641
2642 # Configuration file reading #########################################
2643
2644 # Note: All of the helper functions are for lazy evaluation.  They all
2645 # return a CODE ref, which will return the intended value when evaluated.
2646 # Thus, whenever there's mention of a returned value, it's about that
2647 # intended value.
2648
2649 # Helper function to implement conditional inheritance depending on the
2650 # value of $disabled{asm}.  Used in inherit_from values as follows:
2651 #
2652 #      inherit_from => [ "template", asm("asm_tmpl") ]
2653 #
2654 sub asm {
2655     my @x = @_;
2656     sub {
2657         $disabled{asm} ? () : @x;
2658     }
2659 }
2660
2661 # Helper function to implement conditional value variants, with a default
2662 # plus additional values based on the value of $config{build_type}.
2663 # Arguments are given in hash table form:
2664 #
2665 #       picker(default => "Basic string: ",
2666 #              debug   => "debug",
2667 #              release => "release")
2668 #
2669 # When configuring with --debug, the resulting string will be
2670 # "Basic string: debug", and when not, it will be "Basic string: release"
2671 #
2672 # This can be used to create variants of sets of flags according to the
2673 # build type:
2674 #
2675 #       cflags => picker(default => "-Wall",
2676 #                        debug   => "-g -O0",
2677 #                        release => "-O3")
2678 #
2679 sub picker {
2680     my %opts = @_;
2681     return sub { add($opts{default} || (),
2682                      $opts{$config{build_type}} || ())->(); }
2683 }
2684
2685 # Helper function to combine several values of different types into one.
2686 # This is useful if you want to combine a string with the result of a
2687 # lazy function, such as:
2688 #
2689 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2690 #
2691 sub combine {
2692     my @stuff = @_;
2693     return sub { add(@stuff)->(); }
2694 }
2695
2696 # Helper function to implement conditional values depending on the value
2697 # of $disabled{threads}.  Can be used as follows:
2698 #
2699 #       cflags => combine("-Wall", threads("-pthread"))
2700 #
2701 sub threads {
2702     my @flags = @_;
2703     return sub { add($disabled{threads} ? () : @flags)->(); }
2704 }
2705
2706
2707
2708 our $add_called = 0;
2709 # Helper function to implement adding values to already existing configuration
2710 # values.  It handles elements that are ARRAYs, CODEs and scalars
2711 sub _add {
2712     my $separator = shift;
2713
2714     # If there's any ARRAY in the collection of values OR the separator
2715     # is undef, we will return an ARRAY of combined values, otherwise a
2716     # string of joined values with $separator as the separator.
2717     my $found_array = !defined($separator);
2718
2719     my @values =
2720         map {
2721             my $res = $_;
2722             while (ref($res) eq "CODE") {
2723                 $res = $res->();
2724             }
2725             if (defined($res)) {
2726                 if (ref($res) eq "ARRAY") {
2727                     $found_array = 1;
2728                     @$res;
2729                 } else {
2730                     $res;
2731                 }
2732             } else {
2733                 ();
2734             }
2735     } (@_);
2736
2737     $add_called = 1;
2738
2739     if ($found_array) {
2740         [ @values ];
2741     } else {
2742         join($separator, grep { defined($_) && $_ ne "" } @values);
2743     }
2744 }
2745 sub add_before {
2746     my $separator = " ";
2747     if (ref($_[$#_]) eq "HASH") {
2748         my $opts = pop;
2749         $separator = $opts->{separator};
2750     }
2751     my @x = @_;
2752     sub { _add($separator, @x, @_) };
2753 }
2754 sub add {
2755     my $separator = " ";
2756     if (ref($_[$#_]) eq "HASH") {
2757         my $opts = pop;
2758         $separator = $opts->{separator};
2759     }
2760     my @x = @_;
2761     sub { _add($separator, @_, @x) };
2762 }
2763
2764 sub read_eval_file {
2765     my $fname = shift;
2766     my $content;
2767     my @result;
2768
2769     open F, "< $fname" or die "Can't open '$fname': $!\n";
2770     {
2771         undef local $/;
2772         $content = <F>;
2773     }
2774     close F;
2775     {
2776         local $@;
2777
2778         @result = ( eval $content );
2779         warn $@ if $@;
2780     }
2781     return wantarray ? @result : $result[0];
2782 }
2783
2784 # configuration reader, evaluates the input file as a perl script and expects
2785 # it to fill %targets with target configurations.  Those are then added to
2786 # %table.
2787 sub read_config {
2788     my $fname = shift;
2789     my %targets;
2790
2791     {
2792         # Protect certain tables from tampering
2793         local %table = ();
2794
2795         %targets = read_eval_file($fname);
2796     }
2797     my %preexisting = ();
2798     foreach (sort keys %targets) {
2799         $preexisting{$_} = 1 if $table{$_};
2800     }
2801     die <<"EOF",
2802 The following config targets from $fname
2803 shadow pre-existing config targets with the same name:
2804 EOF
2805         map { "  $_\n" } sort keys %preexisting
2806         if %preexisting;
2807
2808
2809     # For each target, check that it's configured with a hash table.
2810     foreach (keys %targets) {
2811         if (ref($targets{$_}) ne "HASH") {
2812             if (ref($targets{$_}) eq "") {
2813                 warn "Deprecated target configuration for $_, ignoring...\n";
2814             } else {
2815                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2816             }
2817             delete $targets{$_};
2818         } else {
2819             $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2820         }
2821     }
2822
2823     %table = (%table, %targets);
2824
2825 }
2826
2827 # configuration resolver.  Will only resolve all the lazy evaluation
2828 # codeblocks for the chosen target and all those it inherits from,
2829 # recursively
2830 sub resolve_config {
2831     my $target = shift;
2832     my @breadcrumbs = @_;
2833
2834 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2835
2836     if (grep { $_ eq $target } @breadcrumbs) {
2837         die "inherit_from loop!  target backtrace:\n  "
2838             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2839     }
2840
2841     if (!defined($table{$target})) {
2842         warn "Warning! target $target doesn't exist!\n";
2843         return ();
2844     }
2845     # Recurse through all inheritances.  They will be resolved on the
2846     # fly, so when this operation is done, they will all just be a
2847     # bunch of attributes with string values.
2848     # What we get here, though, are keys with references to lists of
2849     # the combined values of them all.  We will deal with lists after
2850     # this stage is done.
2851     my %combined_inheritance = ();
2852     if ($table{$target}->{inherit_from}) {
2853         my @inherit_from =
2854             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2855         foreach (@inherit_from) {
2856             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2857
2858             # 'template' is a marker that's considered private to
2859             # the config that had it.
2860             delete $inherited_config{template};
2861
2862             foreach (keys %inherited_config) {
2863                 if (!$combined_inheritance{$_}) {
2864                     $combined_inheritance{$_} = [];
2865                 }
2866                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2867             }
2868         }
2869     }
2870
2871     # We won't need inherit_from in this target any more, since we've
2872     # resolved all the inheritances that lead to this
2873     delete $table{$target}->{inherit_from};
2874
2875     # Now is the time to deal with those lists.  Here's the place to
2876     # decide what shall be done with those lists, all based on the
2877     # values of the target we're currently dealing with.
2878     # - If a value is a coderef, it will be executed with the list of
2879     #   inherited values as arguments.
2880     # - If the corresponding key doesn't have a value at all or is the
2881     #   empty string, the inherited value list will be run through the
2882     #   default combiner (below), and the result becomes this target's
2883     #   value.
2884     # - Otherwise, this target's value is assumed to be a string that
2885     #   will simply override the inherited list of values.
2886     my $default_combiner = add();
2887
2888     my %all_keys =
2889         map { $_ => 1 } (keys %combined_inheritance,
2890                          keys %{$table{$target}});
2891
2892     sub process_values {
2893         my $object    = shift;
2894         my $inherited = shift;  # Always a [ list ]
2895         my $target    = shift;
2896         my $entry     = shift;
2897
2898         $add_called = 0;
2899
2900         while(ref($object) eq "CODE") {
2901             $object = $object->(@$inherited);
2902         }
2903         if (!defined($object)) {
2904             return ();
2905         }
2906         elsif (ref($object) eq "ARRAY") {
2907             local $add_called;  # To make sure recursive calls don't affect it
2908             return [ map { process_values($_, $inherited, $target, $entry) }
2909                      @$object ];
2910         } elsif (ref($object) eq "") {
2911             return $object;
2912         } else {
2913             die "cannot handle reference type ",ref($object)
2914                 ," found in target ",$target," -> ",$entry,"\n";
2915         }
2916     }
2917
2918     foreach (sort keys %all_keys) {
2919         my $previous = $combined_inheritance{$_};
2920
2921         # Current target doesn't have a value for the current key?
2922         # Assign it the default combiner, the rest of this loop body
2923         # will handle it just like any other coderef.
2924         if (!exists $table{$target}->{$_}) {
2925             $table{$target}->{$_} = $default_combiner;
2926         }
2927
2928         $table{$target}->{$_} = process_values($table{$target}->{$_},
2929                                                $combined_inheritance{$_},
2930                                                $target, $_);
2931         unless(defined($table{$target}->{$_})) {
2932             delete $table{$target}->{$_};
2933         }
2934 #        if ($extra_checks &&
2935 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2936 #            warn "$_ got replaced in $target\n";
2937 #        }
2938     }
2939
2940     # Finally done, return the result.
2941     return %{$table{$target}};
2942 }
2943
2944 sub usage
2945         {
2946         print STDERR $usage;
2947         print STDERR "\npick os/compiler from:\n";
2948         my $j=0;
2949         my $i;
2950         my $k=0;
2951         foreach $i (sort keys %table)
2952                 {
2953                 next if $table{$i}->{template};
2954                 next if $i =~ /^debug/;
2955                 $k += length($i) + 1;
2956                 if ($k > 78)
2957                         {
2958                         print STDERR "\n";
2959                         $k=length($i);
2960                         }
2961                 print STDERR $i . " ";
2962                 }
2963         foreach $i (sort keys %table)
2964                 {
2965                 next if $table{$i}->{template};
2966                 next if $i !~ /^debug/;
2967                 $k += length($i) + 1;
2968                 if ($k > 78)
2969                         {
2970                         print STDERR "\n";
2971                         $k=length($i);
2972                         }
2973                 print STDERR $i . " ";
2974                 }
2975         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2976         exit(1);
2977         }
2978
2979 sub run_dofile
2980 {
2981     my $out = shift;
2982     my @templates = @_;
2983
2984     unlink $out || warn "Can't remove $out, $!"
2985         if -f $out;
2986     foreach (@templates) {
2987         die "Can't open $_, $!" unless -f $_;
2988     }
2989     my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2990     my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2991     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2992     system($cmd);
2993     exit 1 if $? != 0;
2994     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2995 }
2996
2997 sub compiler_predefined {
2998     state %predefined;
2999     my $default_compiler = shift;
3000
3001     return () if $^O eq 'VMS';
3002
3003     die 'compiler_predefines called without a default compiler'
3004         unless $default_compiler;
3005
3006     if (! $predefined{$default_compiler}) {
3007         my $cc = "$config{cross_compile_prefix}$default_compiler";
3008
3009         $predefined{$default_compiler} = {};
3010
3011         # collect compiler pre-defines from gcc or gcc-alike...
3012         open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
3013         while (my $l = <PIPE>) {
3014             $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
3015             $predefined{$default_compiler}->{$1} = $2 // '';
3016         }
3017         close(PIPE);
3018     }
3019
3020     return %{$predefined{$default_compiler}};
3021 }
3022
3023 sub which
3024 {
3025     my ($name)=@_;
3026
3027     if (eval { require IPC::Cmd; 1; }) {
3028         IPC::Cmd->import();
3029         return scalar IPC::Cmd::can_run($name);
3030     } else {
3031         # if there is $directories component in splitpath,
3032         # then it's not something to test with $PATH...
3033         return $name if (File::Spec->splitpath($name))[1];
3034
3035         foreach (File::Spec->path()) {
3036             my $fullpath = catfile($_, "$name$target{exe_extension}");
3037             if (-f $fullpath and -x $fullpath) {
3038                 return $fullpath;
3039             }
3040         }
3041     }
3042 }
3043
3044 sub env
3045 {
3046     my $name = shift;
3047
3048     # Note that if $ENV{$name} doesn't exist or is undefined,
3049     # $config{perlenv}->{$name} will be created with the value
3050     # undef.  This is intentional.
3051
3052     $config{perlenv}->{$name} = $ENV{$name}
3053         if ! exists $config{perlenv}->{$name};
3054     return $config{perlenv}->{$name};
3055 }
3056
3057 # Configuration printer ##############################################
3058
3059 sub print_table_entry
3060 {
3061     my $target = shift;
3062     my %target = resolve_config($target);
3063     my $type = shift;
3064
3065     # Don't print the templates
3066     return if $target{template};
3067
3068     my @sequence = (
3069         "sys_id",
3070         "cpp",
3071         "cppflags",
3072         "defines",
3073         "includes",
3074         "cc",
3075         "cflags",
3076         "unistd",
3077         "ld",
3078         "lflags",
3079         "loutflag",
3080         "plib_lflags",
3081         "ex_libs",
3082         "bn_ops",
3083         "apps_aux_src",
3084         "cpuid_asm_src",
3085         "uplink_aux_src",
3086         "bn_asm_src",
3087         "ec_asm_src",
3088         "des_asm_src",
3089         "aes_asm_src",
3090         "bf_asm_src",
3091         "md5_asm_src",
3092         "cast_asm_src",
3093         "sha1_asm_src",
3094         "rc4_asm_src",
3095         "rmd160_asm_src",
3096         "rc5_asm_src",
3097         "wp_asm_src",
3098         "cmll_asm_src",
3099         "modes_asm_src",
3100         "padlock_asm_src",
3101         "chacha_asm_src",
3102         "poly1035_asm_src",
3103         "thread_scheme",
3104         "perlasm_scheme",
3105         "dso_scheme",
3106         "shared_target",
3107         "shared_cflag",
3108         "shared_defines",
3109         "shared_ldflag",
3110         "shared_rcflag",
3111         "shared_extension",
3112         "dso_extension",
3113         "obj_extension",
3114         "exe_extension",
3115         "ranlib",
3116         "ar",
3117         "arflags",
3118         "aroutflag",
3119         "rc",
3120         "rcflags",
3121         "rcoutflag",
3122         "mt",
3123         "mtflags",
3124         "mtinflag",
3125         "mtoutflag",
3126         "multilib",
3127         "build_scheme",
3128         );
3129
3130     if ($type eq "TABLE") {
3131         print "\n";
3132         print "*** $target\n";
3133         foreach (@sequence) {
3134             if (ref($target{$_}) eq "ARRAY") {
3135                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
3136             } else {
3137                 printf "\$%-12s = %s\n", $_, $target{$_};
3138             }
3139         }
3140     } elsif ($type eq "HASH") {
3141         my $largest =
3142             length((sort { length($a) <=> length($b) } @sequence)[-1]);
3143         print "    '$target' => {\n";
3144         foreach (@sequence) {
3145             if ($target{$_}) {
3146                 if (ref($target{$_}) eq "ARRAY") {
3147                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
3148                 } else {
3149                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
3150                 }
3151             }
3152         }
3153         print "    },\n";
3154     }
3155 }
3156
3157 # Utility routines ###################################################
3158
3159 # On VMS, if the given file is a logical name, File::Spec::Functions
3160 # will consider it an absolute path.  There are cases when we want a
3161 # purely syntactic check without checking the environment.
3162 sub isabsolute {
3163     my $file = shift;
3164
3165     # On non-platforms, we just use file_name_is_absolute().
3166     return file_name_is_absolute($file) unless $^O eq "VMS";
3167
3168     # If the file spec includes a device or a directory spec,
3169     # file_name_is_absolute() is perfectly safe.
3170     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
3171
3172     # Here, we know the given file spec isn't absolute
3173     return 0;
3174 }
3175
3176 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
3177 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
3178 # realpath() requires that at least all path components except the last is an
3179 # existing directory.  On VMS, the last component of the directory spec must
3180 # exist.
3181 sub absolutedir {
3182     my $dir = shift;
3183
3184     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
3185     # will return the volume name for the device, no matter what.  Also,
3186     # it will return an incorrect directory spec if the argument is a
3187     # directory that doesn't exist.
3188     if ($^O eq "VMS") {
3189         return rel2abs($dir);
3190     }
3191
3192     # We use realpath() on Unix, since no other will properly clean out
3193     # a directory spec.
3194     use Cwd qw/realpath/;
3195
3196     return realpath($dir);
3197 }
3198
3199 sub quotify {
3200     my %processors = (
3201         perl    => sub { my $x = shift;
3202                          $x =~ s/([\\\$\@"])/\\$1/g;
3203                          return '"'.$x.'"'; },
3204         maybeshell => sub { my $x = shift;
3205                             (my $y = $x) =~ s/([\\\"])/\\$1/g;
3206                             if ($x ne $y || $x =~ m|\s|) {
3207                                 return '"'.$y.'"';
3208                             } else {
3209                                 return $x;
3210                             }
3211                         },
3212         );
3213     my $for = shift;
3214     my $processor =
3215         defined($processors{$for}) ? $processors{$for} : sub { shift; };
3216
3217     return map { $processor->($_); } @_;
3218 }
3219
3220 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
3221 # $filename is a file name to read from
3222 # $line_concat_cond_re is a regexp detecting a line continuation ending
3223 # $line_concat is a CODEref that takes care of concatenating two lines
3224 sub collect_from_file {
3225     my $filename = shift;
3226     my $line_concat_cond_re = shift;
3227     my $line_concat = shift;
3228
3229     open my $fh, $filename || die "unable to read $filename: $!\n";
3230     return sub {
3231         my $saved_line = "";
3232         $_ = "";
3233         while (<$fh>) {
3234             s|\R$||;
3235             if (defined $line_concat) {
3236                 $_ = $line_concat->($saved_line, $_);
3237                 $saved_line = "";
3238             }
3239             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3240                 $saved_line = $_;
3241                 next;
3242             }
3243             return $_;
3244         }
3245         die "$filename ending with continuation line\n" if $_;
3246         close $fh;
3247         return undef;
3248     }
3249 }
3250
3251 # collect_from_array($array, $line_concat_cond_re, $line_concat)
3252 # $array is an ARRAYref of lines
3253 # $line_concat_cond_re is a regexp detecting a line continuation ending
3254 # $line_concat is a CODEref that takes care of concatenating two lines
3255 sub collect_from_array {
3256     my $array = shift;
3257     my $line_concat_cond_re = shift;
3258     my $line_concat = shift;
3259     my @array = (@$array);
3260
3261     return sub {
3262         my $saved_line = "";
3263         $_ = "";
3264         while (defined($_ = shift @array)) {
3265             s|\R$||;
3266             if (defined $line_concat) {
3267                 $_ = $line_concat->($saved_line, $_);
3268                 $saved_line = "";
3269             }
3270             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3271                 $saved_line = $_;
3272                 next;
3273             }
3274             return $_;
3275         }
3276         die "input text ending with continuation line\n" if $_;
3277         return undef;
3278     }
3279 }
3280
3281 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
3282 # $lineiterator is a CODEref that delivers one line at a time.
3283 # All following arguments are regex/CODEref pairs, where the regexp detects a
3284 # line and the CODEref does something with the result of the regexp.
3285 sub collect_information {
3286     my $lineiterator = shift;
3287     my %collectors = @_;
3288
3289     while(defined($_ = $lineiterator->())) {
3290         s|\R$||;
3291         my $found = 0;
3292         if ($collectors{"BEFORE"}) {
3293             $collectors{"BEFORE"}->($_);
3294         }
3295         foreach my $re (keys %collectors) {
3296             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
3297                 $collectors{$re}->($lineiterator);
3298                 $found = 1;
3299             };
3300         }
3301         if ($collectors{"OTHERWISE"}) {
3302             $collectors{"OTHERWISE"}->($lineiterator, $_)
3303                 unless $found || !defined $collectors{"OTHERWISE"};
3304         }
3305         if ($collectors{"AFTER"}) {
3306             $collectors{"AFTER"}->($_);
3307         }
3308     }
3309 }
3310
3311 # tokenize($line)
3312 # $line is a line of text to split up into tokens
3313 # returns a list of tokens
3314 #
3315 # Tokens are divided by spaces.  If the tokens include spaces, they
3316 # have to be quoted with single or double quotes.  Double quotes
3317 # inside a double quoted token must be escaped.  Escaping is done
3318 # with backslash.
3319 # Basically, the same quoting rules apply for " and ' as in any
3320 # Unix shell.
3321 sub tokenize {
3322     my $line = my $debug_line = shift;
3323     my @result = ();
3324
3325     while ($line =~ s|^\s+||, $line ne "") {
3326         my $token = "";
3327         while ($line ne "" && $line !~ m|^\s|) {
3328             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
3329                 $token .= $1;
3330                 $line = $';
3331             } elsif ($line =~ m/^'([^']*)'/) {
3332                 $token .= $1;
3333                 $line = $';
3334             } elsif ($line =~ m/^(\S+)/) {
3335                 $token .= $1;
3336                 $line = $';
3337             }
3338         }
3339         push @result, $token;
3340     }
3341
3342     if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3343         print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
3344         print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
3345     }
3346     return @result;
3347 }