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