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