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