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