Configure: Add read_eval_file, a general purpose perl file reader/evaluator
[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 = compiler_predefined($target{cc});
1239
1240 if (!$disabled{makedepend}) {
1241     # We know that GNU C version 3 and up as well as all clang
1242     # versions support dependency generation
1243     if ($predefined{__GNUC__} >= 3) {
1244         $config{makedepprog} = "\$(CROSS_COMPILE)$target{cc}";
1245     } else {
1246         $config{makedepprog} = which('makedepend');
1247         $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1248     }
1249 }
1250
1251
1252 # Deal with bn_ops ###################################################
1253
1254 $config{bn_ll}                  =0;
1255 $config{export_var_as_fn}       =0;
1256 my $def_int="unsigned int";
1257 $config{rc4_int}                =$def_int;
1258 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1259
1260 my $count = 0;
1261 foreach (sort split(/\s+/,$target{bn_ops})) {
1262     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1263     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1264     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1265     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1266     ($config{b64l},$config{b64},$config{b32})
1267         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1268     ($config{b64l},$config{b64},$config{b32})
1269         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1270     ($config{b64l},$config{b64},$config{b32})
1271         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1272 }
1273 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1274     if $count > 1;
1275
1276
1277 # Hack cflags for better warnings (dev option) #######################
1278
1279 # "Stringify" the C flags string.  This permits it to be made part of a string
1280 # and works as well on command lines.
1281 $config{cflags} =~ s/([\\\"])/\\$1/g;
1282
1283 if (defined($config{api})) {
1284     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1285     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1286     push @{$config{defines}}, $apiflag;
1287 }
1288
1289 if (defined($predefined{__clang__}) && !$disabled{asm}) {
1290     $config{cflags} .= " -Qunused-arguments";
1291 }
1292
1293 if ($strict_warnings)
1294         {
1295         my $wopt;
1296         my $gccver = $predefined{__GNUC__} // -1;
1297
1298         die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
1299             unless $gccver >= 4;
1300         $gcc_devteam_warn .= " -Wmisleading-indentation" if $gccver >= 6;
1301         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1302                 {
1303                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1304                 }
1305         if (defined($predefined{__clang__}))
1306                 {
1307                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1308                         {
1309                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1310                         }
1311                 }
1312         }
1313
1314 unless ($disabled{"crypto-mdebug-backtrace"})
1315         {
1316         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1317                 {
1318                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1319                 }
1320         if ($target =~ /^BSD-/)
1321                 {
1322                 $config{ex_libs} .= " -lexecinfo";
1323                 }
1324         }
1325
1326 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; $config{cxxflags}="$config{cxxflags}$user_cflags";}
1327 else                    { $no_user_cflags=1;  }
1328 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1329 else               { $no_user_defines=1;    }
1330
1331 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1332
1333 unless ($disabled{afalgeng}) {
1334     $config{afalgeng}="";
1335     if ($target =~ m/^linux/) {
1336         my $minver = 4*10000 + 1*100 + 0;
1337         if ($config{cross_compile_prefix} eq "") {
1338             my $verstr = `uname -r`;
1339             my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1340             ($mi2) = $mi2 =~ /(\d+)/;
1341             my $ver = $ma*10000 + $mi1*100 + $mi2;
1342             if ($ver < $minver) {
1343                 $disabled{afalgeng} = "too-old-kernel";
1344             } else {
1345                 push @{$config{engdirs}}, "afalg";
1346             }
1347         } else {
1348             $disabled{afalgeng} = "cross-compiling";
1349         }
1350     } else {
1351         $disabled{afalgeng}  = "not-linux";
1352     }
1353 }
1354
1355 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1356
1357 # If we use the unified build, collect information from build.info files
1358 my %unified_info = ();
1359
1360 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1361 if ($builder eq "unified") {
1362     use with_fallback qw(Text::Template);
1363
1364     sub cleandir {
1365         my $base = shift;
1366         my $dir = shift;
1367         my $relativeto = shift || ".";
1368
1369         $dir = catdir($base,$dir) unless isabsolute($dir);
1370
1371         # Make sure the directories we're building in exists
1372         mkpath($dir);
1373
1374         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1375         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1376         return $res;
1377     }
1378
1379     sub cleanfile {
1380         my $base = shift;
1381         my $file = shift;
1382         my $relativeto = shift || ".";
1383
1384         $file = catfile($base,$file) unless isabsolute($file);
1385
1386         my $d = dirname($file);
1387         my $f = basename($file);
1388
1389         # Make sure the directories we're building in exists
1390         mkpath($d);
1391
1392         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1393         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1394         return $res;
1395     }
1396
1397     # Store the name of the template file we will build the build file from
1398     # in %config.  This may be useful for the build file itself.
1399     my @build_file_template_names =
1400         ( $builder_platform."-".$target{build_file}.".tmpl",
1401           $target{build_file}.".tmpl" );
1402     my @build_file_templates = ();
1403
1404     # First, look in the user provided directory, if given
1405     if (defined env($local_config_envname)) {
1406         @build_file_templates =
1407             map {
1408                 if ($^O eq 'VMS') {
1409                     # VMS environment variables are logical names,
1410                     # which can be used as is
1411                     $local_config_envname . ':' . $_;
1412                 } else {
1413                     catfile(env($local_config_envname), $_);
1414                 }
1415             }
1416             @build_file_template_names;
1417     }
1418     # Then, look in our standard directory
1419     push @build_file_templates,
1420         ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1421           @build_file_template_names );
1422
1423     my $build_file_template;
1424     for $_ (@build_file_templates) {
1425         $build_file_template = $_;
1426         last if -f $build_file_template;
1427
1428         $build_file_template = undef;
1429     }
1430     if (!defined $build_file_template) {
1431         die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1432     }
1433     $config{build_file_templates}
1434       = [ $build_file_template,
1435           cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1436                     $blddir) ];
1437
1438     my @build_infos = ( [ ".", "build.info" ] );
1439     foreach (@{$config{dirs}}) {
1440         push @build_infos, [ $_, "build.info" ]
1441             if (-f catfile($srcdir, $_, "build.info"));
1442     }
1443     foreach (@{$config{sdirs}}) {
1444         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1445             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1446     }
1447     foreach (@{$config{engdirs}}) {
1448         push @build_infos, [ catdir("engines", $_), "build.info" ]
1449             if (-f catfile($srcdir, "engines", $_, "build.info"));
1450     }
1451     foreach (@{$config{tdirs}}) {
1452         push @build_infos, [ catdir("test", $_), "build.info" ]
1453             if (-f catfile($srcdir, "test", $_, "build.info"));
1454     }
1455
1456     $config{build_infos} = [ ];
1457
1458     foreach (@build_infos) {
1459         my $sourced = catdir($srcdir, $_->[0]);
1460         my $buildd = catdir($blddir, $_->[0]);
1461
1462         mkpath($buildd);
1463
1464         my $f = $_->[1];
1465         # The basic things we're trying to build
1466         my @programs = ();
1467         my @programs_install = ();
1468         my @libraries = ();
1469         my @libraries_install = ();
1470         my @engines = ();
1471         my @engines_install = ();
1472         my @scripts = ();
1473         my @scripts_install = ();
1474         my @extra = ();
1475         my @overrides = ();
1476         my @intermediates = ();
1477         my @rawlines = ();
1478
1479         my %ordinals = ();
1480         my %sources = ();
1481         my %shared_sources = ();
1482         my %includes = ();
1483         my %depends = ();
1484         my %renames = ();
1485         my %sharednames = ();
1486         my %generate = ();
1487
1488         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1489         my $template =
1490             Text::Template->new(TYPE => 'FILE',
1491                                 SOURCE => catfile($sourced, $f),
1492                                 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
1493         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1494         my @text =
1495             split /^/m,
1496             $template->fill_in(HASH => { config => \%config,
1497                                          target => \%target,
1498                                          disabled => \%disabled,
1499                                          withargs => \%withargs,
1500                                          builddir => abs2rel($buildd, $blddir),
1501                                          sourcedir => abs2rel($sourced, $blddir),
1502                                          buildtop => abs2rel($blddir, $blddir),
1503                                          sourcetop => abs2rel($srcdir, $blddir) },
1504                                DELIMITERS => [ "{-", "-}" ]);
1505
1506         # The top item of this stack has the following values
1507         # -2 positive already run and we found ELSE (following ELSIF should fail)
1508         # -1 positive already run (skip until ENDIF)
1509         # 0 negatives so far (if we're at a condition, check it)
1510         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1511         # 2 positive ELSE (following ELSIF should fail)
1512         my @skip = ();
1513         collect_information(
1514             collect_from_array([ @text ],
1515                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1516                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1517             # Info we're looking for
1518             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1519             => sub {
1520                 if (! @skip || $skip[$#skip] > 0) {
1521                     push @skip, !! $1;
1522                 } else {
1523                     push @skip, -1;
1524                 }
1525             },
1526             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1527             => sub { die "ELSIF out of scope" if ! @skip;
1528                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1529                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1530                      $skip[$#skip] = !! $1
1531                          if $skip[$#skip] == 0; },
1532             qr/^\s*ELSE\s*$/
1533             => sub { die "ELSE out of scope" if ! @skip;
1534                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1535                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1536             qr/^\s*ENDIF\s*$/
1537             => sub { die "ENDIF out of scope" if ! @skip;
1538                      pop @skip; },
1539             qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1540             => sub {
1541                 if (!@skip || $skip[$#skip] > 0) {
1542                     my $install = $1;
1543                     my @x = tokenize($2);
1544                     push @programs, @x;
1545                     push @programs_install, @x unless $install;
1546                 }
1547             },
1548             qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1549             => sub {
1550                 if (!@skip || $skip[$#skip] > 0) {
1551                     my $install = $1;
1552                     my @x = tokenize($2);
1553                     push @libraries, @x;
1554                     push @libraries_install, @x unless $install;
1555                 }
1556             },
1557             qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1558             => sub {
1559                 if (!@skip || $skip[$#skip] > 0) {
1560                     my $install = $1;
1561                     my @x = tokenize($2);
1562                     push @engines, @x;
1563                     push @engines_install, @x unless $install;
1564                 }
1565             },
1566             qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1567             => sub {
1568                 if (!@skip || $skip[$#skip] > 0) {
1569                     my $install = $1;
1570                     my @x = tokenize($2);
1571                     push @scripts, @x;
1572                     push @scripts_install, @x unless $install;
1573                 }
1574             },
1575             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1576             => sub { push @extra, tokenize($1)
1577                          if !@skip || $skip[$#skip] > 0 },
1578             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1579             => sub { push @overrides, tokenize($1)
1580                          if !@skip || $skip[$#skip] > 0 },
1581
1582             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1583             => sub { push @{$ordinals{$1}}, tokenize($2)
1584                          if !@skip || $skip[$#skip] > 0 },
1585             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1586             => sub { push @{$sources{$1}}, tokenize($2)
1587                          if !@skip || $skip[$#skip] > 0 },
1588             qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1589             => sub { push @{$shared_sources{$1}}, tokenize($2)
1590                          if !@skip || $skip[$#skip] > 0 },
1591             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1592             => sub { push @{$includes{$1}}, tokenize($2)
1593                          if !@skip || $skip[$#skip] > 0 },
1594             qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
1595             => sub { push @{$depends{$1}}, tokenize($2)
1596                          if !@skip || $skip[$#skip] > 0 },
1597             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1598             => sub { push @{$generate{$1}}, $2
1599                          if !@skip || $skip[$#skip] > 0 },
1600             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1601             => sub { push @{$renames{$1}}, tokenize($2)
1602                          if !@skip || $skip[$#skip] > 0 },
1603             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1604             => sub { push @{$sharednames{$1}}, tokenize($2)
1605                          if !@skip || $skip[$#skip] > 0 },
1606             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1607             => sub {
1608                 my $lineiterator = shift;
1609                 my $target_kind = $1;
1610                 while (defined $lineiterator->()) {
1611                     s|\R$||;
1612                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1613                         die "ENDRAW doesn't match BEGINRAW"
1614                             if $1 ne $target_kind;
1615                         last;
1616                     }
1617                     next if @skip && $skip[$#skip] <= 0;
1618                     push @rawlines,  $_
1619                         if ($target_kind eq $target{build_file}
1620                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1621                 }
1622             },
1623             qr/^\s*(?:#.*)?$/ => sub { },
1624             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1625             "BEFORE" => sub {
1626                 if ($buildinfo_debug) {
1627                     print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1628                     print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1629                 }
1630             },
1631             "AFTER" => sub {
1632                 if ($buildinfo_debug) {
1633                     print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1634                 }
1635             },
1636             );
1637         die "runaway IF?" if (@skip);
1638
1639         foreach (keys %renames) {
1640             die "$_ renamed to more than one thing: "
1641                 ,join(" ", @{$renames{$_}}),"\n"
1642                 if scalar @{$renames{$_}} > 1;
1643             my $dest = cleanfile($buildd, $_, $blddir);
1644             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1645             die "$dest renamed to more than one thing: "
1646                 ,$unified_info{rename}->{$dest}, $to
1647                 unless !defined($unified_info{rename}->{$dest})
1648                 or $unified_info{rename}->{$dest} eq $to;
1649             $unified_info{rename}->{$dest} = $to;
1650         }
1651
1652         foreach (@programs) {
1653             my $program = cleanfile($buildd, $_, $blddir);
1654             if ($unified_info{rename}->{$program}) {
1655                 $program = $unified_info{rename}->{$program};
1656             }
1657             $unified_info{programs}->{$program} = 1;
1658         }
1659
1660         foreach (@programs_install) {
1661             my $program = cleanfile($buildd, $_, $blddir);
1662             if ($unified_info{rename}->{$program}) {
1663                 $program = $unified_info{rename}->{$program};
1664             }
1665             $unified_info{install}->{programs}->{$program} = 1;
1666         }
1667
1668         foreach (@libraries) {
1669             my $library = cleanfile($buildd, $_, $blddir);
1670             if ($unified_info{rename}->{$library}) {
1671                 $library = $unified_info{rename}->{$library};
1672             }
1673             $unified_info{libraries}->{$library} = 1;
1674         }
1675
1676         foreach (@libraries_install) {
1677             my $library = cleanfile($buildd, $_, $blddir);
1678             if ($unified_info{rename}->{$library}) {
1679                 $library = $unified_info{rename}->{$library};
1680             }
1681             $unified_info{install}->{libraries}->{$library} = 1;
1682         }
1683
1684         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1685 ENGINES can only be used if configured with 'dynamic-engine'.
1686 This is usually a fault in a build.info file.
1687 EOF
1688         foreach (@engines) {
1689             my $library = cleanfile($buildd, $_, $blddir);
1690             if ($unified_info{rename}->{$library}) {
1691                 $library = $unified_info{rename}->{$library};
1692             }
1693             $unified_info{engines}->{$library} = 1;
1694         }
1695
1696         foreach (@engines_install) {
1697             my $library = cleanfile($buildd, $_, $blddir);
1698             if ($unified_info{rename}->{$library}) {
1699                 $library = $unified_info{rename}->{$library};
1700             }
1701             $unified_info{install}->{engines}->{$library} = 1;
1702         }
1703
1704         foreach (@scripts) {
1705             my $script = cleanfile($buildd, $_, $blddir);
1706             if ($unified_info{rename}->{$script}) {
1707                 $script = $unified_info{rename}->{$script};
1708             }
1709             $unified_info{scripts}->{$script} = 1;
1710         }
1711
1712         foreach (@scripts_install) {
1713             my $script = cleanfile($buildd, $_, $blddir);
1714             if ($unified_info{rename}->{$script}) {
1715                 $script = $unified_info{rename}->{$script};
1716             }
1717             $unified_info{install}->{scripts}->{$script} = 1;
1718         }
1719
1720         foreach (@extra) {
1721             my $extra = cleanfile($buildd, $_, $blddir);
1722             $unified_info{extra}->{$extra} = 1;
1723         }
1724
1725         foreach (@overrides) {
1726             my $override = cleanfile($buildd, $_, $blddir);
1727             $unified_info{overrides}->{$override} = 1;
1728         }
1729
1730         push @{$unified_info{rawlines}}, @rawlines;
1731
1732         unless ($disabled{shared}) {
1733             # Check sharednames.
1734             foreach (keys %sharednames) {
1735                 my $dest = cleanfile($buildd, $_, $blddir);
1736                 if ($unified_info{rename}->{$dest}) {
1737                     $dest = $unified_info{rename}->{$dest};
1738                 }
1739                 die "shared_name for $dest with multiple values: "
1740                     ,join(" ", @{$sharednames{$_}}),"\n"
1741                     if scalar @{$sharednames{$_}} > 1;
1742                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1743                 die "shared_name found for a library $dest that isn't defined\n"
1744                     unless $unified_info{libraries}->{$dest};
1745                 die "shared_name for $dest with multiple values: "
1746                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1747                     unless !defined($unified_info{sharednames}->{$dest})
1748                     or $unified_info{sharednames}->{$dest} eq $to;
1749                 $unified_info{sharednames}->{$dest} = $to;
1750             }
1751
1752             # Additionally, we set up sharednames for libraries that don't
1753             # have any, as themselves.  Only for libraries that aren't
1754             # explicitly static.
1755             foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) {
1756                 if (!defined $unified_info{sharednames}->{$_}) {
1757                     $unified_info{sharednames}->{$_} = $_
1758                 }
1759             }
1760
1761             # Check that we haven't defined any library as both shared and
1762             # explicitly static.  That is forbidden.
1763             my @doubles = ();
1764             foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
1765                 (my $l = $_) =~ s/\.a$//;
1766                 push @doubles, $l if defined $unified_info{sharednames}->{$l};
1767             }
1768             die "these libraries are both explicitly static and shared:\n  ",
1769                 join(" ", @doubles), "\n"
1770                 if @doubles;
1771         }
1772
1773         foreach (keys %ordinals) {
1774             my $dest = $_;
1775             my $ddest = cleanfile($buildd, $_, $blddir);
1776             if ($unified_info{rename}->{$ddest}) {
1777                 $ddest = $unified_info{rename}->{$ddest};
1778             }
1779             foreach (@{$ordinals{$dest}}) {
1780                 my %known_ordinals =
1781                     (
1782                      crypto =>
1783                      cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1784                      ssl =>
1785                      cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1786                     );
1787                 my $o = $known_ordinals{$_};
1788                 die "Ordinals for $ddest defined more than once\n"
1789                     if $unified_info{ordinals}->{$ddest};
1790                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1791             }
1792         }
1793
1794         foreach (keys %sources) {
1795             my $dest = $_;
1796             my $ddest = cleanfile($buildd, $_, $blddir);
1797             if ($unified_info{rename}->{$ddest}) {
1798                 $ddest = $unified_info{rename}->{$ddest};
1799             }
1800             foreach (@{$sources{$dest}}) {
1801                 my $s = cleanfile($sourced, $_, $blddir);
1802
1803                 # If it isn't in the source tree, we assume it's generated
1804                 # in the build tree
1805                 if (! -f $s) {
1806                     $s = cleanfile($buildd, $_, $blddir);
1807                 }
1808                 # We recognise C++, C and asm files
1809                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1810                     my $o = $_;
1811                     $o =~ s/\.[csS]$/.o/; # C and assembler
1812                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1813                     $o = cleanfile($buildd, $o, $blddir);
1814                     $unified_info{sources}->{$ddest}->{$o} = 1;
1815                     $unified_info{sources}->{$o}->{$s} = 1;
1816                 } else {
1817                     $unified_info{sources}->{$ddest}->{$s} = 1;
1818                 }
1819             }
1820         }
1821
1822         foreach (keys %shared_sources) {
1823             my $dest = $_;
1824             my $ddest = cleanfile($buildd, $_, $blddir);
1825             if ($unified_info{rename}->{$ddest}) {
1826                 $ddest = $unified_info{rename}->{$ddest};
1827             }
1828             foreach (@{$shared_sources{$dest}}) {
1829                 my $s = cleanfile($sourced, $_, $blddir);
1830
1831                 # If it isn't in the source tree, we assume it's generated
1832                 # in the build tree
1833                 if (! -f $s) {
1834                     $s = cleanfile($buildd, $_, $blddir);
1835                 }
1836                 # We recognise C++, C and asm files
1837                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1838                     my $o = $_;
1839                     $o =~ s/\.[csS]$/.o/; # C and assembler
1840                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1841                     $o = cleanfile($buildd, $o, $blddir);
1842                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1843                     $unified_info{sources}->{$o}->{$s} = 1;
1844                 } else {
1845                     die "unrecognised source file type for shared library: $s\n";
1846                 }
1847             }
1848         }
1849
1850         foreach (keys %generate) {
1851             my $dest = $_;
1852             my $ddest = cleanfile($buildd, $_, $blddir);
1853             if ($unified_info{rename}->{$ddest}) {
1854                 $ddest = $unified_info{rename}->{$ddest};
1855             }
1856             die "more than one generator for $dest: "
1857                     ,join(" ", @{$generate{$_}}),"\n"
1858                     if scalar @{$generate{$_}} > 1;
1859             my @generator = split /\s+/, $generate{$dest}->[0];
1860             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1861             $unified_info{generate}->{$ddest} = [ @generator ];
1862         }
1863
1864         foreach (keys %depends) {
1865             my $dest = $_;
1866             my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
1867
1868             # If the destination doesn't exist in source, it can only be
1869             # a generated file in the build tree.
1870             if ($ddest ne "" && ! -f $ddest) {
1871                 $ddest = cleanfile($buildd, $_, $blddir);
1872                 if ($unified_info{rename}->{$ddest}) {
1873                     $ddest = $unified_info{rename}->{$ddest};
1874                 }
1875             }
1876             foreach (@{$depends{$dest}}) {
1877                 my $d = cleanfile($sourced, $_, $blddir);
1878
1879                 # If we know it's generated, or assume it is because we can't
1880                 # find it in the source tree, we set file we depend on to be
1881                 # in the build tree rather than the source tree, and assume
1882                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1883                 # section or in the Makefile template.
1884                 if (! -f $d
1885                     || (grep { $d eq $_ }
1886                         map { cleanfile($srcdir, $_, $blddir) }
1887                         grep { /\.h$/ } keys %{$unified_info{generate}})) {
1888                     $d = cleanfile($buildd, $_, $blddir);
1889                 }
1890                 # Take note if the file to depend on is being renamed
1891                 # Take extra care with files ending with .a, they should
1892                 # be treated without that extension, and the extension
1893                 # should be added back after treatment.
1894                 $d =~ /(\.a)?$/;
1895                 my $e = $1 // "";
1896                 $d = $`;
1897                 if ($unified_info{rename}->{$d}) {
1898                     $d = $unified_info{rename}->{$d};
1899                 }
1900                 $d .= $e;
1901                 $unified_info{depends}->{$ddest}->{$d} = 1;
1902                 # If we depend on a header file or a perl module, let's make
1903                 # sure it can get included
1904                 if ($dest ne "" && $d =~ /\.(h|pm)$/) {
1905                     my $i = dirname($d);
1906                     push @{$unified_info{includes}->{$ddest}->{source}}, $i
1907                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}};
1908                 }
1909             }
1910         }
1911
1912         foreach (keys %includes) {
1913             my $dest = $_;
1914             my $ddest = cleanfile($sourced, $_, $blddir);
1915
1916             # If the destination doesn't exist in source, it can only be
1917             # a generated file in the build tree.
1918             if (! -f $ddest) {
1919                 $ddest = cleanfile($buildd, $_, $blddir);
1920                 if ($unified_info{rename}->{$ddest}) {
1921                     $ddest = $unified_info{rename}->{$ddest};
1922                 }
1923             }
1924             foreach (@{$includes{$dest}}) {
1925                 my $is = cleandir($sourced, $_, $blddir);
1926                 my $ib = cleandir($buildd, $_, $blddir);
1927                 push @{$unified_info{includes}->{$ddest}->{source}}, $is
1928                     unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
1929                 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
1930                     unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
1931             }
1932         }
1933     }
1934
1935     ### Make unified_info a bit more efficient
1936     # One level structures
1937     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1938         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1939     }
1940     # Two level structures
1941     foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
1942         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1943             $unified_info{$l1}->{$l2} =
1944                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1945         }
1946     }
1947     # Includes
1948     foreach my $dest (sort keys %{$unified_info{includes}}) {
1949         if (defined($unified_info{includes}->{$dest}->{build})) {
1950             my @source_includes =
1951                 ( @{$unified_info{includes}->{$dest}->{source}} );
1952             $unified_info{includes}->{$dest} =
1953                 [ @{$unified_info{includes}->{$dest}->{build}} ];
1954             foreach my $inc (@source_includes) {
1955                 push @{$unified_info{includes}->{$dest}}, $inc
1956                     unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
1957             }
1958         } else {
1959             $unified_info{includes}->{$dest} =
1960                 [ @{$unified_info{includes}->{$dest}->{source}} ];
1961         }
1962     }
1963 }
1964
1965 # For the schemes that need it, we provide the old *_obj configs
1966 # from the *_asm_obj ones
1967 foreach (grep /_(asm|aux)_src$/, keys %target) {
1968     my $src = $_;
1969     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1970     $target{$obj} = $target{$src};
1971     $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
1972     $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
1973 }
1974
1975 # Write down our configuration where it fits #########################
1976
1977 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1978 print OUT <<"EOF";
1979 package configdata;
1980
1981 use strict;
1982 use warnings;
1983
1984 use Exporter;
1985 #use vars qw(\@ISA \@EXPORT);
1986 our \@ISA = qw(Exporter);
1987 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
1988
1989 EOF
1990 print OUT "our %config = (\n";
1991 foreach (sort keys %config) {
1992     if (ref($config{$_}) eq "ARRAY") {
1993         print OUT "  ", $_, " => [ ", join(", ",
1994                                            map { quotify("perl", $_) }
1995                                            @{$config{$_}}), " ],\n";
1996     } elsif (ref($config{$_}) eq "HASH") {
1997         print OUT "  ", $_, " => {";
1998         if (scalar keys %{$config{$_}} > 0) {
1999             print OUT "\n";
2000             foreach my $key (sort keys %{$config{$_}}) {
2001                 print OUT "      ",
2002                     join(" => ",
2003                          quotify("perl", $key),
2004                          defined $config{$_}->{$key}
2005                              ? quotify("perl", $config{$_}->{$key})
2006                              : "undef");
2007                 print OUT ",\n";
2008             }
2009             print OUT "  ";
2010         }
2011         print OUT "},\n";
2012     } else {
2013         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
2014     }
2015 }
2016 print OUT <<"EOF";
2017 );
2018
2019 EOF
2020 print OUT "our %target = (\n";
2021 foreach (sort keys %target) {
2022     if (ref($target{$_}) eq "ARRAY") {
2023         print OUT "  ", $_, " => [ ", join(", ",
2024                                            map { quotify("perl", $_) }
2025                                            @{$target{$_}}), " ],\n";
2026     } else {
2027         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
2028     }
2029 }
2030 print OUT <<"EOF";
2031 );
2032
2033 EOF
2034 print OUT "our \%available_protocols = (\n";
2035 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
2036 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
2037 print OUT <<"EOF";
2038 );
2039
2040 EOF
2041 print OUT "our \@disablables = (\n";
2042 foreach (@disablables) {
2043     print OUT "  ", quotify("perl", $_), ",\n";
2044 }
2045 print OUT <<"EOF";
2046 );
2047
2048 EOF
2049 print OUT "our \%disabled = (\n";
2050 foreach (sort keys %disabled) {
2051     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
2052 }
2053 print OUT <<"EOF";
2054 );
2055
2056 EOF
2057 print OUT "our %withargs = (\n";
2058 foreach (sort keys %withargs) {
2059     if (ref($withargs{$_}) eq "ARRAY") {
2060         print OUT "  ", $_, " => [ ", join(", ",
2061                                            map { quotify("perl", $_) }
2062                                            @{$withargs{$_}}), " ],\n";
2063     } else {
2064         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
2065     }
2066 }
2067 print OUT <<"EOF";
2068 );
2069
2070 EOF
2071 if ($builder eq "unified") {
2072     my $recurse;
2073     $recurse = sub {
2074         my $indent = shift;
2075         foreach (@_) {
2076             if (ref $_ eq "ARRAY") {
2077                 print OUT " "x$indent, "[\n";
2078                 foreach (@$_) {
2079                     $recurse->($indent + 4, $_);
2080                 }
2081                 print OUT " "x$indent, "],\n";
2082             } elsif (ref $_ eq "HASH") {
2083                 my %h = %$_;
2084                 print OUT " "x$indent, "{\n";
2085                 foreach (sort keys %h) {
2086                     if (ref $h{$_} eq "") {
2087                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
2088                     } else {
2089                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
2090                         $recurse->($indent + 8, $h{$_});
2091                     }
2092                 }
2093                 print OUT " "x$indent, "},\n";
2094             } else {
2095                 print OUT " "x$indent, quotify("perl", $_), ",\n";
2096             }
2097         }
2098     };
2099     print OUT "our %unified_info = (\n";
2100     foreach (sort keys %unified_info) {
2101         if (ref $unified_info{$_} eq "") {
2102             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
2103         } else {
2104             print OUT " "x4, quotify("perl", $_), " =>\n";
2105             $recurse->(8, $unified_info{$_});
2106         }
2107     }
2108     print OUT <<"EOF";
2109 );
2110
2111 EOF
2112 }
2113 print OUT "1;\n";
2114 close(OUT);
2115
2116 print "\n";
2117 print "PROCESSOR     =$config{processor}\n" if $config{processor};
2118 print "PERL          =$config{perl}\n";
2119 print "PERLVERSION   =$Config{version} for $Config{archname}\n";
2120 print "HASHBANGPERL  =$config{hashbangperl}\n";
2121 print "CC            =$config{cross_compile_prefix}$target{cc}\n";
2122 print "CFLAG         =$target{cflags} $config{cflags}\n";
2123 print "CXX           =$config{cross_compile_prefix}$target{cxx}\n"
2124     if defined $target{cxx};
2125 print "CXXFLAG       =$target{cxxflags} $config{cxxflags}\n"
2126     if defined $target{cxx};
2127 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
2128 #print "RANLIB        =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
2129 #                             "$config{cross_compile_prefix}ranlib" :
2130 #                             "$target{ranlib}", "\n";
2131 print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
2132
2133 my %builders = (
2134     unified => sub {
2135         run_dofile(catfile($blddir, $target{build_file}),
2136                    @{$config{build_file_templates}});
2137     },
2138     );
2139
2140 $builders{$builder}->($builder_platform, @builder_opts);
2141
2142 print <<"EOF" if ($disabled{threads} eq "unavailable");
2143
2144 The library could not be configured for supporting multi-threaded
2145 applications as the compiler options required on this system are not known.
2146 See file INSTALL for details if you need multi-threading.
2147 EOF
2148
2149 print <<"EOF" if ($no_shared_warn);
2150
2151 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2152 platform, so we will pretend you gave the option 'no-pic', which also disables
2153 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
2154 or position independent code, please let us know (but please first make sure
2155 you have tried with a current version of OpenSSL).
2156 EOF
2157
2158 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2159
2160 WARNING: there are indications that another build was made in the source
2161 directory.  This build may have picked up artifacts from that build, the
2162 safest course of action is to clean the source directory and redo this
2163 configuration.
2164 EOF
2165
2166 exit(0);
2167
2168 ######################################################################
2169 #
2170 # Helpers and utility functions
2171 #
2172
2173 # Configuration file reading #########################################
2174
2175 # Note: All of the helper functions are for lazy evaluation.  They all
2176 # return a CODE ref, which will return the intended value when evaluated.
2177 # Thus, whenever there's mention of a returned value, it's about that
2178 # intended value.
2179
2180 # Helper function to implement conditional inheritance depending on the
2181 # value of $disabled{asm}.  Used in inherit_from values as follows:
2182 #
2183 #      inherit_from => [ "template", asm("asm_tmpl") ]
2184 #
2185 sub asm {
2186     my @x = @_;
2187     sub {
2188         $disabled{asm} ? () : @x;
2189     }
2190 }
2191
2192 # Helper function to implement conditional value variants, with a default
2193 # plus additional values based on the value of $config{build_type}.
2194 # Arguments are given in hash table form:
2195 #
2196 #       picker(default => "Basic string: ",
2197 #              debug   => "debug",
2198 #              release => "release")
2199 #
2200 # When configuring with --debug, the resulting string will be
2201 # "Basic string: debug", and when not, it will be "Basic string: release"
2202 #
2203 # This can be used to create variants of sets of flags according to the
2204 # build type:
2205 #
2206 #       cflags => picker(default => "-Wall",
2207 #                        debug   => "-g -O0",
2208 #                        release => "-O3")
2209 #
2210 sub picker {
2211     my %opts = @_;
2212     return sub { add($opts{default} || (),
2213                      $opts{$config{build_type}} || ())->(); }
2214 }
2215
2216 # Helper function to combine several values of different types into one.
2217 # This is useful if you want to combine a string with the result of a
2218 # lazy function, such as:
2219 #
2220 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2221 #
2222 sub combine {
2223     my @stuff = @_;
2224     return sub { add(@stuff)->(); }
2225 }
2226
2227 # Helper function to implement conditional values depending on the value
2228 # of $disabled{threads}.  Can be used as follows:
2229 #
2230 #       cflags => combine("-Wall", threads("-pthread"))
2231 #
2232 sub threads {
2233     my @flags = @_;
2234     return sub { add($disabled{threads} ? () : @flags)->(); }
2235 }
2236
2237
2238
2239 our $add_called = 0;
2240 # Helper function to implement adding values to already existing configuration
2241 # values.  It handles elements that are ARRAYs, CODEs and scalars
2242 sub _add {
2243     my $separator = shift;
2244
2245     # If there's any ARRAY in the collection of values OR the separator
2246     # is undef, we will return an ARRAY of combined values, otherwise a
2247     # string of joined values with $separator as the separator.
2248     my $found_array = !defined($separator);
2249
2250     my @values =
2251         map {
2252             my $res = $_;
2253             while (ref($res) eq "CODE") {
2254                 $res = $res->();
2255             }
2256             if (defined($res)) {
2257                 if (ref($res) eq "ARRAY") {
2258                     $found_array = 1;
2259                     @$res;
2260                 } else {
2261                     $res;
2262                 }
2263             } else {
2264                 ();
2265             }
2266     } (@_);
2267
2268     $add_called = 1;
2269
2270     if ($found_array) {
2271         [ @values ];
2272     } else {
2273         join($separator, grep { defined($_) && $_ ne "" } @values);
2274     }
2275 }
2276 sub add_before {
2277     my $separator = " ";
2278     if (ref($_[$#_]) eq "HASH") {
2279         my $opts = pop;
2280         $separator = $opts->{separator};
2281     }
2282     my @x = @_;
2283     sub { _add($separator, @x, @_) };
2284 }
2285 sub add {
2286     my $separator = " ";
2287     if (ref($_[$#_]) eq "HASH") {
2288         my $opts = pop;
2289         $separator = $opts->{separator};
2290     }
2291     my @x = @_;
2292     sub { _add($separator, @_, @x) };
2293 }
2294
2295 sub read_eval_file {
2296     my $fname = shift;
2297     my $content;
2298     my @result;
2299
2300     open F, "< $fname" or die "Can't open '$fname': $!\n";
2301     {
2302         undef local $/;
2303         $content = <F>;
2304     }
2305     close F;
2306     {
2307         local $@;
2308
2309         @result = ( eval $content );
2310         warn $@ if $@;
2311     }
2312     return wantarray ? @result : $result[0];
2313 }
2314
2315 # configuration reader, evaluates the input file as a perl script and expects
2316 # it to fill %targets with target configurations.  Those are then added to
2317 # %table.
2318 sub read_config {
2319     my $fname = shift;
2320     my %targets;
2321
2322     {
2323         # Protect certain tables from tampering
2324         local %table = ();
2325
2326         %targets = read_eval_file($fname);
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 compiler_predefined {
2518     state %predefined;
2519     my $default_compiler = shift;
2520
2521     return () if $^O eq 'VMS';
2522
2523     die 'compiler_predefines called without a default compiler'
2524         unless $default_compiler;
2525
2526     if (! $predefined{$default_compiler}) {
2527         my $cc = "$config{cross_compile_prefix}$default_compiler";
2528
2529         $predefined{$default_compiler} = {};
2530
2531         # collect compiler pre-defines from gcc or gcc-alike...
2532         open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
2533         while (my $l = <PIPE>) {
2534             $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
2535             $predefined{$default_compiler}->{$1} = $2 // '';
2536         }
2537         close(PIPE);
2538     }
2539
2540     return %{$predefined{$default_compiler}};
2541 }
2542
2543 sub which
2544 {
2545     my ($name)=@_;
2546
2547     if (eval { require IPC::Cmd; 1; }) {
2548         IPC::Cmd->import();
2549         return scalar IPC::Cmd::can_run($name);
2550     } else {
2551         # if there is $directories component in splitpath,
2552         # then it's not something to test with $PATH...
2553         return $name if (File::Spec->splitpath($name))[1];
2554
2555         foreach (File::Spec->path()) {
2556             my $fullpath = catfile($_, "$name$target{exe_extension}");
2557             if (-f $fullpath and -x $fullpath) {
2558                 return $fullpath;
2559             }
2560         }
2561     }
2562 }
2563
2564 sub env
2565 {
2566     my $name = shift;
2567
2568     # Note that if $ENV{$name} doesn't exist or is undefined,
2569     # $config{perlenv}->{$name} will be created with the value
2570     # undef.  This is intentional.
2571
2572     $config{perlenv}->{$name} = $ENV{$name}
2573         if ! exists $config{perlenv}->{$name};
2574     return $config{perlenv}->{$name};
2575 }
2576
2577 # Configuration printer ##############################################
2578
2579 sub print_table_entry
2580 {
2581     my $target = shift;
2582     my %target = resolve_config($target);
2583     my $type = shift;
2584
2585     # Don't print the templates
2586     return if $target{template};
2587
2588     my @sequence = (
2589         "sys_id",
2590         "cc",
2591         "cflags",
2592         "defines",
2593         "unistd",
2594         "ld",
2595         "lflags",
2596         "loutflag",
2597         "plib_lflags",
2598         "ex_libs",
2599         "bn_ops",
2600         "apps_aux_src",
2601         "cpuid_asm_src",
2602         "uplink_aux_src",
2603         "bn_asm_src",
2604         "ec_asm_src",
2605         "des_asm_src",
2606         "aes_asm_src",
2607         "bf_asm_src",
2608         "md5_asm_src",
2609         "cast_asm_src",
2610         "sha1_asm_src",
2611         "rc4_asm_src",
2612         "rmd160_asm_src",
2613         "rc5_asm_src",
2614         "wp_asm_src",
2615         "cmll_asm_src",
2616         "modes_asm_src",
2617         "padlock_asm_src",
2618         "chacha_asm_src",
2619         "poly1035_asm_src",
2620         "thread_scheme",
2621         "perlasm_scheme",
2622         "dso_scheme",
2623         "shared_target",
2624         "shared_cflag",
2625         "shared_defines",
2626         "shared_ldflag",
2627         "shared_rcflag",
2628         "shared_extension",
2629         "dso_extension",
2630         "obj_extension",
2631         "exe_extension",
2632         "ranlib",
2633         "ar",
2634         "arflags",
2635         "aroutflag",
2636         "rc",
2637         "rcflags",
2638         "rcoutflag",
2639         "mt",
2640         "mtflags",
2641         "mtinflag",
2642         "mtoutflag",
2643         "multilib",
2644         "build_scheme",
2645         );
2646
2647     if ($type eq "TABLE") {
2648         print "\n";
2649         print "*** $target\n";
2650         foreach (@sequence) {
2651             if (ref($target{$_}) eq "ARRAY") {
2652                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2653             } else {
2654                 printf "\$%-12s = %s\n", $_, $target{$_};
2655             }
2656         }
2657     } elsif ($type eq "HASH") {
2658         my $largest =
2659             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2660         print "    '$target' => {\n";
2661         foreach (@sequence) {
2662             if ($target{$_}) {
2663                 if (ref($target{$_}) eq "ARRAY") {
2664                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2665                 } else {
2666                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2667                 }
2668             }
2669         }
2670         print "    },\n";
2671     }
2672 }
2673
2674 # Utility routines ###################################################
2675
2676 # On VMS, if the given file is a logical name, File::Spec::Functions
2677 # will consider it an absolute path.  There are cases when we want a
2678 # purely syntactic check without checking the environment.
2679 sub isabsolute {
2680     my $file = shift;
2681
2682     # On non-platforms, we just use file_name_is_absolute().
2683     return file_name_is_absolute($file) unless $^O eq "VMS";
2684
2685     # If the file spec includes a device or a directory spec,
2686     # file_name_is_absolute() is perfectly safe.
2687     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2688
2689     # Here, we know the given file spec isn't absolute
2690     return 0;
2691 }
2692
2693 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2694 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2695 # realpath() requires that at least all path components except the last is an
2696 # existing directory.  On VMS, the last component of the directory spec must
2697 # exist.
2698 sub absolutedir {
2699     my $dir = shift;
2700
2701     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2702     # will return the volume name for the device, no matter what.  Also,
2703     # it will return an incorrect directory spec if the argument is a
2704     # directory that doesn't exist.
2705     if ($^O eq "VMS") {
2706         return rel2abs($dir);
2707     }
2708
2709     # We use realpath() on Unix, since no other will properly clean out
2710     # a directory spec.
2711     use Cwd qw/realpath/;
2712
2713     return realpath($dir);
2714 }
2715
2716 sub quotify {
2717     my %processors = (
2718         perl    => sub { my $x = shift;
2719                          $x =~ s/([\\\$\@"])/\\$1/g;
2720                          return '"'.$x.'"'; },
2721         maybeshell => sub { my $x = shift;
2722                             (my $y = $x) =~ s/([\\\"])/\\$1/g;
2723                             if ($x ne $y || $x =~ m|\s|) {
2724                                 return '"'.$y.'"';
2725                             } else {
2726                                 return $x;
2727                             }
2728                         },
2729         );
2730     my $for = shift;
2731     my $processor =
2732         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2733
2734     return map { $processor->($_); } @_;
2735 }
2736
2737 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2738 # $filename is a file name to read from
2739 # $line_concat_cond_re is a regexp detecting a line continuation ending
2740 # $line_concat is a CODEref that takes care of concatenating two lines
2741 sub collect_from_file {
2742     my $filename = shift;
2743     my $line_concat_cond_re = shift;
2744     my $line_concat = shift;
2745
2746     open my $fh, $filename || die "unable to read $filename: $!\n";
2747     return sub {
2748         my $saved_line = "";
2749         $_ = "";
2750         while (<$fh>) {
2751             s|\R$||;
2752             if (defined $line_concat) {
2753                 $_ = $line_concat->($saved_line, $_);
2754                 $saved_line = "";
2755             }
2756             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2757                 $saved_line = $_;
2758                 next;
2759             }
2760             return $_;
2761         }
2762         die "$filename ending with continuation line\n" if $_;
2763         close $fh;
2764         return undef;
2765     }
2766 }
2767
2768 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2769 # $array is an ARRAYref of lines
2770 # $line_concat_cond_re is a regexp detecting a line continuation ending
2771 # $line_concat is a CODEref that takes care of concatenating two lines
2772 sub collect_from_array {
2773     my $array = shift;
2774     my $line_concat_cond_re = shift;
2775     my $line_concat = shift;
2776     my @array = (@$array);
2777
2778     return sub {
2779         my $saved_line = "";
2780         $_ = "";
2781         while (defined($_ = shift @array)) {
2782             s|\R$||;
2783             if (defined $line_concat) {
2784                 $_ = $line_concat->($saved_line, $_);
2785                 $saved_line = "";
2786             }
2787             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2788                 $saved_line = $_;
2789                 next;
2790             }
2791             return $_;
2792         }
2793         die "input text ending with continuation line\n" if $_;
2794         return undef;
2795     }
2796 }
2797
2798 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2799 # $lineiterator is a CODEref that delivers one line at a time.
2800 # All following arguments are regex/CODEref pairs, where the regexp detects a
2801 # line and the CODEref does something with the result of the regexp.
2802 sub collect_information {
2803     my $lineiterator = shift;
2804     my %collectors = @_;
2805
2806     while(defined($_ = $lineiterator->())) {
2807         s|\R$||;
2808         my $found = 0;
2809         if ($collectors{"BEFORE"}) {
2810             $collectors{"BEFORE"}->($_);
2811         }
2812         foreach my $re (keys %collectors) {
2813             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2814                 $collectors{$re}->($lineiterator);
2815                 $found = 1;
2816             };
2817         }
2818         if ($collectors{"OTHERWISE"}) {
2819             $collectors{"OTHERWISE"}->($lineiterator, $_)
2820                 unless $found || !defined $collectors{"OTHERWISE"};
2821         }
2822         if ($collectors{"AFTER"}) {
2823             $collectors{"AFTER"}->($_);
2824         }
2825     }
2826 }
2827
2828 # tokenize($line)
2829 # $line is a line of text to split up into tokens
2830 # returns a list of tokens
2831 #
2832 # Tokens are divided by spaces.  If the tokens include spaces, they
2833 # have to be quoted with single or double quotes.  Double quotes
2834 # inside a double quoted token must be escaped.  Escaping is done
2835 # with backslash.
2836 # Basically, the same quoting rules apply for " and ' as in any
2837 # Unix shell.
2838 sub tokenize {
2839     my $line = my $debug_line = shift;
2840     my @result = ();
2841
2842     while ($line =~ s|^\s+||, $line ne "") {
2843         my $token = "";
2844         while ($line ne "" && $line !~ m|^\s|) {
2845             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2846                 $token .= $1;
2847                 $line = $';
2848             } elsif ($line =~ m/^'([^']*)'/) {
2849                 $token .= $1;
2850                 $line = $';
2851             } elsif ($line =~ m/^(\S+)/) {
2852                 $token .= $1;
2853                 $line = $';
2854             }
2855         }
2856         push @result, $token;
2857     }
2858
2859     if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2860         print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2861         print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
2862     }
2863     return @result;
2864 }