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