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