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