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