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