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