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