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