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