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