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