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