6c7f2b4458601d10b4a8c1359d2f31ad4a1e987d
[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} unless defined $target{cxxflags};
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{shared_ldflag}}, "-mno-cygwin";
1197         }
1198
1199 if ($target =~ /linux.*-mips/ && !$disabled{asm}
1200         && !grep { $_ !~ /-m(ips|arch=)/ } @{$user{CFLAGS}}) {
1201         # minimally required architecture flags for assembly modules
1202         unshift @{$config{cflags}}, '-mips2' if ($target =~ /mips32/);
1203         unshift @{$config{cflags}}, '-mips3' if ($target =~ /mips64/);
1204 }
1205
1206 # The DSO code currently always implements all functions so that no
1207 # applications will have to worry about that from a compilation point
1208 # of view. However, the "method"s may return zero unless that platform
1209 # has support compiled in for them. Currently each method is enabled
1210 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
1211 # string entry into using the following logic;
1212 if (!$disabled{dso} && $target{dso_scheme} ne "")
1213         {
1214         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
1215         if ($target{dso_scheme} eq "DLFCN")
1216                 {
1217                 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
1218                 }
1219         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
1220                 {
1221                 unshift @{$config{defines}}, "DSO_DLFCN";
1222                 }
1223         else
1224                 {
1225                 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
1226                 }
1227         }
1228
1229 # If threads aren't disabled, check how possible they are
1230 unless ($disabled{threads}) {
1231     if ($auto_threads) {
1232         # Enabled by default, disable it forcibly if unavailable
1233         if ($target{thread_scheme} eq "(unknown)") {
1234             $disabled{threads} = "unavailable";
1235         }
1236     } else {
1237         # The user chose to enable threads explicitly, let's see
1238         # if there's a chance that's possible
1239         if ($target{thread_scheme} eq "(unknown)") {
1240             # If the user asked for "threads" and we don't have internal
1241             # knowledge how to do it, [s]he is expected to provide any
1242             # system-dependent compiler options that are necessary.  We
1243             # can't truly check that the given options are correct, but
1244             # we expect the user to know what [s]He is doing.
1245             if (!@{$user{CFLAGS}} && !@{$user{CPPDEFINES}}) {
1246                 die "You asked for multi-threading support, but didn't\n"
1247                     ,"provide any system-specific compiler options\n";
1248             }
1249         }
1250     }
1251 }
1252
1253 # If threads still aren't disabled, add a C macro to ensure the source
1254 # code knows about it.  Any other flag is taken care of by the configs.
1255 unless($disabled{threads}) {
1256     push @{$config{openssl_thread_defines}}, "OPENSSL_THREADS";
1257 }
1258
1259 # With "deprecated" disable all deprecated features.
1260 if (defined($disabled{"deprecated"})) {
1261         $config{api} = $maxapi;
1262 }
1263
1264 my $no_shared_warn=0;
1265 if ($target{shared_target} eq "")
1266         {
1267         $no_shared_warn = 1
1268             if (!$disabled{shared} || !$disabled{"dynamic-engine"});
1269         $disabled{shared} = "no-shared-target";
1270         $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1271             "no-shared-target";
1272         }
1273
1274 if ($disabled{"dynamic-engine"}) {
1275         push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1276         $config{dynamic_engines} = 0;
1277 } else {
1278         push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1279         $config{dynamic_engines} = 1;
1280 }
1281
1282 unless ($disabled{asan}) {
1283     push @{$config{cflags}}, "-fsanitize=address";
1284 }
1285
1286 unless ($disabled{ubsan}) {
1287     # -DPEDANTIC or -fnosanitize=alignment may also be required on some
1288     # platforms.
1289     push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all";
1290 }
1291
1292 unless ($disabled{msan}) {
1293   push @{$config{cflags}}, "-fsanitize=memory";
1294 }
1295
1296 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1297         && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1298     push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g";
1299 }
1300 #
1301 # Platform fix-ups
1302 #
1303
1304 # This saves the build files from having to check
1305 if ($disabled{pic})
1306         {
1307         foreach (qw(shared_cflag shared_cxxflag shared_cppflag
1308                     shared_defines shared_includes shared_ldflag
1309                     dso_cflags dso_cxxflags dso_cppflags
1310                     dso_defines dso_includes dso_lflags))
1311                 {
1312                 delete $config{$_};
1313                 $target{$_} = "";
1314                 }
1315         }
1316 else
1317         {
1318         push @{$config{defines}}, "OPENSSL_PIC";
1319         }
1320
1321 if ($target{sys_id} ne "")
1322         {
1323         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1324         }
1325
1326 unless ($disabled{asm}) {
1327     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1328     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1329
1330     # bn-586 is the only one implementing bn_*_part_words
1331     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1332     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1333
1334     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1335     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1336     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1337
1338     if ($target{sha1_asm_src}) {
1339         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1340         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1341         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1342     }
1343     if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
1344         push @{$config{defines}}, "RC4_ASM";
1345     }
1346     if ($target{md5_asm_src}) {
1347         push @{$config{defines}}, "MD5_ASM";
1348     }
1349     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1350     if ($target{rmd160_asm_src}) {
1351         push @{$config{defines}}, "RMD160_ASM";
1352     }
1353     if ($target{aes_asm_src}) {
1354         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1355         # aes-ctr.fake is not a real file, only indication that assembler
1356         # module implements AES_ctr32_encrypt...
1357         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1358         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1359         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1360         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1361         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1362         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1363     }
1364     if ($target{wp_asm_src} =~ /mmx/) {
1365         if ($config{processor} eq "386") {
1366             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1367         } elsif (!$disabled{"whirlpool"}) {
1368             push @{$config{defines}}, "WHIRLPOOL_ASM";
1369         }
1370     }
1371     if ($target{modes_asm_src} =~ /ghash-/) {
1372         push @{$config{defines}}, "GHASH_ASM";
1373     }
1374     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1375         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1376     }
1377     if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
1378         push @{$config{defines}}, "PADLOCK_ASM";
1379     }
1380     if ($target{poly1305_asm_src} ne "") {
1381         push @{$config{defines}}, "POLY1305_ASM";
1382     }
1383 }
1384
1385 my %predefined = compiler_predefined($config{cc});
1386
1387 # Check for makedepend capabilities.
1388 if (!$disabled{makedepend}) {
1389     if ($config{target} =~ /^(VC|vms)-/) {
1390         # For VC- and vms- targets, there's nothing more to do here.  The
1391         # functionality is hard coded in the corresponding build files for
1392         # cl (Windows) and CC/DECC (VMS).
1393     } elsif ($predefined{__GNUC__} >= 3) {
1394         # We know that GNU C version 3 and up as well as all clang
1395         # versions support dependency generation
1396         $config{makedepprog} = "\$(CROSS_COMPILE)$config{cc}";
1397     } else {
1398         # In all other cases, we look for 'makedepend', and disable the
1399         # capability if not found.
1400         $config{makedepprog} = which('makedepend');
1401         $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1402     }
1403 }
1404
1405
1406 # Deal with bn_ops ###################################################
1407
1408 $config{bn_ll}                  =0;
1409 $config{export_var_as_fn}       =0;
1410 my $def_int="unsigned int";
1411 $config{rc4_int}                =$def_int;
1412 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1413
1414 my $count = 0;
1415 foreach (sort split(/\s+/,$target{bn_ops})) {
1416     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1417     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1418     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1419     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1420     ($config{b64l},$config{b64},$config{b32})
1421         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1422     ($config{b64l},$config{b64},$config{b32})
1423         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1424     ($config{b64l},$config{b64},$config{b32})
1425         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1426 }
1427 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1428     if $count > 1;
1429
1430
1431 # Hack cflags for better warnings (dev option) #######################
1432
1433 # "Stringify" the C flags string.  This permits it to be made part of a string
1434 # and works as well on command lines.
1435 $config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1436                         @{$config{cflags}} ];
1437
1438 if (defined($config{api})) {
1439     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1440     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1441     push @{$config{defines}}, $apiflag;
1442 }
1443
1444 if (defined($predefined{__clang__}) && !$disabled{asm}) {
1445     push @{$config{cflags}}, "-Qunused-arguments";
1446 }
1447
1448 if ($strict_warnings)
1449         {
1450         my $wopt;
1451         my $gccver = $predefined{__GNUC__} // -1;
1452
1453         die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
1454             unless $gccver >= 4;
1455         $gcc_devteam_warn .= " -Wmisleading-indentation" if $gccver >= 6;
1456         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1457                 {
1458                 push @{$config{cflags}}, $wopt
1459                         unless grep { $_ eq $wopt } @{$config{cflags}};
1460                 }
1461         if (defined($predefined{__clang__}))
1462                 {
1463                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1464                         {
1465                         push @{$config{cflags}}, $wopt
1466                                 unless grep { $_ eq $wopt } @{$config{cflags}};
1467                         }
1468                 }
1469         }
1470
1471 unless ($disabled{"crypto-mdebug-backtrace"})
1472         {
1473         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1474                 {
1475                 push @{$config{cflags}}, $wopt
1476                         unless grep { $_ eq $wopt } @{$config{cflags}};
1477                 }
1478         if ($target =~ /^BSD-/)
1479                 {
1480                 push @{$config{ex_libs}}, "-lexecinfo";
1481                 }
1482         }
1483
1484 unless ($disabled{afalgeng}) {
1485     $config{afalgeng}="";
1486     if ($target =~ m/^linux/) {
1487         my $minver = 4*10000 + 1*100 + 0;
1488         if ($config{cross_compile_prefix} eq "") {
1489             my $verstr = `uname -r`;
1490             my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1491             ($mi2) = $mi2 =~ /(\d+)/;
1492             my $ver = $ma*10000 + $mi1*100 + $mi2;
1493             if ($ver < $minver) {
1494                 $disabled{afalgeng} = "too-old-kernel";
1495             } else {
1496                 push @{$config{engdirs}}, "afalg";
1497             }
1498         } else {
1499             $disabled{afalgeng} = "cross-compiling";
1500         }
1501     } else {
1502         $disabled{afalgeng}  = "not-linux";
1503     }
1504 }
1505
1506 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1507
1508 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1509
1510 # If we use the unified build, collect information from build.info files
1511 my %unified_info = ();
1512
1513 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1514 if ($builder eq "unified") {
1515     use with_fallback qw(Text::Template);
1516
1517     sub cleandir {
1518         my $base = shift;
1519         my $dir = shift;
1520         my $relativeto = shift || ".";
1521
1522         $dir = catdir($base,$dir) unless isabsolute($dir);
1523
1524         # Make sure the directories we're building in exists
1525         mkpath($dir);
1526
1527         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1528         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1529         return $res;
1530     }
1531
1532     sub cleanfile {
1533         my $base = shift;
1534         my $file = shift;
1535         my $relativeto = shift || ".";
1536
1537         $file = catfile($base,$file) unless isabsolute($file);
1538
1539         my $d = dirname($file);
1540         my $f = basename($file);
1541
1542         # Make sure the directories we're building in exists
1543         mkpath($d);
1544
1545         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1546         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1547         return $res;
1548     }
1549
1550     # Store the name of the template file we will build the build file from
1551     # in %config.  This may be useful for the build file itself.
1552     my @build_file_template_names =
1553         ( $builder_platform."-".$target{build_file}.".tmpl",
1554           $target{build_file}.".tmpl" );
1555     my @build_file_templates = ();
1556
1557     # First, look in the user provided directory, if given
1558     if (defined env($local_config_envname)) {
1559         @build_file_templates =
1560             map {
1561                 if ($^O eq 'VMS') {
1562                     # VMS environment variables are logical names,
1563                     # which can be used as is
1564                     $local_config_envname . ':' . $_;
1565                 } else {
1566                     catfile(env($local_config_envname), $_);
1567                 }
1568             }
1569             @build_file_template_names;
1570     }
1571     # Then, look in our standard directory
1572     push @build_file_templates,
1573         ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1574           @build_file_template_names );
1575
1576     my $build_file_template;
1577     for $_ (@build_file_templates) {
1578         $build_file_template = $_;
1579         last if -f $build_file_template;
1580
1581         $build_file_template = undef;
1582     }
1583     if (!defined $build_file_template) {
1584         die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1585     }
1586     $config{build_file_templates}
1587       = [ $build_file_template,
1588           cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1589                     $blddir) ];
1590
1591     my @build_infos = ( [ ".", "build.info" ] );
1592     foreach (@{$config{dirs}}) {
1593         push @build_infos, [ $_, "build.info" ]
1594             if (-f catfile($srcdir, $_, "build.info"));
1595     }
1596     foreach (@{$config{sdirs}}) {
1597         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1598             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1599     }
1600     foreach (@{$config{engdirs}}) {
1601         push @build_infos, [ catdir("engines", $_), "build.info" ]
1602             if (-f catfile($srcdir, "engines", $_, "build.info"));
1603     }
1604     foreach (@{$config{tdirs}}) {
1605         push @build_infos, [ catdir("test", $_), "build.info" ]
1606             if (-f catfile($srcdir, "test", $_, "build.info"));
1607     }
1608
1609     $config{build_infos} = [ ];
1610
1611     my %ordinals = ();
1612     foreach (@build_infos) {
1613         my $sourced = catdir($srcdir, $_->[0]);
1614         my $buildd = catdir($blddir, $_->[0]);
1615
1616         mkpath($buildd);
1617
1618         my $f = $_->[1];
1619         # The basic things we're trying to build
1620         my @programs = ();
1621         my @programs_install = ();
1622         my @libraries = ();
1623         my @libraries_install = ();
1624         my @engines = ();
1625         my @engines_install = ();
1626         my @scripts = ();
1627         my @scripts_install = ();
1628         my @extra = ();
1629         my @overrides = ();
1630         my @intermediates = ();
1631         my @rawlines = ();
1632
1633         my %sources = ();
1634         my %shared_sources = ();
1635         my %includes = ();
1636         my %depends = ();
1637         my %renames = ();
1638         my %sharednames = ();
1639         my %generate = ();
1640
1641         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1642         my $template =
1643             Text::Template->new(TYPE => 'FILE',
1644                                 SOURCE => catfile($sourced, $f),
1645                                 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
1646         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1647         my @text =
1648             split /^/m,
1649             $template->fill_in(HASH => { config => \%config,
1650                                          target => \%target,
1651                                          disabled => \%disabled,
1652                                          withargs => \%withargs,
1653                                          builddir => abs2rel($buildd, $blddir),
1654                                          sourcedir => abs2rel($sourced, $blddir),
1655                                          buildtop => abs2rel($blddir, $blddir),
1656                                          sourcetop => abs2rel($srcdir, $blddir) },
1657                                DELIMITERS => [ "{-", "-}" ]);
1658
1659         # The top item of this stack has the following values
1660         # -2 positive already run and we found ELSE (following ELSIF should fail)
1661         # -1 positive already run (skip until ENDIF)
1662         # 0 negatives so far (if we're at a condition, check it)
1663         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1664         # 2 positive ELSE (following ELSIF should fail)
1665         my @skip = ();
1666         collect_information(
1667             collect_from_array([ @text ],
1668                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1669                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1670             # Info we're looking for
1671             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1672             => sub {
1673                 if (! @skip || $skip[$#skip] > 0) {
1674                     push @skip, !! $1;
1675                 } else {
1676                     push @skip, -1;
1677                 }
1678             },
1679             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1680             => sub { die "ELSIF out of scope" if ! @skip;
1681                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1682                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1683                      $skip[$#skip] = !! $1
1684                          if $skip[$#skip] == 0; },
1685             qr/^\s*ELSE\s*$/
1686             => sub { die "ELSE out of scope" if ! @skip;
1687                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1688                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1689             qr/^\s*ENDIF\s*$/
1690             => sub { die "ENDIF out of scope" if ! @skip;
1691                      pop @skip; },
1692             qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1693             => sub {
1694                 if (!@skip || $skip[$#skip] > 0) {
1695                     my $install = $1;
1696                     my @x = tokenize($2);
1697                     push @programs, @x;
1698                     push @programs_install, @x unless $install;
1699                 }
1700             },
1701             qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1702             => sub {
1703                 if (!@skip || $skip[$#skip] > 0) {
1704                     my $install = $1;
1705                     my @x = tokenize($2);
1706                     push @libraries, @x;
1707                     push @libraries_install, @x unless $install;
1708                 }
1709             },
1710             qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1711             => sub {
1712                 if (!@skip || $skip[$#skip] > 0) {
1713                     my $install = $1;
1714                     my @x = tokenize($2);
1715                     push @engines, @x;
1716                     push @engines_install, @x unless $install;
1717                 }
1718             },
1719             qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1720             => sub {
1721                 if (!@skip || $skip[$#skip] > 0) {
1722                     my $install = $1;
1723                     my @x = tokenize($2);
1724                     push @scripts, @x;
1725                     push @scripts_install, @x unless $install;
1726                 }
1727             },
1728             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1729             => sub { push @extra, tokenize($1)
1730                          if !@skip || $skip[$#skip] > 0 },
1731             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1732             => sub { push @overrides, tokenize($1)
1733                          if !@skip || $skip[$#skip] > 0 },
1734
1735             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1736             => sub { push @{$ordinals{$1}}, tokenize($2)
1737                          if !@skip || $skip[$#skip] > 0 },
1738             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1739             => sub { push @{$sources{$1}}, tokenize($2)
1740                          if !@skip || $skip[$#skip] > 0 },
1741             qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1742             => sub { push @{$shared_sources{$1}}, tokenize($2)
1743                          if !@skip || $skip[$#skip] > 0 },
1744             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1745             => sub { push @{$includes{$1}}, tokenize($2)
1746                          if !@skip || $skip[$#skip] > 0 },
1747             qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
1748             => sub { push @{$depends{$1}}, tokenize($2)
1749                          if !@skip || $skip[$#skip] > 0 },
1750             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1751             => sub { push @{$generate{$1}}, $2
1752                          if !@skip || $skip[$#skip] > 0 },
1753             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1754             => sub { push @{$renames{$1}}, tokenize($2)
1755                          if !@skip || $skip[$#skip] > 0 },
1756             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1757             => sub { push @{$sharednames{$1}}, tokenize($2)
1758                          if !@skip || $skip[$#skip] > 0 },
1759             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1760             => sub {
1761                 my $lineiterator = shift;
1762                 my $target_kind = $1;
1763                 while (defined $lineiterator->()) {
1764                     s|\R$||;
1765                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1766                         die "ENDRAW doesn't match BEGINRAW"
1767                             if $1 ne $target_kind;
1768                         last;
1769                     }
1770                     next if @skip && $skip[$#skip] <= 0;
1771                     push @rawlines,  $_
1772                         if ($target_kind eq $target{build_file}
1773                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1774                 }
1775             },
1776             qr/^\s*(?:#.*)?$/ => sub { },
1777             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1778             "BEFORE" => sub {
1779                 if ($buildinfo_debug) {
1780                     print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1781                     print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1782                 }
1783             },
1784             "AFTER" => sub {
1785                 if ($buildinfo_debug) {
1786                     print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1787                 }
1788             },
1789             );
1790         die "runaway IF?" if (@skip);
1791
1792         foreach (keys %renames) {
1793             die "$_ renamed to more than one thing: "
1794                 ,join(" ", @{$renames{$_}}),"\n"
1795                 if scalar @{$renames{$_}} > 1;
1796             my $dest = cleanfile($buildd, $_, $blddir);
1797             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1798             die "$dest renamed to more than one thing: "
1799                 ,$unified_info{rename}->{$dest}, $to
1800                 unless !defined($unified_info{rename}->{$dest})
1801                 or $unified_info{rename}->{$dest} eq $to;
1802             $unified_info{rename}->{$dest} = $to;
1803         }
1804
1805         foreach (@programs) {
1806             my $program = cleanfile($buildd, $_, $blddir);
1807             if ($unified_info{rename}->{$program}) {
1808                 $program = $unified_info{rename}->{$program};
1809             }
1810             $unified_info{programs}->{$program} = 1;
1811         }
1812
1813         foreach (@programs_install) {
1814             my $program = cleanfile($buildd, $_, $blddir);
1815             if ($unified_info{rename}->{$program}) {
1816                 $program = $unified_info{rename}->{$program};
1817             }
1818             $unified_info{install}->{programs}->{$program} = 1;
1819         }
1820
1821         foreach (@libraries) {
1822             my $library = cleanfile($buildd, $_, $blddir);
1823             if ($unified_info{rename}->{$library}) {
1824                 $library = $unified_info{rename}->{$library};
1825             }
1826             $unified_info{libraries}->{$library} = 1;
1827         }
1828
1829         foreach (@libraries_install) {
1830             my $library = cleanfile($buildd, $_, $blddir);
1831             if ($unified_info{rename}->{$library}) {
1832                 $library = $unified_info{rename}->{$library};
1833             }
1834             $unified_info{install}->{libraries}->{$library} = 1;
1835         }
1836
1837         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1838 ENGINES can only be used if configured with 'dynamic-engine'.
1839 This is usually a fault in a build.info file.
1840 EOF
1841         foreach (@engines) {
1842             my $library = cleanfile($buildd, $_, $blddir);
1843             if ($unified_info{rename}->{$library}) {
1844                 $library = $unified_info{rename}->{$library};
1845             }
1846             $unified_info{engines}->{$library} = 1;
1847         }
1848
1849         foreach (@engines_install) {
1850             my $library = cleanfile($buildd, $_, $blddir);
1851             if ($unified_info{rename}->{$library}) {
1852                 $library = $unified_info{rename}->{$library};
1853             }
1854             $unified_info{install}->{engines}->{$library} = 1;
1855         }
1856
1857         foreach (@scripts) {
1858             my $script = cleanfile($buildd, $_, $blddir);
1859             if ($unified_info{rename}->{$script}) {
1860                 $script = $unified_info{rename}->{$script};
1861             }
1862             $unified_info{scripts}->{$script} = 1;
1863         }
1864
1865         foreach (@scripts_install) {
1866             my $script = cleanfile($buildd, $_, $blddir);
1867             if ($unified_info{rename}->{$script}) {
1868                 $script = $unified_info{rename}->{$script};
1869             }
1870             $unified_info{install}->{scripts}->{$script} = 1;
1871         }
1872
1873         foreach (@extra) {
1874             my $extra = cleanfile($buildd, $_, $blddir);
1875             $unified_info{extra}->{$extra} = 1;
1876         }
1877
1878         foreach (@overrides) {
1879             my $override = cleanfile($buildd, $_, $blddir);
1880             $unified_info{overrides}->{$override} = 1;
1881         }
1882
1883         push @{$unified_info{rawlines}}, @rawlines;
1884
1885         unless ($disabled{shared}) {
1886             # Check sharednames.
1887             foreach (keys %sharednames) {
1888                 my $dest = cleanfile($buildd, $_, $blddir);
1889                 if ($unified_info{rename}->{$dest}) {
1890                     $dest = $unified_info{rename}->{$dest};
1891                 }
1892                 die "shared_name for $dest with multiple values: "
1893                     ,join(" ", @{$sharednames{$_}}),"\n"
1894                     if scalar @{$sharednames{$_}} > 1;
1895                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1896                 die "shared_name found for a library $dest that isn't defined\n"
1897                     unless $unified_info{libraries}->{$dest};
1898                 die "shared_name for $dest with multiple values: "
1899                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1900                     unless !defined($unified_info{sharednames}->{$dest})
1901                     or $unified_info{sharednames}->{$dest} eq $to;
1902                 $unified_info{sharednames}->{$dest} = $to;
1903             }
1904
1905             # Additionally, we set up sharednames for libraries that don't
1906             # have any, as themselves.  Only for libraries that aren't
1907             # explicitly static.
1908             foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) {
1909                 if (!defined $unified_info{sharednames}->{$_}) {
1910                     $unified_info{sharednames}->{$_} = $_
1911                 }
1912             }
1913
1914             # Check that we haven't defined any library as both shared and
1915             # explicitly static.  That is forbidden.
1916             my @doubles = ();
1917             foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
1918                 (my $l = $_) =~ s/\.a$//;
1919                 push @doubles, $l if defined $unified_info{sharednames}->{$l};
1920             }
1921             die "these libraries are both explicitly static and shared:\n  ",
1922                 join(" ", @doubles), "\n"
1923                 if @doubles;
1924         }
1925
1926         foreach (keys %sources) {
1927             my $dest = $_;
1928             my $ddest = cleanfile($buildd, $_, $blddir);
1929             if ($unified_info{rename}->{$ddest}) {
1930                 $ddest = $unified_info{rename}->{$ddest};
1931             }
1932             foreach (@{$sources{$dest}}) {
1933                 my $s = cleanfile($sourced, $_, $blddir);
1934
1935                 # If it isn't in the source tree, we assume it's generated
1936                 # in the build tree
1937                 if (! -f $s) {
1938                     $s = cleanfile($buildd, $_, $blddir);
1939                 }
1940                 # We recognise C++, C and asm files
1941                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1942                     my $o = $_;
1943                     $o =~ s/\.[csS]$/.o/; # C and assembler
1944                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1945                     $o = cleanfile($buildd, $o, $blddir);
1946                     $unified_info{sources}->{$ddest}->{$o} = 1;
1947                     $unified_info{sources}->{$o}->{$s} = 1;
1948                 } else {
1949                     $unified_info{sources}->{$ddest}->{$s} = 1;
1950                 }
1951             }
1952         }
1953
1954         foreach (keys %shared_sources) {
1955             my $dest = $_;
1956             my $ddest = cleanfile($buildd, $_, $blddir);
1957             if ($unified_info{rename}->{$ddest}) {
1958                 $ddest = $unified_info{rename}->{$ddest};
1959             }
1960             foreach (@{$shared_sources{$dest}}) {
1961                 my $s = cleanfile($sourced, $_, $blddir);
1962
1963                 # If it isn't in the source tree, we assume it's generated
1964                 # in the build tree
1965                 if (! -f $s) {
1966                     $s = cleanfile($buildd, $_, $blddir);
1967                 }
1968
1969                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1970                     # We recognise C++, C and asm files
1971                     my $o = $_;
1972                     $o =~ s/\.[csS]$/.o/; # C and assembler
1973                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1974                     $o = cleanfile($buildd, $o, $blddir);
1975                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1976                     $unified_info{sources}->{$o}->{$s} = 1;
1977                 } elsif ($s =~ /\.rc$/) {
1978                     # We also recognise resource files
1979                     my $o = $_;
1980                     $o =~ s/\.rc$/.res/; # Resource configuration
1981                     my $o = cleanfile($buildd, $o, $blddir);
1982                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1983                     $unified_info{sources}->{$o}->{$s} = 1;
1984                 } elsif ($s =~ /\.(def|map|opt)$/) {
1985                     # We also recognise .def / .map / .opt files
1986                     # We know they are generated files
1987                     my $def = cleanfile($buildd, $s, $blddir);
1988                     $unified_info{shared_sources}->{$ddest}->{$def} = 1;
1989                 } else {
1990                     die "unrecognised source file type for shared library: $s\n";
1991                 }
1992             }
1993         }
1994
1995         foreach (keys %generate) {
1996             my $dest = $_;
1997             my $ddest = cleanfile($buildd, $_, $blddir);
1998             if ($unified_info{rename}->{$ddest}) {
1999                 $ddest = $unified_info{rename}->{$ddest};
2000             }
2001             die "more than one generator for $dest: "
2002                     ,join(" ", @{$generate{$_}}),"\n"
2003                     if scalar @{$generate{$_}} > 1;
2004             my @generator = split /\s+/, $generate{$dest}->[0];
2005             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
2006             $unified_info{generate}->{$ddest} = [ @generator ];
2007         }
2008
2009         foreach (keys %depends) {
2010             my $dest = $_;
2011             my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
2012
2013             # If the destination doesn't exist in source, it can only be
2014             # a generated file in the build tree.
2015             if ($ddest ne "" && ! -f $ddest) {
2016                 $ddest = cleanfile($buildd, $_, $blddir);
2017                 if ($unified_info{rename}->{$ddest}) {
2018                     $ddest = $unified_info{rename}->{$ddest};
2019                 }
2020             }
2021             foreach (@{$depends{$dest}}) {
2022                 my $d = cleanfile($sourced, $_, $blddir);
2023
2024                 # If we know it's generated, or assume it is because we can't
2025                 # find it in the source tree, we set file we depend on to be
2026                 # in the build tree rather than the source tree, and assume
2027                 # and that there are lines to build it in a BEGINRAW..ENDRAW
2028                 # section or in the Makefile template.
2029                 if (! -f $d
2030                     || (grep { $d eq $_ }
2031                         map { cleanfile($srcdir, $_, $blddir) }
2032                         grep { /\.h$/ } keys %{$unified_info{generate}})) {
2033                     $d = cleanfile($buildd, $_, $blddir);
2034                 }
2035                 # Take note if the file to depend on is being renamed
2036                 # Take extra care with files ending with .a, they should
2037                 # be treated without that extension, and the extension
2038                 # should be added back after treatment.
2039                 $d =~ /(\.a)?$/;
2040                 my $e = $1 // "";
2041                 $d = $`;
2042                 if ($unified_info{rename}->{$d}) {
2043                     $d = $unified_info{rename}->{$d};
2044                 }
2045                 $d .= $e;
2046                 $unified_info{depends}->{$ddest}->{$d} = 1;
2047             }
2048         }
2049
2050         foreach (keys %includes) {
2051             my $dest = $_;
2052             my $ddest = cleanfile($sourced, $_, $blddir);
2053
2054             # If the destination doesn't exist in source, it can only be
2055             # a generated file in the build tree.
2056             if (! -f $ddest) {
2057                 $ddest = cleanfile($buildd, $_, $blddir);
2058                 if ($unified_info{rename}->{$ddest}) {
2059                     $ddest = $unified_info{rename}->{$ddest};
2060                 }
2061             }
2062             foreach (@{$includes{$dest}}) {
2063                 my $is = cleandir($sourced, $_, $blddir);
2064                 my $ib = cleandir($buildd, $_, $blddir);
2065                 push @{$unified_info{includes}->{$ddest}->{source}}, $is
2066                     unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
2067                 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
2068                     unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
2069             }
2070         }
2071     }
2072
2073     my $ordinals_text = join(', ', sort keys %ordinals);
2074     warn <<"EOF" if $ordinals_text;
2075
2076 WARNING: ORDINALS were specified for $ordinals_text
2077 They are ignored and should be replaced with a combination of GENERATE,
2078 DEPEND and SHARED_SOURCE.
2079 EOF
2080
2081     # Massage the result
2082
2083     # If we depend on a header file or a perl module, add an inclusion of
2084     # its directory to allow smoothe inclusion
2085     foreach my $dest (keys %{$unified_info{depends}}) {
2086         next if $dest eq "";
2087         foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
2088             next unless $d =~ /\.(h|pm)$/;
2089             if ($d eq "configdata.pm"
2090                     || defined($unified_info{generate}->{$d})) {
2091                 my $i = cleandir($blddir, dirname($d));
2092                 push @{$unified_info{includes}->{$dest}->{build}}, $i
2093                     unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{build}};
2094             } else {
2095                 my $i = cleandir($srcdir, dirname($d));
2096                 push @{$unified_info{includes}->{$dest}->{source}}, $i
2097                     unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{source}};
2098             }
2099         }
2100     }
2101
2102     # Trickle down includes placed on libraries, engines and programs to
2103     # their sources (i.e. object files)
2104     foreach my $dest (keys %{$unified_info{engines}},
2105                       keys %{$unified_info{libraries}},
2106                       keys %{$unified_info{programs}}) {
2107         foreach my $k (("source", "build")) {
2108             next unless defined($unified_info{includes}->{$dest}->{$k});
2109             my @incs = reverse @{$unified_info{includes}->{$dest}->{$k}};
2110             foreach my $obj (grep /\.o$/,
2111                              (keys %{$unified_info{sources}->{$dest}},
2112                               keys %{$unified_info{shared_sources}->{$dest}})) {
2113                 foreach my $inc (@incs) {
2114                     unshift @{$unified_info{includes}->{$obj}->{$k}}, $inc
2115                         unless grep { $_ eq $inc } @{$unified_info{includes}->{$obj}->{$k}};
2116                 }
2117             }
2118         }
2119         delete $unified_info{includes}->{$dest};
2120     }
2121
2122     ### Make unified_info a bit more efficient
2123     # One level structures
2124     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
2125         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
2126     }
2127     # Two level structures
2128     foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
2129         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
2130             $unified_info{$l1}->{$l2} =
2131                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
2132         }
2133     }
2134     # Includes
2135     foreach my $dest (sort keys %{$unified_info{includes}}) {
2136         if (defined($unified_info{includes}->{$dest}->{build})) {
2137             my @source_includes = ();
2138             @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} )
2139                 if defined($unified_info{includes}->{$dest}->{source});
2140             $unified_info{includes}->{$dest} =
2141                 [ @{$unified_info{includes}->{$dest}->{build}} ];
2142             foreach my $inc (@source_includes) {
2143                 push @{$unified_info{includes}->{$dest}}, $inc
2144                     unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
2145             }
2146         } else {
2147             $unified_info{includes}->{$dest} =
2148                 [ @{$unified_info{includes}->{$dest}->{source}} ];
2149         }
2150     }
2151 }
2152
2153 # For the schemes that need it, we provide the old *_obj configs
2154 # from the *_asm_obj ones
2155 foreach (grep /_(asm|aux)_src$/, keys %target) {
2156     my $src = $_;
2157     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
2158     $target{$obj} = $target{$src};
2159     $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
2160     $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
2161 }
2162
2163 # Write down our configuration where it fits #########################
2164
2165 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
2166 print OUT <<"EOF";
2167 package configdata;
2168
2169 use strict;
2170 use warnings;
2171
2172 use Exporter;
2173 #use vars qw(\@ISA \@EXPORT);
2174 our \@ISA = qw(Exporter);
2175 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
2176
2177 EOF
2178 print OUT "our %config = (\n";
2179 foreach (sort keys %config) {
2180     if (ref($config{$_}) eq "ARRAY") {
2181         print OUT "  ", $_, " => [ ", join(", ",
2182                                            map { quotify("perl", $_) }
2183                                            @{$config{$_}}), " ],\n";
2184     } elsif (ref($config{$_}) eq "HASH") {
2185         print OUT "  ", $_, " => {";
2186         if (scalar keys %{$config{$_}} > 0) {
2187             print OUT "\n";
2188             foreach my $key (sort keys %{$config{$_}}) {
2189                 print OUT "      ",
2190                     join(" => ",
2191                          quotify("perl", $key),
2192                          defined $config{$_}->{$key}
2193                              ? quotify("perl", $config{$_}->{$key})
2194                              : "undef");
2195                 print OUT ",\n";
2196             }
2197             print OUT "  ";
2198         }
2199         print OUT "},\n";
2200     } else {
2201         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
2202     }
2203 }
2204 print OUT <<"EOF";
2205 );
2206
2207 EOF
2208 print OUT "our %target = (\n";
2209 foreach (sort keys %target) {
2210     if (ref($target{$_}) eq "ARRAY") {
2211         print OUT "  ", $_, " => [ ", join(", ",
2212                                            map { quotify("perl", $_) }
2213                                            @{$target{$_}}), " ],\n";
2214     } else {
2215         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
2216     }
2217 }
2218 print OUT <<"EOF";
2219 );
2220
2221 EOF
2222 print OUT "our \%available_protocols = (\n";
2223 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
2224 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
2225 print OUT <<"EOF";
2226 );
2227
2228 EOF
2229 print OUT "our \@disablables = (\n";
2230 foreach (@disablables) {
2231     print OUT "  ", quotify("perl", $_), ",\n";
2232 }
2233 print OUT <<"EOF";
2234 );
2235
2236 EOF
2237 print OUT "our \%disabled = (\n";
2238 foreach (sort keys %disabled) {
2239     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
2240 }
2241 print OUT <<"EOF";
2242 );
2243
2244 EOF
2245 print OUT "our %withargs = (\n";
2246 foreach (sort keys %withargs) {
2247     if (ref($withargs{$_}) eq "ARRAY") {
2248         print OUT "  ", $_, " => [ ", join(", ",
2249                                            map { quotify("perl", $_) }
2250                                            @{$withargs{$_}}), " ],\n";
2251     } else {
2252         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
2253     }
2254 }
2255 print OUT <<"EOF";
2256 );
2257
2258 EOF
2259 if ($builder eq "unified") {
2260     my $recurse;
2261     $recurse = sub {
2262         my $indent = shift;
2263         foreach (@_) {
2264             if (ref $_ eq "ARRAY") {
2265                 print OUT " "x$indent, "[\n";
2266                 foreach (@$_) {
2267                     $recurse->($indent + 4, $_);
2268                 }
2269                 print OUT " "x$indent, "],\n";
2270             } elsif (ref $_ eq "HASH") {
2271                 my %h = %$_;
2272                 print OUT " "x$indent, "{\n";
2273                 foreach (sort keys %h) {
2274                     if (ref $h{$_} eq "") {
2275                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
2276                     } else {
2277                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
2278                         $recurse->($indent + 8, $h{$_});
2279                     }
2280                 }
2281                 print OUT " "x$indent, "},\n";
2282             } else {
2283                 print OUT " "x$indent, quotify("perl", $_), ",\n";
2284             }
2285         }
2286     };
2287     print OUT "our %unified_info = (\n";
2288     foreach (sort keys %unified_info) {
2289         if (ref $unified_info{$_} eq "") {
2290             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
2291         } else {
2292             print OUT " "x4, quotify("perl", $_), " =>\n";
2293             $recurse->(8, $unified_info{$_});
2294         }
2295     }
2296     print OUT <<"EOF";
2297 );
2298
2299 EOF
2300 }
2301 print OUT "1;\n";
2302 close(OUT);
2303
2304 print "\n";
2305 print "PROCESSOR     =$config{processor}\n" if $config{processor};
2306 print "PERL          =$config{perl}\n";
2307 print "PERLVERSION   =$Config{version} for $Config{archname}\n";
2308 print "HASHBANGPERL  =$config{hashbangperl}\n";
2309 print "DEFINES       =",join(" ", @{$config{defines}}),"\n"
2310     if defined $config{defines};
2311 print "INCLUDES      =",join(" ", @{$config{includes}}),"\n"
2312     if defined $config{includes};
2313 print "CPPFLAGS      =",join(" ", @{$config{cppflags}}),"\n"
2314     if defined $config{cppflags};
2315 print "CC            =$config{cross_compile_prefix}$config{cc}\n";
2316 print "CFLAGS        =",join(" ", @{$config{cflags}}),"\n"
2317     if defined $config{cflags};
2318 print "CXX           =$config{cross_compile_prefix}$config{cxx}\n"
2319     if defined $config{cxx};
2320 print "CXXFLAGS      =",join(" ", @{$config{cxxflags}}),"\n"
2321     if defined $config{cxxflags};
2322 print "LD            =$config{cross_compile_prefix}$config{ld}\n"
2323     if defined $config{ld};
2324 print "LDFLAGS       =",join(" ", @{$config{lflags}}),"\n"
2325     if defined $config{lflags};
2326 print "EX_LIBS       =",join(" ", @{$config{ex_libs}}),"\n"
2327     if defined $config{ex_libs};
2328
2329 my %builders = (
2330     unified => sub {
2331         run_dofile(catfile($blddir, $target{build_file}),
2332                    @{$config{build_file_templates}});
2333     },
2334     );
2335
2336 $builders{$builder}->($builder_platform, @builder_opts);
2337
2338 print <<"EOF" if ($disabled{threads} eq "unavailable");
2339
2340 The library could not be configured for supporting multi-threaded
2341 applications as the compiler options required on this system are not known.
2342 See file INSTALL for details if you need multi-threading.
2343 EOF
2344
2345 print <<"EOF" if ($no_shared_warn);
2346
2347 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2348 platform, so we will pretend you gave the option 'no-pic', which also disables
2349 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
2350 or position independent code, please let us know (but please first make sure
2351 you have tried with a current version of OpenSSL).
2352 EOF
2353
2354 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2355
2356 WARNING: there are indications that another build was made in the source
2357 directory.  This build may have picked up artifacts from that build, the
2358 safest course of action is to clean the source directory and redo this
2359 configuration.
2360 EOF
2361
2362 exit(0);
2363
2364 ######################################################################
2365 #
2366 # Helpers and utility functions
2367 #
2368
2369 # Configuration file reading #########################################
2370
2371 # Note: All of the helper functions are for lazy evaluation.  They all
2372 # return a CODE ref, which will return the intended value when evaluated.
2373 # Thus, whenever there's mention of a returned value, it's about that
2374 # intended value.
2375
2376 # Helper function to implement conditional inheritance depending on the
2377 # value of $disabled{asm}.  Used in inherit_from values as follows:
2378 #
2379 #      inherit_from => [ "template", asm("asm_tmpl") ]
2380 #
2381 sub asm {
2382     my @x = @_;
2383     sub {
2384         $disabled{asm} ? () : @x;
2385     }
2386 }
2387
2388 # Helper function to implement conditional value variants, with a default
2389 # plus additional values based on the value of $config{build_type}.
2390 # Arguments are given in hash table form:
2391 #
2392 #       picker(default => "Basic string: ",
2393 #              debug   => "debug",
2394 #              release => "release")
2395 #
2396 # When configuring with --debug, the resulting string will be
2397 # "Basic string: debug", and when not, it will be "Basic string: release"
2398 #
2399 # This can be used to create variants of sets of flags according to the
2400 # build type:
2401 #
2402 #       cflags => picker(default => "-Wall",
2403 #                        debug   => "-g -O0",
2404 #                        release => "-O3")
2405 #
2406 sub picker {
2407     my %opts = @_;
2408     return sub { add($opts{default} || (),
2409                      $opts{$config{build_type}} || ())->(); }
2410 }
2411
2412 # Helper function to combine several values of different types into one.
2413 # This is useful if you want to combine a string with the result of a
2414 # lazy function, such as:
2415 #
2416 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2417 #
2418 sub combine {
2419     my @stuff = @_;
2420     return sub { add(@stuff)->(); }
2421 }
2422
2423 # Helper function to implement conditional values depending on the value
2424 # of $disabled{threads}.  Can be used as follows:
2425 #
2426 #       cflags => combine("-Wall", threads("-pthread"))
2427 #
2428 sub threads {
2429     my @flags = @_;
2430     return sub { add($disabled{threads} ? () : @flags)->(); }
2431 }
2432
2433
2434
2435 our $add_called = 0;
2436 # Helper function to implement adding values to already existing configuration
2437 # values.  It handles elements that are ARRAYs, CODEs and scalars
2438 sub _add {
2439     my $separator = shift;
2440
2441     # If there's any ARRAY in the collection of values OR the separator
2442     # is undef, we will return an ARRAY of combined values, otherwise a
2443     # string of joined values with $separator as the separator.
2444     my $found_array = !defined($separator);
2445
2446     my @values =
2447         map {
2448             my $res = $_;
2449             while (ref($res) eq "CODE") {
2450                 $res = $res->();
2451             }
2452             if (defined($res)) {
2453                 if (ref($res) eq "ARRAY") {
2454                     $found_array = 1;
2455                     @$res;
2456                 } else {
2457                     $res;
2458                 }
2459             } else {
2460                 ();
2461             }
2462     } (@_);
2463
2464     $add_called = 1;
2465
2466     if ($found_array) {
2467         [ @values ];
2468     } else {
2469         join($separator, grep { defined($_) && $_ ne "" } @values);
2470     }
2471 }
2472 sub add_before {
2473     my $separator = " ";
2474     if (ref($_[$#_]) eq "HASH") {
2475         my $opts = pop;
2476         $separator = $opts->{separator};
2477     }
2478     my @x = @_;
2479     sub { _add($separator, @x, @_) };
2480 }
2481 sub add {
2482     my $separator = " ";
2483     if (ref($_[$#_]) eq "HASH") {
2484         my $opts = pop;
2485         $separator = $opts->{separator};
2486     }
2487     my @x = @_;
2488     sub { _add($separator, @_, @x) };
2489 }
2490
2491 sub read_eval_file {
2492     my $fname = shift;
2493     my $content;
2494     my @result;
2495
2496     open F, "< $fname" or die "Can't open '$fname': $!\n";
2497     {
2498         undef local $/;
2499         $content = <F>;
2500     }
2501     close F;
2502     {
2503         local $@;
2504
2505         @result = ( eval $content );
2506         warn $@ if $@;
2507     }
2508     return wantarray ? @result : $result[0];
2509 }
2510
2511 # configuration reader, evaluates the input file as a perl script and expects
2512 # it to fill %targets with target configurations.  Those are then added to
2513 # %table.
2514 sub read_config {
2515     my $fname = shift;
2516     my %targets;
2517
2518     {
2519         # Protect certain tables from tampering
2520         local %table = ();
2521
2522         %targets = read_eval_file($fname);
2523     }
2524     my %preexisting = ();
2525     foreach (sort keys %targets) {
2526         $preexisting{$_} = 1 if $table{$_};
2527     }
2528     die <<"EOF",
2529 The following config targets from $fname
2530 shadow pre-existing config targets with the same name:
2531 EOF
2532         map { "  $_\n" } sort keys %preexisting
2533         if %preexisting;
2534
2535
2536     # For each target, check that it's configured with a hash table.
2537     foreach (keys %targets) {
2538         if (ref($targets{$_}) ne "HASH") {
2539             if (ref($targets{$_}) eq "") {
2540                 warn "Deprecated target configuration for $_, ignoring...\n";
2541             } else {
2542                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2543             }
2544             delete $targets{$_};
2545         } else {
2546             $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2547         }
2548     }
2549
2550     %table = (%table, %targets);
2551
2552 }
2553
2554 # configuration resolver.  Will only resolve all the lazy evaluation
2555 # codeblocks for the chosen target and all those it inherits from,
2556 # recursively
2557 sub resolve_config {
2558     my $target = shift;
2559     my @breadcrumbs = @_;
2560
2561 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2562
2563     if (grep { $_ eq $target } @breadcrumbs) {
2564         die "inherit_from loop!  target backtrace:\n  "
2565             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2566     }
2567
2568     if (!defined($table{$target})) {
2569         warn "Warning! target $target doesn't exist!\n";
2570         return ();
2571     }
2572     # Recurse through all inheritances.  They will be resolved on the
2573     # fly, so when this operation is done, they will all just be a
2574     # bunch of attributes with string values.
2575     # What we get here, though, are keys with references to lists of
2576     # the combined values of them all.  We will deal with lists after
2577     # this stage is done.
2578     my %combined_inheritance = ();
2579     if ($table{$target}->{inherit_from}) {
2580         my @inherit_from =
2581             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2582         foreach (@inherit_from) {
2583             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2584
2585             # 'template' is a marker that's considered private to
2586             # the config that had it.
2587             delete $inherited_config{template};
2588
2589             foreach (keys %inherited_config) {
2590                 if (!$combined_inheritance{$_}) {
2591                     $combined_inheritance{$_} = [];
2592                 }
2593                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2594             }
2595         }
2596     }
2597
2598     # We won't need inherit_from in this target any more, since we've
2599     # resolved all the inheritances that lead to this
2600     delete $table{$target}->{inherit_from};
2601
2602     # Now is the time to deal with those lists.  Here's the place to
2603     # decide what shall be done with those lists, all based on the
2604     # values of the target we're currently dealing with.
2605     # - If a value is a coderef, it will be executed with the list of
2606     #   inherited values as arguments.
2607     # - If the corresponding key doesn't have a value at all or is the
2608     #   empty string, the inherited value list will be run through the
2609     #   default combiner (below), and the result becomes this target's
2610     #   value.
2611     # - Otherwise, this target's value is assumed to be a string that
2612     #   will simply override the inherited list of values.
2613     my $default_combiner = add();
2614
2615     my %all_keys =
2616         map { $_ => 1 } (keys %combined_inheritance,
2617                          keys %{$table{$target}});
2618
2619     sub process_values {
2620         my $object    = shift;
2621         my $inherited = shift;  # Always a [ list ]
2622         my $target    = shift;
2623         my $entry     = shift;
2624
2625         $add_called = 0;
2626
2627         while(ref($object) eq "CODE") {
2628             $object = $object->(@$inherited);
2629         }
2630         if (!defined($object)) {
2631             return ();
2632         }
2633         elsif (ref($object) eq "ARRAY") {
2634             local $add_called;  # To make sure recursive calls don't affect it
2635             return [ map { process_values($_, $inherited, $target, $entry) }
2636                      @$object ];
2637         } elsif (ref($object) eq "") {
2638             return $object;
2639         } else {
2640             die "cannot handle reference type ",ref($object)
2641                 ," found in target ",$target," -> ",$entry,"\n";
2642         }
2643     }
2644
2645     foreach (sort keys %all_keys) {
2646         my $previous = $combined_inheritance{$_};
2647
2648         # Current target doesn't have a value for the current key?
2649         # Assign it the default combiner, the rest of this loop body
2650         # will handle it just like any other coderef.
2651         if (!exists $table{$target}->{$_}) {
2652             $table{$target}->{$_} = $default_combiner;
2653         }
2654
2655         $table{$target}->{$_} = process_values($table{$target}->{$_},
2656                                                $combined_inheritance{$_},
2657                                                $target, $_);
2658         unless(defined($table{$target}->{$_})) {
2659             delete $table{$target}->{$_};
2660         }
2661 #        if ($extra_checks &&
2662 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2663 #            warn "$_ got replaced in $target\n";
2664 #        }
2665     }
2666
2667     # Finally done, return the result.
2668     return %{$table{$target}};
2669 }
2670
2671 sub usage
2672         {
2673         print STDERR $usage;
2674         print STDERR "\npick os/compiler from:\n";
2675         my $j=0;
2676         my $i;
2677         my $k=0;
2678         foreach $i (sort keys %table)
2679                 {
2680                 next if $table{$i}->{template};
2681                 next if $i =~ /^debug/;
2682                 $k += length($i) + 1;
2683                 if ($k > 78)
2684                         {
2685                         print STDERR "\n";
2686                         $k=length($i);
2687                         }
2688                 print STDERR $i . " ";
2689                 }
2690         foreach $i (sort keys %table)
2691                 {
2692                 next if $table{$i}->{template};
2693                 next if $i !~ /^debug/;
2694                 $k += length($i) + 1;
2695                 if ($k > 78)
2696                         {
2697                         print STDERR "\n";
2698                         $k=length($i);
2699                         }
2700                 print STDERR $i . " ";
2701                 }
2702         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2703         exit(1);
2704         }
2705
2706 sub run_dofile
2707 {
2708     my $out = shift;
2709     my @templates = @_;
2710
2711     unlink $out || warn "Can't remove $out, $!"
2712         if -f $out;
2713     foreach (@templates) {
2714         die "Can't open $_, $!" unless -f $_;
2715     }
2716     my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2717     my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2718     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2719     system($cmd);
2720     exit 1 if $? != 0;
2721     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2722 }
2723
2724 sub compiler_predefined {
2725     state %predefined;
2726     my $default_compiler = shift;
2727
2728     return () if $^O eq 'VMS';
2729
2730     die 'compiler_predefines called without a default compiler'
2731         unless $default_compiler;
2732
2733     if (! $predefined{$default_compiler}) {
2734         my $cc = "$config{cross_compile_prefix}$default_compiler";
2735
2736         $predefined{$default_compiler} = {};
2737
2738         # collect compiler pre-defines from gcc or gcc-alike...
2739         open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
2740         while (my $l = <PIPE>) {
2741             $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
2742             $predefined{$default_compiler}->{$1} = $2 // '';
2743         }
2744         close(PIPE);
2745     }
2746
2747     return %{$predefined{$default_compiler}};
2748 }
2749
2750 sub which
2751 {
2752     my ($name)=@_;
2753
2754     if (eval { require IPC::Cmd; 1; }) {
2755         IPC::Cmd->import();
2756         return scalar IPC::Cmd::can_run($name);
2757     } else {
2758         # if there is $directories component in splitpath,
2759         # then it's not something to test with $PATH...
2760         return $name if (File::Spec->splitpath($name))[1];
2761
2762         foreach (File::Spec->path()) {
2763             my $fullpath = catfile($_, "$name$target{exe_extension}");
2764             if (-f $fullpath and -x $fullpath) {
2765                 return $fullpath;
2766             }
2767         }
2768     }
2769 }
2770
2771 sub env
2772 {
2773     my $name = shift;
2774
2775     # Note that if $ENV{$name} doesn't exist or is undefined,
2776     # $config{perlenv}->{$name} will be created with the value
2777     # undef.  This is intentional.
2778
2779     $config{perlenv}->{$name} = $ENV{$name}
2780         if ! exists $config{perlenv}->{$name};
2781     return $config{perlenv}->{$name};
2782 }
2783
2784 # Configuration printer ##############################################
2785
2786 sub print_table_entry
2787 {
2788     my $target = shift;
2789     my %target = resolve_config($target);
2790     my $type = shift;
2791
2792     # Don't print the templates
2793     return if $target{template};
2794
2795     my @sequence = (
2796         "sys_id",
2797         "cpp",
2798         "cppflags",
2799         "defines",
2800         "includes",
2801         "cc",
2802         "cflags",
2803         "unistd",
2804         "ld",
2805         "lflags",
2806         "loutflag",
2807         "plib_lflags",
2808         "ex_libs",
2809         "bn_ops",
2810         "apps_aux_src",
2811         "cpuid_asm_src",
2812         "uplink_aux_src",
2813         "bn_asm_src",
2814         "ec_asm_src",
2815         "des_asm_src",
2816         "aes_asm_src",
2817         "bf_asm_src",
2818         "md5_asm_src",
2819         "cast_asm_src",
2820         "sha1_asm_src",
2821         "rc4_asm_src",
2822         "rmd160_asm_src",
2823         "rc5_asm_src",
2824         "wp_asm_src",
2825         "cmll_asm_src",
2826         "modes_asm_src",
2827         "padlock_asm_src",
2828         "chacha_asm_src",
2829         "poly1035_asm_src",
2830         "thread_scheme",
2831         "perlasm_scheme",
2832         "dso_scheme",
2833         "shared_target",
2834         "shared_cflag",
2835         "shared_defines",
2836         "shared_ldflag",
2837         "shared_rcflag",
2838         "shared_extension",
2839         "dso_extension",
2840         "obj_extension",
2841         "exe_extension",
2842         "ranlib",
2843         "ar",
2844         "arflags",
2845         "aroutflag",
2846         "rc",
2847         "rcflags",
2848         "rcoutflag",
2849         "mt",
2850         "mtflags",
2851         "mtinflag",
2852         "mtoutflag",
2853         "multilib",
2854         "build_scheme",
2855         );
2856
2857     if ($type eq "TABLE") {
2858         print "\n";
2859         print "*** $target\n";
2860         foreach (@sequence) {
2861             if (ref($target{$_}) eq "ARRAY") {
2862                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2863             } else {
2864                 printf "\$%-12s = %s\n", $_, $target{$_};
2865             }
2866         }
2867     } elsif ($type eq "HASH") {
2868         my $largest =
2869             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2870         print "    '$target' => {\n";
2871         foreach (@sequence) {
2872             if ($target{$_}) {
2873                 if (ref($target{$_}) eq "ARRAY") {
2874                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2875                 } else {
2876                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2877                 }
2878             }
2879         }
2880         print "    },\n";
2881     }
2882 }
2883
2884 # Utility routines ###################################################
2885
2886 # On VMS, if the given file is a logical name, File::Spec::Functions
2887 # will consider it an absolute path.  There are cases when we want a
2888 # purely syntactic check without checking the environment.
2889 sub isabsolute {
2890     my $file = shift;
2891
2892     # On non-platforms, we just use file_name_is_absolute().
2893     return file_name_is_absolute($file) unless $^O eq "VMS";
2894
2895     # If the file spec includes a device or a directory spec,
2896     # file_name_is_absolute() is perfectly safe.
2897     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2898
2899     # Here, we know the given file spec isn't absolute
2900     return 0;
2901 }
2902
2903 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2904 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2905 # realpath() requires that at least all path components except the last is an
2906 # existing directory.  On VMS, the last component of the directory spec must
2907 # exist.
2908 sub absolutedir {
2909     my $dir = shift;
2910
2911     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2912     # will return the volume name for the device, no matter what.  Also,
2913     # it will return an incorrect directory spec if the argument is a
2914     # directory that doesn't exist.
2915     if ($^O eq "VMS") {
2916         return rel2abs($dir);
2917     }
2918
2919     # We use realpath() on Unix, since no other will properly clean out
2920     # a directory spec.
2921     use Cwd qw/realpath/;
2922
2923     return realpath($dir);
2924 }
2925
2926 sub quotify {
2927     my %processors = (
2928         perl    => sub { my $x = shift;
2929                          $x =~ s/([\\\$\@"])/\\$1/g;
2930                          return '"'.$x.'"'; },
2931         maybeshell => sub { my $x = shift;
2932                             (my $y = $x) =~ s/([\\\"])/\\$1/g;
2933                             if ($x ne $y || $x =~ m|\s|) {
2934                                 return '"'.$y.'"';
2935                             } else {
2936                                 return $x;
2937                             }
2938                         },
2939         );
2940     my $for = shift;
2941     my $processor =
2942         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2943
2944     return map { $processor->($_); } @_;
2945 }
2946
2947 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2948 # $filename is a file name to read from
2949 # $line_concat_cond_re is a regexp detecting a line continuation ending
2950 # $line_concat is a CODEref that takes care of concatenating two lines
2951 sub collect_from_file {
2952     my $filename = shift;
2953     my $line_concat_cond_re = shift;
2954     my $line_concat = shift;
2955
2956     open my $fh, $filename || die "unable to read $filename: $!\n";
2957     return sub {
2958         my $saved_line = "";
2959         $_ = "";
2960         while (<$fh>) {
2961             s|\R$||;
2962             if (defined $line_concat) {
2963                 $_ = $line_concat->($saved_line, $_);
2964                 $saved_line = "";
2965             }
2966             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2967                 $saved_line = $_;
2968                 next;
2969             }
2970             return $_;
2971         }
2972         die "$filename ending with continuation line\n" if $_;
2973         close $fh;
2974         return undef;
2975     }
2976 }
2977
2978 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2979 # $array is an ARRAYref of lines
2980 # $line_concat_cond_re is a regexp detecting a line continuation ending
2981 # $line_concat is a CODEref that takes care of concatenating two lines
2982 sub collect_from_array {
2983     my $array = shift;
2984     my $line_concat_cond_re = shift;
2985     my $line_concat = shift;
2986     my @array = (@$array);
2987
2988     return sub {
2989         my $saved_line = "";
2990         $_ = "";
2991         while (defined($_ = shift @array)) {
2992             s|\R$||;
2993             if (defined $line_concat) {
2994                 $_ = $line_concat->($saved_line, $_);
2995                 $saved_line = "";
2996             }
2997             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2998                 $saved_line = $_;
2999                 next;
3000             }
3001             return $_;
3002         }
3003         die "input text ending with continuation line\n" if $_;
3004         return undef;
3005     }
3006 }
3007
3008 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
3009 # $lineiterator is a CODEref that delivers one line at a time.
3010 # All following arguments are regex/CODEref pairs, where the regexp detects a
3011 # line and the CODEref does something with the result of the regexp.
3012 sub collect_information {
3013     my $lineiterator = shift;
3014     my %collectors = @_;
3015
3016     while(defined($_ = $lineiterator->())) {
3017         s|\R$||;
3018         my $found = 0;
3019         if ($collectors{"BEFORE"}) {
3020             $collectors{"BEFORE"}->($_);
3021         }
3022         foreach my $re (keys %collectors) {
3023             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
3024                 $collectors{$re}->($lineiterator);
3025                 $found = 1;
3026             };
3027         }
3028         if ($collectors{"OTHERWISE"}) {
3029             $collectors{"OTHERWISE"}->($lineiterator, $_)
3030                 unless $found || !defined $collectors{"OTHERWISE"};
3031         }
3032         if ($collectors{"AFTER"}) {
3033             $collectors{"AFTER"}->($_);
3034         }
3035     }
3036 }
3037
3038 # tokenize($line)
3039 # $line is a line of text to split up into tokens
3040 # returns a list of tokens
3041 #
3042 # Tokens are divided by spaces.  If the tokens include spaces, they
3043 # have to be quoted with single or double quotes.  Double quotes
3044 # inside a double quoted token must be escaped.  Escaping is done
3045 # with backslash.
3046 # Basically, the same quoting rules apply for " and ' as in any
3047 # Unix shell.
3048 sub tokenize {
3049     my $line = my $debug_line = shift;
3050     my @result = ();
3051
3052     while ($line =~ s|^\s+||, $line ne "") {
3053         my $token = "";
3054         while ($line ne "" && $line !~ m|^\s|) {
3055             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
3056                 $token .= $1;
3057                 $line = $';
3058             } elsif ($line =~ m/^'([^']*)'/) {
3059                 $token .= $1;
3060                 $line = $';
3061             } elsif ($line =~ m/^(\S+)/) {
3062                 $token .= $1;
3063                 $line = $';
3064             }
3065         }
3066         push @result, $token;
3067     }
3068
3069     if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3070         print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
3071         print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
3072     }
3073     return @result;
3074 }