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