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