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