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