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