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