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