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