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