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