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