rsa: Do not allow less than 512 bit RSA keys
[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 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
883 $config{conf_files} = [ sort keys %conf_files ];
884 %target = ( %{$table{DEFAULTS}}, %target );
885
886 foreach my $feature (@{$target{disable}}) {
887     if (exists $deprecated_disablables{$feature}) {
888         warn "***** config $target disables deprecated feature $feature\n";
889     } elsif (!grep { $feature eq $_ } @disablables) {
890         die "***** config $target disables unknown feature $feature\n";
891     }
892     $disabled{$feature} = 'config';
893 }
894 foreach my $feature (@{$target{enable}}) {
895     if ("default" eq ($disabled{$_} // "")) {
896         if (exists $deprecated_disablables{$feature}) {
897             warn "***** config $target enables deprecated feature $feature\n";
898         } elsif (!grep { $feature eq $_ } @disablables) {
899             die "***** config $target enables unknown feature $feature\n";
900         }
901         delete $disabled{$_};
902     }
903 }
904
905 foreach (sort (keys %disabled))
906         {
907         $config{options} .= " no-$_";
908
909         printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
910
911         if (/^dso$/)
912                 { }
913         elsif (/^threads$/)
914                 { }
915         elsif (/^shared$/)
916                 { }
917         elsif (/^pic$/)
918                 { }
919         elsif (/^zlib$/)
920                 { }
921         elsif (/^dynamic-engine$/)
922                 { }
923         elsif (/^makedepend$/)
924                 { }
925         elsif (/^zlib-dynamic$/)
926                 { }
927         elsif (/^sse2$/)
928                 { $no_sse2 = 1; }
929         elsif (/^engine$/)
930                 {
931                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
932                 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
933                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
934                 print " OPENSSL_NO_ENGINE (skip engines)";
935                 }
936         else
937                 {
938                 my ($WHAT, $what);
939
940                 ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/;
941
942                 # Fix up C macro end names
943                 $WHAT = "RMD160" if $what eq "ripemd";
944
945                 # fix-up crypto/directory name(s)
946                 $what = "ripemd" if $what eq "rmd160";
947                 $what = "whrlpool" if $what eq "whirlpool";
948
949                 if ($what ne "async" && $what ne "err"
950                     && grep { $_ eq $what } @{$config{sdirs}})
951                         {
952                         push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT";
953                         @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}};
954
955                         print " OPENSSL_NO_$WHAT (skip dir)";
956                         }
957                 else
958                         {
959                         push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
960                         print " OPENSSL_NO_$WHAT";
961
962                         if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
963                         }
964                 }
965
966         print "\n";
967         }
968
969 $target{cxxflags}=$target{cflags} unless defined $target{cxxflags};
970 $target{exe_extension}="";
971 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
972                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
973 $target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
974
975 ($target{shared_extension_simple}=$target{shared_extension})
976     =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||;
977 $target{dso_extension}=$target{shared_extension_simple};
978 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
979     if ($config{target} =~ /^(?:Cygwin|mingw)/);
980
981
982 $config{cross_compile_prefix} = env('CROSS_COMPILE')
983     if $config{cross_compile_prefix} eq "";
984
985 # Allow overriding the names of some tools.  USE WITH CARE
986 # Note: only Unix cares about HASHBANGPERL...  that explains
987 # the default string.
988 $config{perl} =    ($^O ne "VMS" ? $^X : "perl");
989 $config{hashbangperl} =
990     env('HASHBANGPERL')           || env('PERL')      || "/usr/bin/env perl";
991 $target{cc} =      env('CC')      || $target{cc}      || "cc";
992 $target{cxx} =     env('CXX')     || $target{cxx}     || "c++";
993 $target{ranlib} =  env('RANLIB')  || $target{ranlib}  ||
994                    (which("$config{cross_compile_prefix}ranlib") ?
995                           "\$(CROSS_COMPILE)ranlib" : "true");
996 $target{ar} =      env('AR')      || $target{ar}      || "ar";
997 $target{nm} =      env('NM')      || $target{nm}      || "nm";
998 $target{rc} =
999     env('RC')  || env('WINDRES')  || $target{rc}      || "windres";
1000
1001 # Allow overriding the build file name
1002 $target{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
1003
1004 # Cache information necessary for reconfiguration
1005 $config{cc} = $target{cc};
1006 $config{cxx} = $target{cxx};
1007 $config{build_file} = $target{build_file};
1008
1009 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
1010 # or release_ attributes.
1011 # Do it in such a way that no spurious space is appended (hence the grep).
1012 $config{defines} = [];
1013 $config{cflags} = "";
1014 $config{cxxflags} = "";
1015 $config{ex_libs} = "";
1016 $config{shared_ldflag} = "";
1017
1018 # Make sure build_scheme is consistent.
1019 $target{build_scheme} = [ $target{build_scheme} ]
1020     if ref($target{build_scheme}) ne "ARRAY";
1021
1022 my ($builder, $builder_platform, @builder_opts) =
1023     @{$target{build_scheme}};
1024
1025 foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm",
1026                       $builder_platform."-checker.pm")) {
1027     my $checker_path = catfile($srcdir, "Configurations", $checker);
1028     if (-f $checker_path) {
1029         my $fn = $ENV{CONFIGURE_CHECKER_WARN}
1030             ? sub { warn $@; } : sub { die $@; };
1031         if (! do $checker_path) {
1032             if ($@) {
1033                 $fn->($@);
1034             } elsif ($!) {
1035                 $fn->($!);
1036             } else {
1037                 $fn->("The detected tools didn't match the platform\n");
1038             }
1039         }
1040         last;
1041     }
1042 }
1043
1044 push @{$config{defines}}, "NDEBUG"    if $config{build_type} eq "release";
1045
1046 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
1047         {
1048         $config{cflags} .= " -mno-cygwin";
1049         $config{shared_ldflag} .= " -mno-cygwin";
1050         }
1051
1052 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
1053         # minimally required architecture flags for assembly modules
1054         $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
1055         $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
1056 }
1057
1058 my $no_shared_warn=0;
1059 my $no_user_cflags=0;
1060 my $no_user_defines=0;
1061
1062 # The DSO code currently always implements all functions so that no
1063 # applications will have to worry about that from a compilation point
1064 # of view. However, the "method"s may return zero unless that platform
1065 # has support compiled in for them. Currently each method is enabled
1066 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
1067 # string entry into using the following logic;
1068 if (!$disabled{dso} && $target{dso_scheme} ne "")
1069         {
1070         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
1071         if ($target{dso_scheme} eq "DLFCN")
1072                 {
1073                 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
1074                 }
1075         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
1076                 {
1077                 unshift @{$config{defines}}, "DSO_DLFCN";
1078                 }
1079         else
1080                 {
1081                 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
1082                 }
1083         }
1084
1085 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
1086
1087 # If threads aren't disabled, check how possible they are
1088 unless ($disabled{threads}) {
1089     if ($auto_threads) {
1090         # Enabled by default, disable it forcibly if unavailable
1091         if ($target{thread_scheme} eq "(unknown)") {
1092             $disabled{threads} = "unavailable";
1093         }
1094     } else {
1095         # The user chose to enable threads explicitly, let's see
1096         # if there's a chance that's possible
1097         if ($target{thread_scheme} eq "(unknown)") {
1098             # If the user asked for "threads" and we don't have internal
1099             # knowledge how to do it, [s]he is expected to provide any
1100             # system-dependent compiler options that are necessary.  We
1101             # can't truly check that the given options are correct, but
1102             # we expect the user to know what [s]He is doing.
1103             if ($no_user_cflags && $no_user_defines) {
1104                 die "You asked for multi-threading support, but didn't\n"
1105                     ,"provide any system-specific compiler options\n";
1106             }
1107         }
1108     }
1109 }
1110
1111 # If threads still aren't disabled, add a C macro to ensure the source
1112 # code knows about it.  Any other flag is taken care of by the configs.
1113 unless($disabled{threads}) {
1114     foreach (("defines", "openssl_thread_defines")) {
1115         push @{$config{$_}}, "OPENSSL_THREADS";
1116     }
1117 }
1118
1119 # With "deprecated" disable all deprecated features.
1120 if (defined($disabled{"deprecated"})) {
1121         $config{api} = $maxapi;
1122 }
1123
1124 if ($target{shared_target} eq "")
1125         {
1126         $no_shared_warn = 1
1127             if (!$disabled{shared} || !$disabled{"dynamic-engine"});
1128         $disabled{shared} = "no-shared-target";
1129         $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1130             "no-shared-target";
1131         }
1132
1133 if ($disabled{"dynamic-engine"}) {
1134         push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1135         $config{dynamic_engines} = 0;
1136 } else {
1137         push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1138         $config{dynamic_engines} = 1;
1139 }
1140
1141 unless ($disabled{asan}) {
1142     $config{cflags} .= "-fsanitize=address ";
1143 }
1144
1145 unless ($disabled{ubsan}) {
1146     # -DPEDANTIC or -fnosanitize=alignment may also be required on some
1147     # platforms.
1148     $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
1149 }
1150
1151 unless ($disabled{msan}) {
1152   $config{cflags} .= "-fsanitize=memory ";
1153 }
1154
1155 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1156         && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1157     $config{cflags} .= "-fno-omit-frame-pointer -g ";
1158 }
1159 #
1160 # Platform fix-ups
1161 #
1162
1163 # This saves the build files from having to check
1164 if ($disabled{pic})
1165         {
1166         $target{shared_cflag} = $target{shared_ldflag} =
1167                 $target{shared_rcflag} = "";
1168         }
1169 else
1170         {
1171         push @{$config{defines}}, "OPENSSL_PIC";
1172         }
1173
1174 if ($target{sys_id} ne "")
1175         {
1176         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1177         }
1178
1179 unless ($disabled{asm}) {
1180     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1181     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1182
1183     # bn-586 is the only one implementing bn_*_part_words
1184     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1185     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1186
1187     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1188     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1189     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1190
1191     if ($target{sha1_asm_src}) {
1192         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1193         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1194         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1195     }
1196     if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
1197         push @{$config{defines}}, "RC4_ASM";
1198     }
1199     if ($target{md5_asm_src}) {
1200         push @{$config{defines}}, "MD5_ASM";
1201     }
1202     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1203     if ($target{rmd160_asm_src}) {
1204         push @{$config{defines}}, "RMD160_ASM";
1205     }
1206     if ($target{aes_asm_src}) {
1207         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1208         # aes-ctr.fake is not a real file, only indication that assembler
1209         # module implements AES_ctr32_encrypt...
1210         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1211         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1212         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1213         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1214         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1215         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1216     }
1217     if ($target{wp_asm_src} =~ /mmx/) {
1218         if ($config{processor} eq "386") {
1219             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1220         } elsif (!$disabled{"whirlpool"}) {
1221             push @{$config{defines}}, "WHIRLPOOL_ASM";
1222         }
1223     }
1224     if ($target{modes_asm_src} =~ /ghash-/) {
1225         push @{$config{defines}}, "GHASH_ASM";
1226     }
1227     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1228         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1229     }
1230     if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
1231         push @{$config{defines}}, "PADLOCK_ASM";
1232     }
1233     if ($target{poly1305_asm_src} ne "") {
1234         push @{$config{defines}}, "POLY1305_ASM";
1235     }
1236 }
1237
1238 my %predefined;
1239
1240 if ($^O ne "VMS") {
1241     my $cc = "$config{cross_compile_prefix}$target{cc}";
1242
1243     # collect compiler pre-defines from gcc or gcc-alike...
1244     open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
1245     while (<PIPE>) {
1246         m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
1247         $predefined{$1} = $2 // "";
1248     }
1249     close(PIPE);
1250
1251     if (!$disabled{makedepend}) {
1252         # We know that GNU C version 3 and up as well as all clang
1253         # versions support dependency generation
1254         if ($predefined{__GNUC__} >= 3) {
1255             $config{makedepprog} = $cc;
1256         } else {
1257             $config{makedepprog} = which('makedepend');
1258             $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1259         }
1260     }
1261 }
1262
1263
1264
1265 # Deal with bn_ops ###################################################
1266
1267 $config{bn_ll}                  =0;
1268 $config{export_var_as_fn}       =0;
1269 my $def_int="unsigned int";
1270 $config{rc4_int}                =$def_int;
1271 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1272
1273 my $count = 0;
1274 foreach (sort split(/\s+/,$target{bn_ops})) {
1275     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1276     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1277     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1278     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1279     ($config{b64l},$config{b64},$config{b32})
1280         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1281     ($config{b64l},$config{b64},$config{b32})
1282         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1283     ($config{b64l},$config{b64},$config{b32})
1284         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1285 }
1286 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1287     if $count > 1;
1288
1289
1290 # Hack cflags for better warnings (dev option) #######################
1291
1292 # "Stringify" the C flags string.  This permits it to be made part of a string
1293 # and works as well on command lines.
1294 $config{cflags} =~ s/([\\\"])/\\$1/g;
1295
1296 if (defined($config{api})) {
1297     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1298     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1299     push @{$config{defines}}, $apiflag;
1300 }
1301
1302 if (defined($predefined{__clang__}) && !$disabled{asm}) {
1303     $config{cflags} .= " -Qunused-arguments";
1304 }
1305
1306 if ($strict_warnings)
1307         {
1308         my $wopt;
1309         my $gccver = $predefined{__GNUC__} // -1;
1310
1311         die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
1312             unless $gccver >= 4;
1313         $gcc_devteam_warn .= " -Wmisleading-indentation" if $gccver >= 6;
1314         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1315                 {
1316                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1317                 }
1318         if (defined($predefined{__clang__}))
1319                 {
1320                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1321                         {
1322                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1323                         }
1324                 }
1325         }
1326
1327 unless ($disabled{"crypto-mdebug-backtrace"})
1328         {
1329         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1330                 {
1331                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1332                 }
1333         if ($target =~ /^BSD-/)
1334                 {
1335                 $config{ex_libs} .= " -lexecinfo";
1336                 }
1337         }
1338
1339 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; $config{cxxflags}="$config{cxxflags}$user_cflags";}
1340 else                    { $no_user_cflags=1;  }
1341 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1342 else               { $no_user_defines=1;    }
1343
1344 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1345
1346 unless ($disabled{afalgeng}) {
1347     $config{afalgeng}="";
1348     if ($target =~ m/^linux/) {
1349         my $minver = 4*10000 + 1*100 + 0;
1350         if ($config{cross_compile_prefix} eq "") {
1351             my $verstr = `uname -r`;
1352             my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1353             ($mi2) = $mi2 =~ /(\d+)/;
1354             my $ver = $ma*10000 + $mi1*100 + $mi2;
1355             if ($ver < $minver) {
1356                 $disabled{afalgeng} = "too-old-kernel";
1357             } else {
1358                 push @{$config{engdirs}}, "afalg";
1359             }
1360         } else {
1361             $disabled{afalgeng} = "cross-compiling";
1362         }
1363     } else {
1364         $disabled{afalgeng}  = "not-linux";
1365     }
1366 }
1367
1368 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1369
1370 # If we use the unified build, collect information from build.info files
1371 my %unified_info = ();
1372
1373 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1374 if ($builder eq "unified") {
1375     use with_fallback qw(Text::Template);
1376
1377     sub cleandir {
1378         my $base = shift;
1379         my $dir = shift;
1380         my $relativeto = shift || ".";
1381
1382         $dir = catdir($base,$dir) unless isabsolute($dir);
1383
1384         # Make sure the directories we're building in exists
1385         mkpath($dir);
1386
1387         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1388         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1389         return $res;
1390     }
1391
1392     sub cleanfile {
1393         my $base = shift;
1394         my $file = shift;
1395         my $relativeto = shift || ".";
1396
1397         $file = catfile($base,$file) unless isabsolute($file);
1398
1399         my $d = dirname($file);
1400         my $f = basename($file);
1401
1402         # Make sure the directories we're building in exists
1403         mkpath($d);
1404
1405         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1406         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1407         return $res;
1408     }
1409
1410     # Store the name of the template file we will build the build file from
1411     # in %config.  This may be useful for the build file itself.
1412     my @build_file_template_names =
1413         ( $builder_platform."-".$target{build_file}.".tmpl",
1414           $target{build_file}.".tmpl" );
1415     my @build_file_templates = ();
1416
1417     # First, look in the user provided directory, if given
1418     if (defined env($local_config_envname)) {
1419         @build_file_templates =
1420             map {
1421                 if ($^O eq 'VMS') {
1422                     # VMS environment variables are logical names,
1423                     # which can be used as is
1424                     $local_config_envname . ':' . $_;
1425                 } else {
1426                     catfile(env($local_config_envname), $_);
1427                 }
1428             }
1429             @build_file_template_names;
1430     }
1431     # Then, look in our standard directory
1432     push @build_file_templates,
1433         ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1434           @build_file_template_names );
1435
1436     my $build_file_template;
1437     for $_ (@build_file_templates) {
1438         $build_file_template = $_;
1439         last if -f $build_file_template;
1440
1441         $build_file_template = undef;
1442     }
1443     if (!defined $build_file_template) {
1444         die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1445     }
1446     $config{build_file_templates}
1447       = [ $build_file_template,
1448           cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1449                     $blddir) ];
1450
1451     my @build_infos = ( [ ".", "build.info" ] );
1452     foreach (@{$config{dirs}}) {
1453         push @build_infos, [ $_, "build.info" ]
1454             if (-f catfile($srcdir, $_, "build.info"));
1455     }
1456     foreach (@{$config{sdirs}}) {
1457         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1458             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1459     }
1460     foreach (@{$config{engdirs}}) {
1461         push @build_infos, [ catdir("engines", $_), "build.info" ]
1462             if (-f catfile($srcdir, "engines", $_, "build.info"));
1463     }
1464     foreach (@{$config{tdirs}}) {
1465         push @build_infos, [ catdir("test", $_), "build.info" ]
1466             if (-f catfile($srcdir, "test", $_, "build.info"));
1467     }
1468
1469     $config{build_infos} = [ ];
1470
1471     foreach (@build_infos) {
1472         my $sourced = catdir($srcdir, $_->[0]);
1473         my $buildd = catdir($blddir, $_->[0]);
1474
1475         mkpath($buildd);
1476
1477         my $f = $_->[1];
1478         # The basic things we're trying to build
1479         my @programs = ();
1480         my @programs_install = ();
1481         my @libraries = ();
1482         my @libraries_install = ();
1483         my @engines = ();
1484         my @engines_install = ();
1485         my @scripts = ();
1486         my @scripts_install = ();
1487         my @extra = ();
1488         my @overrides = ();
1489         my @intermediates = ();
1490         my @rawlines = ();
1491
1492         my %ordinals = ();
1493         my %sources = ();
1494         my %shared_sources = ();
1495         my %includes = ();
1496         my %depends = ();
1497         my %renames = ();
1498         my %sharednames = ();
1499         my %generate = ();
1500
1501         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1502         my $template =
1503             Text::Template->new(TYPE => 'FILE',
1504                                 SOURCE => catfile($sourced, $f),
1505                                 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
1506         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1507         my @text =
1508             split /^/m,
1509             $template->fill_in(HASH => { config => \%config,
1510                                          target => \%target,
1511                                          disabled => \%disabled,
1512                                          withargs => \%withargs,
1513                                          builddir => abs2rel($buildd, $blddir),
1514                                          sourcedir => abs2rel($sourced, $blddir),
1515                                          buildtop => abs2rel($blddir, $blddir),
1516                                          sourcetop => abs2rel($srcdir, $blddir) },
1517                                DELIMITERS => [ "{-", "-}" ]);
1518
1519         # The top item of this stack has the following values
1520         # -2 positive already run and we found ELSE (following ELSIF should fail)
1521         # -1 positive already run (skip until ENDIF)
1522         # 0 negatives so far (if we're at a condition, check it)
1523         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1524         # 2 positive ELSE (following ELSIF should fail)
1525         my @skip = ();
1526         collect_information(
1527             collect_from_array([ @text ],
1528                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1529                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1530             # Info we're looking for
1531             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1532             => sub {
1533                 if (! @skip || $skip[$#skip] > 0) {
1534                     push @skip, !! $1;
1535                 } else {
1536                     push @skip, -1;
1537                 }
1538             },
1539             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1540             => sub { die "ELSIF out of scope" if ! @skip;
1541                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1542                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1543                      $skip[$#skip] = !! $1
1544                          if $skip[$#skip] == 0; },
1545             qr/^\s*ELSE\s*$/
1546             => sub { die "ELSE out of scope" if ! @skip;
1547                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1548                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1549             qr/^\s*ENDIF\s*$/
1550             => sub { die "ENDIF out of scope" if ! @skip;
1551                      pop @skip; },
1552             qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1553             => sub {
1554                 if (!@skip || $skip[$#skip] > 0) {
1555                     my $install = $1;
1556                     my @x = tokenize($2);
1557                     push @programs, @x;
1558                     push @programs_install, @x unless $install;
1559                 }
1560             },
1561             qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1562             => sub {
1563                 if (!@skip || $skip[$#skip] > 0) {
1564                     my $install = $1;
1565                     my @x = tokenize($2);
1566                     push @libraries, @x;
1567                     push @libraries_install, @x unless $install;
1568                 }
1569             },
1570             qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1571             => sub {
1572                 if (!@skip || $skip[$#skip] > 0) {
1573                     my $install = $1;
1574                     my @x = tokenize($2);
1575                     push @engines, @x;
1576                     push @engines_install, @x unless $install;
1577                 }
1578             },
1579             qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1580             => sub {
1581                 if (!@skip || $skip[$#skip] > 0) {
1582                     my $install = $1;
1583                     my @x = tokenize($2);
1584                     push @scripts, @x;
1585                     push @scripts_install, @x unless $install;
1586                 }
1587             },
1588             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1589             => sub { push @extra, tokenize($1)
1590                          if !@skip || $skip[$#skip] > 0 },
1591             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1592             => sub { push @overrides, tokenize($1)
1593                          if !@skip || $skip[$#skip] > 0 },
1594
1595             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1596             => sub { push @{$ordinals{$1}}, tokenize($2)
1597                          if !@skip || $skip[$#skip] > 0 },
1598             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1599             => sub { push @{$sources{$1}}, tokenize($2)
1600                          if !@skip || $skip[$#skip] > 0 },
1601             qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1602             => sub { push @{$shared_sources{$1}}, tokenize($2)
1603                          if !@skip || $skip[$#skip] > 0 },
1604             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1605             => sub { push @{$includes{$1}}, tokenize($2)
1606                          if !@skip || $skip[$#skip] > 0 },
1607             qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
1608             => sub { push @{$depends{$1}}, tokenize($2)
1609                          if !@skip || $skip[$#skip] > 0 },
1610             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1611             => sub { push @{$generate{$1}}, $2
1612                          if !@skip || $skip[$#skip] > 0 },
1613             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1614             => sub { push @{$renames{$1}}, tokenize($2)
1615                          if !@skip || $skip[$#skip] > 0 },
1616             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1617             => sub { push @{$sharednames{$1}}, tokenize($2)
1618                          if !@skip || $skip[$#skip] > 0 },
1619             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1620             => sub {
1621                 my $lineiterator = shift;
1622                 my $target_kind = $1;
1623                 while (defined $lineiterator->()) {
1624                     s|\R$||;
1625                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1626                         die "ENDRAW doesn't match BEGINRAW"
1627                             if $1 ne $target_kind;
1628                         last;
1629                     }
1630                     next if @skip && $skip[$#skip] <= 0;
1631                     push @rawlines,  $_
1632                         if ($target_kind eq $target{build_file}
1633                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1634                 }
1635             },
1636             qr/^\s*(?:#.*)?$/ => sub { },
1637             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1638             "BEFORE" => sub {
1639                 if ($buildinfo_debug) {
1640                     print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1641                     print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1642                 }
1643             },
1644             "AFTER" => sub {
1645                 if ($buildinfo_debug) {
1646                     print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1647                 }
1648             },
1649             );
1650         die "runaway IF?" if (@skip);
1651
1652         foreach (keys %renames) {
1653             die "$_ renamed to more than one thing: "
1654                 ,join(" ", @{$renames{$_}}),"\n"
1655                 if scalar @{$renames{$_}} > 1;
1656             my $dest = cleanfile($buildd, $_, $blddir);
1657             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1658             die "$dest renamed to more than one thing: "
1659                 ,$unified_info{rename}->{$dest}, $to
1660                 unless !defined($unified_info{rename}->{$dest})
1661                 or $unified_info{rename}->{$dest} eq $to;
1662             $unified_info{rename}->{$dest} = $to;
1663         }
1664
1665         foreach (@programs) {
1666             my $program = cleanfile($buildd, $_, $blddir);
1667             if ($unified_info{rename}->{$program}) {
1668                 $program = $unified_info{rename}->{$program};
1669             }
1670             $unified_info{programs}->{$program} = 1;
1671         }
1672
1673         foreach (@programs_install) {
1674             my $program = cleanfile($buildd, $_, $blddir);
1675             if ($unified_info{rename}->{$program}) {
1676                 $program = $unified_info{rename}->{$program};
1677             }
1678             $unified_info{install}->{programs}->{$program} = 1;
1679         }
1680
1681         foreach (@libraries) {
1682             my $library = cleanfile($buildd, $_, $blddir);
1683             if ($unified_info{rename}->{$library}) {
1684                 $library = $unified_info{rename}->{$library};
1685             }
1686             $unified_info{libraries}->{$library} = 1;
1687         }
1688
1689         foreach (@libraries_install) {
1690             my $library = cleanfile($buildd, $_, $blddir);
1691             if ($unified_info{rename}->{$library}) {
1692                 $library = $unified_info{rename}->{$library};
1693             }
1694             $unified_info{install}->{libraries}->{$library} = 1;
1695         }
1696
1697         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1698 ENGINES can only be used if configured with 'dynamic-engine'.
1699 This is usually a fault in a build.info file.
1700 EOF
1701         foreach (@engines) {
1702             my $library = cleanfile($buildd, $_, $blddir);
1703             if ($unified_info{rename}->{$library}) {
1704                 $library = $unified_info{rename}->{$library};
1705             }
1706             $unified_info{engines}->{$library} = 1;
1707         }
1708
1709         foreach (@engines_install) {
1710             my $library = cleanfile($buildd, $_, $blddir);
1711             if ($unified_info{rename}->{$library}) {
1712                 $library = $unified_info{rename}->{$library};
1713             }
1714             $unified_info{install}->{engines}->{$library} = 1;
1715         }
1716
1717         foreach (@scripts) {
1718             my $script = cleanfile($buildd, $_, $blddir);
1719             if ($unified_info{rename}->{$script}) {
1720                 $script = $unified_info{rename}->{$script};
1721             }
1722             $unified_info{scripts}->{$script} = 1;
1723         }
1724
1725         foreach (@scripts_install) {
1726             my $script = cleanfile($buildd, $_, $blddir);
1727             if ($unified_info{rename}->{$script}) {
1728                 $script = $unified_info{rename}->{$script};
1729             }
1730             $unified_info{install}->{scripts}->{$script} = 1;
1731         }
1732
1733         foreach (@extra) {
1734             my $extra = cleanfile($buildd, $_, $blddir);
1735             $unified_info{extra}->{$extra} = 1;
1736         }
1737
1738         foreach (@overrides) {
1739             my $override = cleanfile($buildd, $_, $blddir);
1740             $unified_info{overrides}->{$override} = 1;
1741         }
1742
1743         push @{$unified_info{rawlines}}, @rawlines;
1744
1745         unless ($disabled{shared}) {
1746             # Check sharednames.
1747             foreach (keys %sharednames) {
1748                 my $dest = cleanfile($buildd, $_, $blddir);
1749                 if ($unified_info{rename}->{$dest}) {
1750                     $dest = $unified_info{rename}->{$dest};
1751                 }
1752                 die "shared_name for $dest with multiple values: "
1753                     ,join(" ", @{$sharednames{$_}}),"\n"
1754                     if scalar @{$sharednames{$_}} > 1;
1755                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1756                 die "shared_name found for a library $dest that isn't defined\n"
1757                     unless $unified_info{libraries}->{$dest};
1758                 die "shared_name for $dest with multiple values: "
1759                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1760                     unless !defined($unified_info{sharednames}->{$dest})
1761                     or $unified_info{sharednames}->{$dest} eq $to;
1762                 $unified_info{sharednames}->{$dest} = $to;
1763             }
1764
1765             # Additionally, we set up sharednames for libraries that don't
1766             # have any, as themselves.  Only for libraries that aren't
1767             # explicitly static.
1768             foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) {
1769                 if (!defined $unified_info{sharednames}->{$_}) {
1770                     $unified_info{sharednames}->{$_} = $_
1771                 }
1772             }
1773
1774             # Check that we haven't defined any library as both shared and
1775             # explicitly static.  That is forbidden.
1776             my @doubles = ();
1777             foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
1778                 (my $l = $_) =~ s/\.a$//;
1779                 push @doubles, $l if defined $unified_info{sharednames}->{$l};
1780             }
1781             die "these libraries are both explicitly static and shared:\n  ",
1782                 join(" ", @doubles), "\n"
1783                 if @doubles;
1784         }
1785
1786         foreach (keys %ordinals) {
1787             my $dest = $_;
1788             my $ddest = cleanfile($buildd, $_, $blddir);
1789             if ($unified_info{rename}->{$ddest}) {
1790                 $ddest = $unified_info{rename}->{$ddest};
1791             }
1792             foreach (@{$ordinals{$dest}}) {
1793                 my %known_ordinals =
1794                     (
1795                      crypto =>
1796                      cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1797                      ssl =>
1798                      cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1799                     );
1800                 my $o = $known_ordinals{$_};
1801                 die "Ordinals for $ddest defined more than once\n"
1802                     if $unified_info{ordinals}->{$ddest};
1803                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1804             }
1805         }
1806
1807         foreach (keys %sources) {
1808             my $dest = $_;
1809             my $ddest = cleanfile($buildd, $_, $blddir);
1810             if ($unified_info{rename}->{$ddest}) {
1811                 $ddest = $unified_info{rename}->{$ddest};
1812             }
1813             foreach (@{$sources{$dest}}) {
1814                 my $s = cleanfile($sourced, $_, $blddir);
1815
1816                 # If it isn't in the source tree, we assume it's generated
1817                 # in the build tree
1818                 if (! -f $s) {
1819                     $s = cleanfile($buildd, $_, $blddir);
1820                 }
1821                 # We recognise C++, C and asm files
1822                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1823                     my $o = $_;
1824                     $o =~ s/\.[csS]$/.o/; # C and assembler
1825                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1826                     $o = cleanfile($buildd, $o, $blddir);
1827                     $unified_info{sources}->{$ddest}->{$o} = 1;
1828                     $unified_info{sources}->{$o}->{$s} = 1;
1829                 } else {
1830                     $unified_info{sources}->{$ddest}->{$s} = 1;
1831                 }
1832             }
1833         }
1834
1835         foreach (keys %shared_sources) {
1836             my $dest = $_;
1837             my $ddest = cleanfile($buildd, $_, $blddir);
1838             if ($unified_info{rename}->{$ddest}) {
1839                 $ddest = $unified_info{rename}->{$ddest};
1840             }
1841             foreach (@{$shared_sources{$dest}}) {
1842                 my $s = cleanfile($sourced, $_, $blddir);
1843
1844                 # If it isn't in the source tree, we assume it's generated
1845                 # in the build tree
1846                 if (! -f $s) {
1847                     $s = cleanfile($buildd, $_, $blddir);
1848                 }
1849                 # We recognise C++, C and asm files
1850                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1851                     my $o = $_;
1852                     $o =~ s/\.[csS]$/.o/; # C and assembler
1853                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1854                     $o = cleanfile($buildd, $o, $blddir);
1855                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1856                     $unified_info{sources}->{$o}->{$s} = 1;
1857                 } else {
1858                     die "unrecognised source file type for shared library: $s\n";
1859                 }
1860             }
1861         }
1862
1863         foreach (keys %generate) {
1864             my $dest = $_;
1865             my $ddest = cleanfile($buildd, $_, $blddir);
1866             if ($unified_info{rename}->{$ddest}) {
1867                 $ddest = $unified_info{rename}->{$ddest};
1868             }
1869             die "more than one generator for $dest: "
1870                     ,join(" ", @{$generate{$_}}),"\n"
1871                     if scalar @{$generate{$_}} > 1;
1872             my @generator = split /\s+/, $generate{$dest}->[0];
1873             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1874             $unified_info{generate}->{$ddest} = [ @generator ];
1875         }
1876
1877         foreach (keys %depends) {
1878             my $dest = $_;
1879             my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
1880
1881             # If the destination doesn't exist in source, it can only be
1882             # a generated file in the build tree.
1883             if ($ddest ne "" && ! -f $ddest) {
1884                 $ddest = cleanfile($buildd, $_, $blddir);
1885                 if ($unified_info{rename}->{$ddest}) {
1886                     $ddest = $unified_info{rename}->{$ddest};
1887                 }
1888             }
1889             foreach (@{$depends{$dest}}) {
1890                 my $d = cleanfile($sourced, $_, $blddir);
1891
1892                 # If we know it's generated, or assume it is because we can't
1893                 # find it in the source tree, we set file we depend on to be
1894                 # in the build tree rather than the source tree, and assume
1895                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1896                 # section or in the Makefile template.
1897                 if (! -f $d
1898                     || (grep { $d eq $_ }
1899                         map { cleanfile($srcdir, $_, $blddir) }
1900                         grep { /\.h$/ } keys %{$unified_info{generate}})) {
1901                     $d = cleanfile($buildd, $_, $blddir);
1902                 }
1903                 # Take note if the file to depend on is being renamed
1904                 # Take extra care with files ending with .a, they should
1905                 # be treated without that extension, and the extension
1906                 # should be added back after treatment.
1907                 $d =~ /(\.a)?$/;
1908                 my $e = $1 // "";
1909                 $d = $`;
1910                 if ($unified_info{rename}->{$d}) {
1911                     $d = $unified_info{rename}->{$d};
1912                 }
1913                 $d .= $e;
1914                 $unified_info{depends}->{$ddest}->{$d} = 1;
1915                 # If we depend on a header file or a perl module, let's make
1916                 # sure it can get included
1917                 if ($dest ne "" && $d =~ /\.(h|pm)$/) {
1918                     my $i = dirname($d);
1919                     push @{$unified_info{includes}->{$ddest}->{source}}, $i
1920                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}};
1921                 }
1922             }
1923         }
1924
1925         foreach (keys %includes) {
1926             my $dest = $_;
1927             my $ddest = cleanfile($sourced, $_, $blddir);
1928
1929             # If the destination doesn't exist in source, it can only be
1930             # a generated file in the build tree.
1931             if (! -f $ddest) {
1932                 $ddest = cleanfile($buildd, $_, $blddir);
1933                 if ($unified_info{rename}->{$ddest}) {
1934                     $ddest = $unified_info{rename}->{$ddest};
1935                 }
1936             }
1937             foreach (@{$includes{$dest}}) {
1938                 my $is = cleandir($sourced, $_, $blddir);
1939                 my $ib = cleandir($buildd, $_, $blddir);
1940                 push @{$unified_info{includes}->{$ddest}->{source}}, $is
1941                     unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
1942                 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
1943                     unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
1944             }
1945         }
1946     }
1947
1948     ### Make unified_info a bit more efficient
1949     # One level structures
1950     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1951         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1952     }
1953     # Two level structures
1954     foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
1955         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1956             $unified_info{$l1}->{$l2} =
1957                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1958         }
1959     }
1960     # Includes
1961     foreach my $dest (sort keys %{$unified_info{includes}}) {
1962         if (defined($unified_info{includes}->{$dest}->{build})) {
1963             my @source_includes =
1964                 ( @{$unified_info{includes}->{$dest}->{source}} );
1965             $unified_info{includes}->{$dest} =
1966                 [ @{$unified_info{includes}->{$dest}->{build}} ];
1967             foreach my $inc (@source_includes) {
1968                 push @{$unified_info{includes}->{$dest}}, $inc
1969                     unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
1970             }
1971         } else {
1972             $unified_info{includes}->{$dest} =
1973                 [ @{$unified_info{includes}->{$dest}->{source}} ];
1974         }
1975     }
1976 }
1977
1978 # For the schemes that need it, we provide the old *_obj configs
1979 # from the *_asm_obj ones
1980 foreach (grep /_(asm|aux)_src$/, keys %target) {
1981     my $src = $_;
1982     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1983     $target{$obj} = $target{$src};
1984     $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
1985     $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
1986 }
1987
1988 # Write down our configuration where it fits #########################
1989
1990 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1991 print OUT <<"EOF";
1992 package configdata;
1993
1994 use strict;
1995 use warnings;
1996
1997 use Exporter;
1998 #use vars qw(\@ISA \@EXPORT);
1999 our \@ISA = qw(Exporter);
2000 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
2001
2002 EOF
2003 print OUT "our %config = (\n";
2004 foreach (sort keys %config) {
2005     if (ref($config{$_}) eq "ARRAY") {
2006         print OUT "  ", $_, " => [ ", join(", ",
2007                                            map { quotify("perl", $_) }
2008                                            @{$config{$_}}), " ],\n";
2009     } elsif (ref($config{$_}) eq "HASH") {
2010         print OUT "  ", $_, " => {";
2011         if (scalar keys %{$config{$_}} > 0) {
2012             print OUT "\n";
2013             foreach my $key (sort keys %{$config{$_}}) {
2014                 print OUT "      ",
2015                     join(" => ",
2016                          quotify("perl", $key),
2017                          defined $config{$_}->{$key}
2018                              ? quotify("perl", $config{$_}->{$key})
2019                              : "undef");
2020                 print OUT ",\n";
2021             }
2022             print OUT "  ";
2023         }
2024         print OUT "},\n";
2025     } else {
2026         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
2027     }
2028 }
2029 print OUT <<"EOF";
2030 );
2031
2032 EOF
2033 print OUT "our %target = (\n";
2034 foreach (sort keys %target) {
2035     if (ref($target{$_}) eq "ARRAY") {
2036         print OUT "  ", $_, " => [ ", join(", ",
2037                                            map { quotify("perl", $_) }
2038                                            @{$target{$_}}), " ],\n";
2039     } else {
2040         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
2041     }
2042 }
2043 print OUT <<"EOF";
2044 );
2045
2046 EOF
2047 print OUT "our \%available_protocols = (\n";
2048 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
2049 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
2050 print OUT <<"EOF";
2051 );
2052
2053 EOF
2054 print OUT "our \@disablables = (\n";
2055 foreach (@disablables) {
2056     print OUT "  ", quotify("perl", $_), ",\n";
2057 }
2058 print OUT <<"EOF";
2059 );
2060
2061 EOF
2062 print OUT "our \%disabled = (\n";
2063 foreach (sort keys %disabled) {
2064     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
2065 }
2066 print OUT <<"EOF";
2067 );
2068
2069 EOF
2070 print OUT "our %withargs = (\n";
2071 foreach (sort keys %withargs) {
2072     if (ref($withargs{$_}) eq "ARRAY") {
2073         print OUT "  ", $_, " => [ ", join(", ",
2074                                            map { quotify("perl", $_) }
2075                                            @{$withargs{$_}}), " ],\n";
2076     } else {
2077         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
2078     }
2079 }
2080 print OUT <<"EOF";
2081 );
2082
2083 EOF
2084 if ($builder eq "unified") {
2085     my $recurse;
2086     $recurse = sub {
2087         my $indent = shift;
2088         foreach (@_) {
2089             if (ref $_ eq "ARRAY") {
2090                 print OUT " "x$indent, "[\n";
2091                 foreach (@$_) {
2092                     $recurse->($indent + 4, $_);
2093                 }
2094                 print OUT " "x$indent, "],\n";
2095             } elsif (ref $_ eq "HASH") {
2096                 my %h = %$_;
2097                 print OUT " "x$indent, "{\n";
2098                 foreach (sort keys %h) {
2099                     if (ref $h{$_} eq "") {
2100                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
2101                     } else {
2102                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
2103                         $recurse->($indent + 8, $h{$_});
2104                     }
2105                 }
2106                 print OUT " "x$indent, "},\n";
2107             } else {
2108                 print OUT " "x$indent, quotify("perl", $_), ",\n";
2109             }
2110         }
2111     };
2112     print OUT "our %unified_info = (\n";
2113     foreach (sort keys %unified_info) {
2114         if (ref $unified_info{$_} eq "") {
2115             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
2116         } else {
2117             print OUT " "x4, quotify("perl", $_), " =>\n";
2118             $recurse->(8, $unified_info{$_});
2119         }
2120     }
2121     print OUT <<"EOF";
2122 );
2123
2124 EOF
2125 }
2126 print OUT "1;\n";
2127 close(OUT);
2128
2129 print "\n";
2130 print "PROCESSOR     =$config{processor}\n" if $config{processor};
2131 print "PERL          =$config{perl}\n";
2132 print "PERLVERSION   =$Config{version} for $Config{archname}\n";
2133 print "HASHBANGPERL  =$config{hashbangperl}\n";
2134 print "CC            =$config{cross_compile_prefix}$target{cc}\n";
2135 print "CFLAG         =$target{cflags} $config{cflags}\n";
2136 print "CXX           =$config{cross_compile_prefix}$target{cxx}\n"
2137     if defined $target{cxx};
2138 print "CXXFLAG       =$target{cxxflags} $config{cxxflags}\n"
2139     if defined $target{cxx};
2140 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
2141 #print "RANLIB        =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
2142 #                             "$config{cross_compile_prefix}ranlib" :
2143 #                             "$target{ranlib}", "\n";
2144 print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
2145
2146 my %builders = (
2147     unified => sub {
2148         run_dofile(catfile($blddir, $target{build_file}),
2149                    @{$config{build_file_templates}});
2150     },
2151     );
2152
2153 $builders{$builder}->($builder_platform, @builder_opts);
2154
2155 print <<"EOF" if ($disabled{threads} eq "unavailable");
2156
2157 The library could not be configured for supporting multi-threaded
2158 applications as the compiler options required on this system are not known.
2159 See file INSTALL for details if you need multi-threading.
2160 EOF
2161
2162 print <<"EOF" if ($no_shared_warn);
2163
2164 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2165 platform, so we will pretend you gave the option 'no-pic', which also disables
2166 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
2167 or position independent code, please let us know (but please first make sure
2168 you have tried with a current version of OpenSSL).
2169 EOF
2170
2171 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2172
2173 WARNING: there are indications that another build was made in the source
2174 directory.  This build may have picked up artifacts from that build, the
2175 safest course of action is to clean the source directory and redo this
2176 configuration.
2177 EOF
2178
2179 exit(0);
2180
2181 ######################################################################
2182 #
2183 # Helpers and utility functions
2184 #
2185
2186 # Configuration file reading #########################################
2187
2188 # Note: All of the helper functions are for lazy evaluation.  They all
2189 # return a CODE ref, which will return the intended value when evaluated.
2190 # Thus, whenever there's mention of a returned value, it's about that
2191 # intended value.
2192
2193 # Helper function to implement conditional inheritance depending on the
2194 # value of $disabled{asm}.  Used in inherit_from values as follows:
2195 #
2196 #      inherit_from => [ "template", asm("asm_tmpl") ]
2197 #
2198 sub asm {
2199     my @x = @_;
2200     sub {
2201         $disabled{asm} ? () : @x;
2202     }
2203 }
2204
2205 # Helper function to implement conditional value variants, with a default
2206 # plus additional values based on the value of $config{build_type}.
2207 # Arguments are given in hash table form:
2208 #
2209 #       picker(default => "Basic string: ",
2210 #              debug   => "debug",
2211 #              release => "release")
2212 #
2213 # When configuring with --debug, the resulting string will be
2214 # "Basic string: debug", and when not, it will be "Basic string: release"
2215 #
2216 # This can be used to create variants of sets of flags according to the
2217 # build type:
2218 #
2219 #       cflags => picker(default => "-Wall",
2220 #                        debug   => "-g -O0",
2221 #                        release => "-O3")
2222 #
2223 sub picker {
2224     my %opts = @_;
2225     return sub { add($opts{default} || (),
2226                      $opts{$config{build_type}} || ())->(); }
2227 }
2228
2229 # Helper function to combine several values of different types into one.
2230 # This is useful if you want to combine a string with the result of a
2231 # lazy function, such as:
2232 #
2233 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2234 #
2235 sub combine {
2236     my @stuff = @_;
2237     return sub { add(@stuff)->(); }
2238 }
2239
2240 # Helper function to implement conditional values depending on the value
2241 # of $disabled{threads}.  Can be used as follows:
2242 #
2243 #       cflags => combine("-Wall", threads("-pthread"))
2244 #
2245 sub threads {
2246     my @flags = @_;
2247     return sub { add($disabled{threads} ? () : @flags)->(); }
2248 }
2249
2250
2251
2252 our $add_called = 0;
2253 # Helper function to implement adding values to already existing configuration
2254 # values.  It handles elements that are ARRAYs, CODEs and scalars
2255 sub _add {
2256     my $separator = shift;
2257
2258     # If there's any ARRAY in the collection of values OR the separator
2259     # is undef, we will return an ARRAY of combined values, otherwise a
2260     # string of joined values with $separator as the separator.
2261     my $found_array = !defined($separator);
2262
2263     my @values =
2264         map {
2265             my $res = $_;
2266             while (ref($res) eq "CODE") {
2267                 $res = $res->();
2268             }
2269             if (defined($res)) {
2270                 if (ref($res) eq "ARRAY") {
2271                     $found_array = 1;
2272                     @$res;
2273                 } else {
2274                     $res;
2275                 }
2276             } else {
2277                 ();
2278             }
2279     } (@_);
2280
2281     $add_called = 1;
2282
2283     if ($found_array) {
2284         [ @values ];
2285     } else {
2286         join($separator, grep { defined($_) && $_ ne "" } @values);
2287     }
2288 }
2289 sub add_before {
2290     my $separator = " ";
2291     if (ref($_[$#_]) eq "HASH") {
2292         my $opts = pop;
2293         $separator = $opts->{separator};
2294     }
2295     my @x = @_;
2296     sub { _add($separator, @x, @_) };
2297 }
2298 sub add {
2299     my $separator = " ";
2300     if (ref($_[$#_]) eq "HASH") {
2301         my $opts = pop;
2302         $separator = $opts->{separator};
2303     }
2304     my @x = @_;
2305     sub { _add($separator, @_, @x) };
2306 }
2307
2308 # configuration reader, evaluates the input file as a perl script and expects
2309 # it to fill %targets with target configurations.  Those are then added to
2310 # %table.
2311 sub read_config {
2312     my $fname = shift;
2313     open(CONFFILE, "< $fname")
2314         or die "Can't open configuration file '$fname'!\n";
2315     my $x = $/;
2316     undef $/;
2317     my $content = <CONFFILE>;
2318     $/ = $x;
2319     close(CONFFILE);
2320     my %targets = ();
2321     {
2322         # Protect certain tables from tampering
2323         local %table = %::table;
2324
2325         eval $content;
2326         warn $@ if $@;
2327     }
2328
2329     # For each target, check that it's configured with a hash table.
2330     foreach (keys %targets) {
2331         if (ref($targets{$_}) ne "HASH") {
2332             if (ref($targets{$_}) eq "") {
2333                 warn "Deprecated target configuration for $_, ignoring...\n";
2334             } else {
2335                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2336             }
2337             delete $targets{$_};
2338         } else {
2339             $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2340         }
2341     }
2342
2343     %table = (%table, %targets);
2344
2345 }
2346
2347 # configuration resolver.  Will only resolve all the lazy evaluation
2348 # codeblocks for the chosen target and all those it inherits from,
2349 # recursively
2350 sub resolve_config {
2351     my $target = shift;
2352     my @breadcrumbs = @_;
2353
2354 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2355
2356     if (grep { $_ eq $target } @breadcrumbs) {
2357         die "inherit_from loop!  target backtrace:\n  "
2358             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2359     }
2360
2361     if (!defined($table{$target})) {
2362         warn "Warning! target $target doesn't exist!\n";
2363         return ();
2364     }
2365     # Recurse through all inheritances.  They will be resolved on the
2366     # fly, so when this operation is done, they will all just be a
2367     # bunch of attributes with string values.
2368     # What we get here, though, are keys with references to lists of
2369     # the combined values of them all.  We will deal with lists after
2370     # this stage is done.
2371     my %combined_inheritance = ();
2372     if ($table{$target}->{inherit_from}) {
2373         my @inherit_from =
2374             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2375         foreach (@inherit_from) {
2376             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2377
2378             # 'template' is a marker that's considered private to
2379             # the config that had it.
2380             delete $inherited_config{template};
2381
2382             foreach (keys %inherited_config) {
2383                 if (!$combined_inheritance{$_}) {
2384                     $combined_inheritance{$_} = [];
2385                 }
2386                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2387             }
2388         }
2389     }
2390
2391     # We won't need inherit_from in this target any more, since we've
2392     # resolved all the inheritances that lead to this
2393     delete $table{$target}->{inherit_from};
2394
2395     # Now is the time to deal with those lists.  Here's the place to
2396     # decide what shall be done with those lists, all based on the
2397     # values of the target we're currently dealing with.
2398     # - If a value is a coderef, it will be executed with the list of
2399     #   inherited values as arguments.
2400     # - If the corresponding key doesn't have a value at all or is the
2401     #   empty string, the inherited value list will be run through the
2402     #   default combiner (below), and the result becomes this target's
2403     #   value.
2404     # - Otherwise, this target's value is assumed to be a string that
2405     #   will simply override the inherited list of values.
2406     my $default_combiner = add();
2407
2408     my %all_keys =
2409         map { $_ => 1 } (keys %combined_inheritance,
2410                          keys %{$table{$target}});
2411
2412     sub process_values {
2413         my $object    = shift;
2414         my $inherited = shift;  # Always a [ list ]
2415         my $target    = shift;
2416         my $entry     = shift;
2417
2418         $add_called = 0;
2419
2420         while(ref($object) eq "CODE") {
2421             $object = $object->(@$inherited);
2422         }
2423         if (!defined($object)) {
2424             return ();
2425         }
2426         elsif (ref($object) eq "ARRAY") {
2427             local $add_called;  # To make sure recursive calls don't affect it
2428             return [ map { process_values($_, $inherited, $target, $entry) }
2429                      @$object ];
2430         } elsif (ref($object) eq "") {
2431             return $object;
2432         } else {
2433             die "cannot handle reference type ",ref($object)
2434                 ," found in target ",$target," -> ",$entry,"\n";
2435         }
2436     }
2437
2438     foreach (sort keys %all_keys) {
2439         my $previous = $combined_inheritance{$_};
2440
2441         # Current target doesn't have a value for the current key?
2442         # Assign it the default combiner, the rest of this loop body
2443         # will handle it just like any other coderef.
2444         if (!exists $table{$target}->{$_}) {
2445             $table{$target}->{$_} = $default_combiner;
2446         }
2447
2448         $table{$target}->{$_} = process_values($table{$target}->{$_},
2449                                                $combined_inheritance{$_},
2450                                                $target, $_);
2451         unless(defined($table{$target}->{$_})) {
2452             delete $table{$target}->{$_};
2453         }
2454 #        if ($extra_checks &&
2455 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2456 #            warn "$_ got replaced in $target\n";
2457 #        }
2458     }
2459
2460     # Finally done, return the result.
2461     return %{$table{$target}};
2462 }
2463
2464 sub usage
2465         {
2466         print STDERR $usage;
2467         print STDERR "\npick os/compiler from:\n";
2468         my $j=0;
2469         my $i;
2470         my $k=0;
2471         foreach $i (sort keys %table)
2472                 {
2473                 next if $table{$i}->{template};
2474                 next if $i =~ /^debug/;
2475                 $k += length($i) + 1;
2476                 if ($k > 78)
2477                         {
2478                         print STDERR "\n";
2479                         $k=length($i);
2480                         }
2481                 print STDERR $i . " ";
2482                 }
2483         foreach $i (sort keys %table)
2484                 {
2485                 next if $table{$i}->{template};
2486                 next if $i !~ /^debug/;
2487                 $k += length($i) + 1;
2488                 if ($k > 78)
2489                         {
2490                         print STDERR "\n";
2491                         $k=length($i);
2492                         }
2493                 print STDERR $i . " ";
2494                 }
2495         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2496         exit(1);
2497         }
2498
2499 sub run_dofile
2500 {
2501     my $out = shift;
2502     my @templates = @_;
2503
2504     unlink $out || warn "Can't remove $out, $!"
2505         if -f $out;
2506     foreach (@templates) {
2507         die "Can't open $_, $!" unless -f $_;
2508     }
2509     my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2510     my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2511     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2512     system($cmd);
2513     exit 1 if $? != 0;
2514     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2515 }
2516
2517 sub which
2518 {
2519     my ($name)=@_;
2520
2521     if (eval { require IPC::Cmd; 1; }) {
2522         IPC::Cmd->import();
2523         return scalar IPC::Cmd::can_run($name);
2524     } else {
2525         # if there is $directories component in splitpath,
2526         # then it's not something to test with $PATH...
2527         return $name if (File::Spec->splitpath($name))[1];
2528
2529         foreach (File::Spec->path()) {
2530             my $fullpath = catfile($_, "$name$target{exe_extension}");
2531             if (-f $fullpath and -x $fullpath) {
2532                 return $fullpath;
2533             }
2534         }
2535     }
2536 }
2537
2538 sub env
2539 {
2540     my $name = shift;
2541
2542     # Note that if $ENV{$name} doesn't exist or is undefined,
2543     # $config{perlenv}->{$name} will be created with the value
2544     # undef.  This is intentional.
2545
2546     $config{perlenv}->{$name} = $ENV{$name}
2547         if ! exists $config{perlenv}->{$name};
2548     return $config{perlenv}->{$name};
2549 }
2550
2551 # Configuration printer ##############################################
2552
2553 sub print_table_entry
2554 {
2555     my $target = shift;
2556     my %target = resolve_config($target);
2557     my $type = shift;
2558
2559     # Don't print the templates
2560     return if $target{template};
2561
2562     my @sequence = (
2563         "sys_id",
2564         "cc",
2565         "cflags",
2566         "defines",
2567         "unistd",
2568         "ld",
2569         "lflags",
2570         "loutflag",
2571         "plib_lflags",
2572         "ex_libs",
2573         "bn_ops",
2574         "apps_aux_src",
2575         "cpuid_asm_src",
2576         "uplink_aux_src",
2577         "bn_asm_src",
2578         "ec_asm_src",
2579         "des_asm_src",
2580         "aes_asm_src",
2581         "bf_asm_src",
2582         "md5_asm_src",
2583         "cast_asm_src",
2584         "sha1_asm_src",
2585         "rc4_asm_src",
2586         "rmd160_asm_src",
2587         "rc5_asm_src",
2588         "wp_asm_src",
2589         "cmll_asm_src",
2590         "modes_asm_src",
2591         "padlock_asm_src",
2592         "chacha_asm_src",
2593         "poly1035_asm_src",
2594         "thread_scheme",
2595         "perlasm_scheme",
2596         "dso_scheme",
2597         "shared_target",
2598         "shared_cflag",
2599         "shared_defines",
2600         "shared_ldflag",
2601         "shared_rcflag",
2602         "shared_extension",
2603         "dso_extension",
2604         "obj_extension",
2605         "exe_extension",
2606         "ranlib",
2607         "ar",
2608         "arflags",
2609         "aroutflag",
2610         "rc",
2611         "rcflags",
2612         "rcoutflag",
2613         "mt",
2614         "mtflags",
2615         "mtinflag",
2616         "mtoutflag",
2617         "multilib",
2618         "build_scheme",
2619         );
2620
2621     if ($type eq "TABLE") {
2622         print "\n";
2623         print "*** $target\n";
2624         foreach (@sequence) {
2625             if (ref($target{$_}) eq "ARRAY") {
2626                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2627             } else {
2628                 printf "\$%-12s = %s\n", $_, $target{$_};
2629             }
2630         }
2631     } elsif ($type eq "HASH") {
2632         my $largest =
2633             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2634         print "    '$target' => {\n";
2635         foreach (@sequence) {
2636             if ($target{$_}) {
2637                 if (ref($target{$_}) eq "ARRAY") {
2638                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2639                 } else {
2640                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2641                 }
2642             }
2643         }
2644         print "    },\n";
2645     }
2646 }
2647
2648 # Utility routines ###################################################
2649
2650 # On VMS, if the given file is a logical name, File::Spec::Functions
2651 # will consider it an absolute path.  There are cases when we want a
2652 # purely syntactic check without checking the environment.
2653 sub isabsolute {
2654     my $file = shift;
2655
2656     # On non-platforms, we just use file_name_is_absolute().
2657     return file_name_is_absolute($file) unless $^O eq "VMS";
2658
2659     # If the file spec includes a device or a directory spec,
2660     # file_name_is_absolute() is perfectly safe.
2661     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2662
2663     # Here, we know the given file spec isn't absolute
2664     return 0;
2665 }
2666
2667 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2668 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2669 # realpath() requires that at least all path components except the last is an
2670 # existing directory.  On VMS, the last component of the directory spec must
2671 # exist.
2672 sub absolutedir {
2673     my $dir = shift;
2674
2675     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2676     # will return the volume name for the device, no matter what.  Also,
2677     # it will return an incorrect directory spec if the argument is a
2678     # directory that doesn't exist.
2679     if ($^O eq "VMS") {
2680         return rel2abs($dir);
2681     }
2682
2683     # We use realpath() on Unix, since no other will properly clean out
2684     # a directory spec.
2685     use Cwd qw/realpath/;
2686
2687     return realpath($dir);
2688 }
2689
2690 sub quotify {
2691     my %processors = (
2692         perl    => sub { my $x = shift;
2693                          $x =~ s/([\\\$\@"])/\\$1/g;
2694                          return '"'.$x.'"'; },
2695         maybeshell => sub { my $x = shift;
2696                             (my $y = $x) =~ s/([\\\"])/\\$1/g;
2697                             if ($x ne $y || $x =~ m|\s|) {
2698                                 return '"'.$y.'"';
2699                             } else {
2700                                 return $x;
2701                             }
2702                         },
2703         );
2704     my $for = shift;
2705     my $processor =
2706         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2707
2708     return map { $processor->($_); } @_;
2709 }
2710
2711 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2712 # $filename is a file name to read from
2713 # $line_concat_cond_re is a regexp detecting a line continuation ending
2714 # $line_concat is a CODEref that takes care of concatenating two lines
2715 sub collect_from_file {
2716     my $filename = shift;
2717     my $line_concat_cond_re = shift;
2718     my $line_concat = shift;
2719
2720     open my $fh, $filename || die "unable to read $filename: $!\n";
2721     return sub {
2722         my $saved_line = "";
2723         $_ = "";
2724         while (<$fh>) {
2725             s|\R$||;
2726             if (defined $line_concat) {
2727                 $_ = $line_concat->($saved_line, $_);
2728                 $saved_line = "";
2729             }
2730             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2731                 $saved_line = $_;
2732                 next;
2733             }
2734             return $_;
2735         }
2736         die "$filename ending with continuation line\n" if $_;
2737         close $fh;
2738         return undef;
2739     }
2740 }
2741
2742 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2743 # $array is an ARRAYref of lines
2744 # $line_concat_cond_re is a regexp detecting a line continuation ending
2745 # $line_concat is a CODEref that takes care of concatenating two lines
2746 sub collect_from_array {
2747     my $array = shift;
2748     my $line_concat_cond_re = shift;
2749     my $line_concat = shift;
2750     my @array = (@$array);
2751
2752     return sub {
2753         my $saved_line = "";
2754         $_ = "";
2755         while (defined($_ = shift @array)) {
2756             s|\R$||;
2757             if (defined $line_concat) {
2758                 $_ = $line_concat->($saved_line, $_);
2759                 $saved_line = "";
2760             }
2761             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2762                 $saved_line = $_;
2763                 next;
2764             }
2765             return $_;
2766         }
2767         die "input text ending with continuation line\n" if $_;
2768         return undef;
2769     }
2770 }
2771
2772 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2773 # $lineiterator is a CODEref that delivers one line at a time.
2774 # All following arguments are regex/CODEref pairs, where the regexp detects a
2775 # line and the CODEref does something with the result of the regexp.
2776 sub collect_information {
2777     my $lineiterator = shift;
2778     my %collectors = @_;
2779
2780     while(defined($_ = $lineiterator->())) {
2781         s|\R$||;
2782         my $found = 0;
2783         if ($collectors{"BEFORE"}) {
2784             $collectors{"BEFORE"}->($_);
2785         }
2786         foreach my $re (keys %collectors) {
2787             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2788                 $collectors{$re}->($lineiterator);
2789                 $found = 1;
2790             };
2791         }
2792         if ($collectors{"OTHERWISE"}) {
2793             $collectors{"OTHERWISE"}->($lineiterator, $_)
2794                 unless $found || !defined $collectors{"OTHERWISE"};
2795         }
2796         if ($collectors{"AFTER"}) {
2797             $collectors{"AFTER"}->($_);
2798         }
2799     }
2800 }
2801
2802 # tokenize($line)
2803 # $line is a line of text to split up into tokens
2804 # returns a list of tokens
2805 #
2806 # Tokens are divided by spaces.  If the tokens include spaces, they
2807 # have to be quoted with single or double quotes.  Double quotes
2808 # inside a double quoted token must be escaped.  Escaping is done
2809 # with backslash.
2810 # Basically, the same quoting rules apply for " and ' as in any
2811 # Unix shell.
2812 sub tokenize {
2813     my $line = my $debug_line = shift;
2814     my @result = ();
2815
2816     while ($line =~ s|^\s+||, $line ne "") {
2817         my $token = "";
2818         while ($line ne "" && $line !~ m|^\s|) {
2819             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2820                 $token .= $1;
2821                 $line = $';
2822             } elsif ($line =~ m/^'([^']*)'/) {
2823                 $token .= $1;
2824                 $line = $';
2825             } elsif ($line =~ m/^(\S+)/) {
2826                 $token .= $1;
2827                 $line = $';
2828             }
2829         }
2830         push @result, $token;
2831     }
2832
2833     if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2834         print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2835         print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
2836     }
2837     return @result;
2838 }