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