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