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