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