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