]> git.ipfire.org Git - thirdparty/openssl.git/blame - Configure
Configure: Read in extra information to help create shared libraries
[thirdparty/openssl.git] / Configure
CommitLineData
de17db91 1#! /usr/bin/env perl
f4d8f037 2# -*- mode: perl; -*-
d42d0a4d 3# Copyright 2016-2017 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"
d42d0a4d 425 "aria" => "default",
c38bb727 426 "asan" => "default",
a9c27fe1
BK
427 "crypto-mdebug" => "default",
428 "crypto-mdebug-backtrace" => "default",
619eb33a 429 "devcryptoeng" => "default",
9e04edf2 430 "ec_nistp_64_gcc_128" => "default",
8b1a5af3 431 "egd" => "default",
ce2596d4 432 "external-tests" => "default",
f59d0131
KR
433 "fuzz-libfuzzer" => "default",
434 "fuzz-afl" => "default",
b612799a 435 "heartbeats" => "default",
8b1a5af3 436 "md2" => "default",
29df3061 437 "msan" => "default",
8b1a5af3
MC
438 "rc5" => "default",
439 "sctp" => "default",
8b1a5af3 440 "ssl-trace" => "default",
9829b5ab
KR
441 "ssl3" => "default",
442 "ssl3-method" => "default",
c38bb727 443 "ubsan" => "default",
84a68336
MC
444 #TODO(TLS1.3): Temporarily disabled while this is a WIP
445 "tls1_3" => "default",
3556b83e 446 "tls13downgrade" => "default",
8b1a5af3
MC
447 "unit-test" => "default",
448 "weak-ssl-ciphers" => "default",
449 "zlib" => "default",
450 "zlib-dynamic" => "default",
9e04edf2 451 );
c9a112f5 452
c569e206
RL
453# Note: => pair form used for aesthetics, not to truly make a hash table
454my @disable_cascades = (
455 # "what" => [ "cascade", ... ]
7d130f68 456 sub { $config{processor} eq "386" }
c569e206
RL
457 => [ "sse2" ],
458 "ssl" => [ "ssl3" ],
459 "ssl3-method" => [ "ssl3" ],
460 "zlib" => [ "zlib-dynamic" ],
c569e206 461 "des" => [ "mdc2" ],
9e4d6fbf 462 "ec" => [ "ecdsa", "ecdh" ],
c569e206 463
3fd4d211 464 "dgram" => [ "dtls", "sctp" ],
505f74ca 465 "sock" => [ "dgram" ],
c569e206 466 "dtls" => [ @dtls ],
343a7467
RL
467 sub { 0 == scalar grep { !$disabled{$_} } @dtls }
468 => [ "dtls" ],
c569e206 469
c569e206 470 "tls" => [ @tls ],
343a7467
RL
471 sub { 0 == scalar grep { !$disabled{$_} } @tls }
472 => [ "tls" ],
c569e206 473
ef8ca6bd 474 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
343ec2b0
RL
475
476 # Without DSO, we can't load dynamic engines, so don't build them dynamic
477 "dso" => [ "dynamic-engine" ],
ae48242c
RL
478
479 # Without position independent code, there can be no shared libraries or DSOs
00698061
RL
480 "pic" => [ "shared" ],
481 "shared" => [ "dynamic-engine" ],
619eb33a 482 "engine" => [ "afalgeng", "devcryptoeng" ],
d90a6beb
MC
483
484 # no-autoalginit is only useful when building non-shared
485 "autoalginit" => [ "shared", "apps" ],
486
15a1bd0a 487 "stdio" => [ "apps", "capieng", "egd" ],
d90a6beb 488 "apps" => [ "tests" ],
302eba3f 489 "tests" => [ "external-tests" ],
3cf96e88
MC
490 "comp" => [ "zlib" ],
491 "ec" => [ "tls1_3" ],
b612799a 492 sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
29df3061
EK
493
494 sub { !$disabled{"msan"} } => [ "asm" ],
c569e206
RL
495 );
496
497# Avoid protocol support holes. Also disable all versions below N, if version
498# N is disabled while N+1 is enabled.
499#
500my @list = (reverse @tls);
501while ((my $first, my $second) = (shift @list, shift @list)) {
502 last unless @list;
503 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
504 => [ @list ] );
505 unshift @list, $second;
506}
507my @list = (reverse @dtls);
508while ((my $first, my $second) = (shift @list, shift @list)) {
509 last unless @list;
510 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
511 => [ @list ] );
512 unshift @list, $second;
513}
514
7a762197 515# Explicit "no-..." options will be collected in %disabled along with the defaults.
e4ef2e25 516# To remove something from %disabled, use "enable-foo".
7a762197
BM
517# For symmetry, "disable-foo" is a synonym for "no-foo".
518
d0590fe6 519my $no_sse2=0;
b6e4dac2 520
462ba4f6 521&usage if ($#ARGV < 0);
d02b48c6 522
bcb1977b
RL
523my $user_cflags="";
524my @user_defines=();
7d130f68
RL
525$config{openssl_api_defines}=[];
526$config{openssl_algorithm_defines}=[];
527$config{openssl_thread_defines}=[];
528$config{openssl_sys_defines}=[];
529$config{openssl_other_defines}=[];
fe05264e
RL
530my $libs="";
531my $target="";
3fa04f0d 532$config{options}="";
8864f0de 533$config{build_type} = "release";
c59cb511 534
fe05264e 535my %unsupported_options = ();
e80381e1 536my %deprecated_options = ();
8389ec4b
RS
537# If you change this, update apps/version.c
538my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
539my @seed_sources = ();
fad599f7 540while (@argvcopy)
16b6081e 541 {
fad599f7 542 $_ = shift @argvcopy;
89bea083
RL
543
544 # Support env variable assignments among the options
545 if (m|^(\w+)=(.+)?$|)
546 {
547 $config{perlenv}->{$1} = $2;
548 next;
549 }
550
7c55e22c
RL
551 # VMS is a case insensitive environment, and depending on settings
552 # out of our control, we may receive options uppercased. Let's
553 # downcase at least the part before any equal sign.
554 if ($^O eq "VMS")
555 {
556 s/^([^=]*)/lc($1)/e;
557 }
fe05264e 558 s /^-no-/no-/; # some people just can't read the instructions
c9a112f5 559
fe05264e
RL
560 # rewrite some options in "enable-..." form
561 s /^-?-?shared$/enable-shared/;
562 s /^sctp$/enable-sctp/;
563 s /^threads$/enable-threads/;
564 s /^zlib$/enable-zlib/;
565 s /^zlib-dynamic$/enable-zlib-dynamic/;
c9a112f5 566
e4ef2e25 567 if (/^(no|disable|enable)-(.+)$/)
2b1343b9
MC
568 {
569 my $word = $2;
570 if (!exists $deprecated_disablables{$word}
571 && !grep { $word =~ /^${_}$/ } @disablables)
572 {
573 $unsupported_options{$_} = 1;
574 next;
575 }
576 }
577 if (/^no-(.+)$/ || /^disable-(.+)$/)
578 {
e4ef2e25
RS
579 foreach my $proto ((@tls, @dtls))
580 {
581 if ($1 eq "$proto-method")
582 {
583 $disabled{"$proto"} = "option($proto-method)";
584 last;
585 }
586 }
587 if ($1 eq "dtls")
588 {
589 foreach my $proto (@dtls)
590 {
591 $disabled{$proto} = "option(dtls)";
592 }
c5c7700c 593 $disabled{"dtls"} = "option(dtls)";
e4ef2e25
RS
594 }
595 elsif ($1 eq "ssl")
596 {
597 # Last one of its kind
598 $disabled{"ssl3"} = "option(ssl)";
599 }
600 elsif ($1 eq "tls")
601 {
602 # XXX: Tests will fail if all SSL/TLS
603 # protocols are disabled.
604 foreach my $proto (@tls)
605 {
606 $disabled{$proto} = "option(tls)";
607 }
608 }
343ec2b0
RL
609 elsif ($1 eq "static-engine")
610 {
19ab5790 611 delete $disabled{"dynamic-engine"};
343ec2b0
RL
612 }
613 elsif ($1 eq "dynamic-engine")
614 {
19ab5790 615 $disabled{"dynamic-engine"} = "option";
343ec2b0 616 }
2b1343b9
MC
617 elsif (exists $deprecated_disablables{$1})
618 {
619 $deprecated_options{$_} = 1;
620 if (defined $deprecated_disablables{$1})
621 {
622 $disabled{$deprecated_disablables{$1}} = "option";
623 }
624 }
e4ef2e25
RS
625 else
626 {
627 $disabled{$1} = "option";
628 }
9c62a279
RL
629 # No longer an automatic choice
630 $auto_threads = 0 if ($1 eq "threads");
fe05264e 631 }
e4ef2e25 632 elsif (/^enable-(.+)$/)
fe05264e 633 {
343ec2b0
RL
634 if ($1 eq "static-engine")
635 {
19ab5790 636 $disabled{"dynamic-engine"} = "option";
343ec2b0
RL
637 }
638 elsif ($1 eq "dynamic-engine")
639 {
19ab5790 640 delete $disabled{"dynamic-engine"};
343ec2b0 641 }
25004db7
RL
642 elsif ($1 eq "zlib-dynamic")
643 {
644 delete $disabled{"zlib"};
645 }
fe05264e 646 my $algo = $1;
fe05264e 647 delete $disabled{$algo};
c9a112f5 648
9c62a279
RL
649 # No longer an automatic choice
650 $auto_threads = 0 if ($1 eq "threads");
fe05264e
RL
651 }
652 elsif (/^--strict-warnings$/)
653 {
654 $strict_warnings = 1;
655 }
656 elsif (/^--debug$/)
657 {
8864f0de 658 $config{build_type} = "debug";
fe05264e
RL
659 }
660 elsif (/^--release$/)
661 {
8864f0de 662 $config{build_type} = "release";
fe05264e
RL
663 }
664 elsif (/^386$/)
7d130f68 665 { $config{processor}=386; }
fe05264e
RL
666 elsif (/^fips$/)
667 {
b53338cb 668 die "FIPS mode not supported\n";
fe05264e
RL
669 }
670 elsif (/^rsaref$/)
671 {
672 # No RSAref support any more since it's not needed.
673 # The check for the option is there so scripts aren't
674 # broken
675 }
676 elsif (/^nofipscanistercheck$/)
677 {
b53338cb 678 die "FIPS mode not supported\n";
fe05264e
RL
679 }
680 elsif (/^[-+]/)
681 {
45c6e23c 682 if (/^--prefix=(.*)$/)
fe05264e 683 {
291e94df 684 $config{prefix}=$1;
5482dac9
RL
685 die "Directory given with --prefix MUST be absolute\n"
686 unless file_name_is_absolute($config{prefix});
c9a112f5 687 }
fe05264e 688 elsif (/^--api=(.*)$/)
0c28f277 689 {
107b5792 690 $config{api}=$1;
0c28f277 691 }
fe05264e 692 elsif (/^--libdir=(.*)$/)
9e43c6b5 693 {
107b5792 694 $config{libdir}=$1;
9e43c6b5 695 }
fe05264e 696 elsif (/^--openssldir=(.*)$/)
9e43c6b5 697 {
291e94df 698 $config{openssldir}=$1;
9e43c6b5 699 }
fe05264e 700 elsif (/^--with-zlib-lib=(.*)$/)
9fdb2cc5 701 {
20a5819f 702 $withargs{zlib_lib}=$1;
7d8bb912 703 }
fe05264e 704 elsif (/^--with-zlib-include=(.*)$/)
3eb0ed6d 705 {
da430a55 706 $withargs{zlib_include}=$1;
462ba4f6 707 }
f59d0131
KR
708 elsif (/^--with-fuzzer-lib=(.*)$/)
709 {
710 $withargs{fuzzer_lib}=$1;
711 }
712 elsif (/^--with-fuzzer-include=(.*)$/)
713 {
714 $withargs{fuzzer_include}=$1;
715 }
8389ec4b
RS
716 elsif (/^--with-rand-seed=(.*)$/)
717 {
718 foreach my $x (split(m|,|, $1))
719 {
720 die "Unknown --with-rand-seed choice $x\n"
721 if ! grep { $x eq $_ } @known_seed_sources;
722 push @seed_sources, $x;
723 }
724 }
fe05264e 725 elsif (/^--cross-compile-prefix=(.*)$/)
e5f3045f 726 {
642a6138 727 $config{cross_compile_prefix}=$1;
e5f3045f 728 }
fe05264e 729 elsif (/^--config=(.*)$/)
d02b48c6 730 {
fe05264e 731 read_config $1;
c59cb511 732 }
fe05264e 733 elsif (/^-[lL](.*)$/ or /^-Wl,/)
c9a112f5 734 {
fe05264e 735 $libs.=$_." ";
d02b48c6 736 }
b7438b43
AP
737 elsif (/^-framework$/)
738 {
739 $libs.=$_." ".shift(@argvcopy)." ";
740 }
fad599f7
RL
741 elsif (/^-rpath$/ or /^-R$/)
742 # -rpath is the OSF1 rpath flag
743 # -R is the old Solaris rpath flag
744 {
745 my $rpath = shift(@argvcopy) || "";
746 $rpath .= " " if $rpath ne "";
747 $libs.=$_." ".$rpath;
748 }
9d46752d
AP
749 elsif (/^-static$/)
750 {
751 $libs.=$_." ";
047d97af 752 $disabled{"dso"} = "forced";
9d46752d
AP
753 $disabled{"pic"} = "forced";
754 $disabled{"shared"} = "forced";
755 $disabled{"threads"} = "forced";
756 }
bcb1977b
RL
757 elsif (/^-D(.*)$/)
758 {
759 push @user_defines, $1;
760 }
fe05264e
RL
761 else # common if (/^[-+]/), just pass down...
762 {
763 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
2b91ec75 764 $user_cflags.=" ".$_;
fe05264e
RL
765 }
766 }
fe05264e
RL
767 else
768 {
769 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
770 $target=$_;
771 }
772 unless ($_ eq $target || /^no-/ || /^disable-/)
773 {
46f4e1be 774 # "no-..." follows later after implied deactivations
8483a003 775 # have been derived. (Don't take this too seriously,
fe05264e
RL
776 # we really only write OPTIONS to the Makefile out of
777 # nostalgia.)
778
3fa04f0d
RL
779 if ($config{options} eq "")
780 { $config{options} = $_; }
fe05264e 781 else
3fa04f0d 782 { $config{options} .= " ".$_; }
fbabb752 783 }
489eb740 784
107b5792
RL
785 if (defined($config{api}) && !exists $apitable->{$config{api}}) {
786 die "***** Unsupported api compatibility level: $config{api}\n",
98186eb4
VD
787 }
788
e80381e1
RL
789 if (keys %deprecated_options)
790 {
791 warn "***** Deprecated options: ",
792 join(", ", keys %deprecated_options), "\n";
793 }
489eb740
RL
794 if (keys %unsupported_options)
795 {
796 die "***** Unsupported options: ",
797 join(", ", keys %unsupported_options), "\n";
798 }
fbabb752 799 }
b6e4dac2 800
342a1a23
RL
801if ($libs =~ /(^|\s)-Wl,-rpath,/
802 && !$disabled{shared}
803 && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
804 die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
805 "***** any of asan, msan or ubsan\n";
806}
807
8389ec4b
RS
808if (scalar(@seed_sources) == 0) {
809 print "Using implicit seed configuration\n";
810 push @seed_sources, 'os';
811}
812die "Cannot seed with none and anything else"
813 if scalar(grep { $_ eq 'none' } @seed_sources) > 0
814 && scalar(@seed_sources) > 1;
815push @{$config{openssl_other_defines}},
816 map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
817 @seed_sources;
818
c569e206
RL
819my @tocheckfor = (keys %disabled);
820while (@tocheckfor) {
821 my %new_tocheckfor = ();
822 my @cascade_copy = (@disable_cascades);
823 while (@cascade_copy) {
824 my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
825 if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
2110febb 826 foreach(grep { !defined($disabled{$_}) } @$descendents) {
01d99976 827 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
2110febb 828 }
ef236ec3 829 }
c569e206
RL
830 }
831 @tocheckfor = (keys %new_tocheckfor);
832}
edc032b5 833
d63c12c6 834our $die = sub { die @_; };
436a376b 835if ($target eq "TABLE") {
d63c12c6 836 local $die = sub { warn @_; };
00ae96ca
RL
837 foreach (sort keys %table) {
838 print_table_entry($_, "TABLE");
839 }
840 exit 0;
436a376b
BM
841}
842
10a926c1 843if ($target eq "LIST") {
00ae96ca
RL
844 foreach (sort keys %table) {
845 print $_,"\n" unless $table{$_}->{template};
846 }
847 exit 0;
10a926c1
UM
848}
849
aaf878cc 850if ($target eq "HASH") {
d63c12c6 851 local $die = sub { warn @_; };
00ae96ca
RL
852 print "%table = (\n";
853 foreach (sort keys %table) {
854 print_table_entry($_, "HASH");
855 }
856 exit 0;
aaf878cc
RL
857}
858
64119271
RL
859print "Configuring OpenSSL version $config{version} ($config{version_num})\n";
860print "for $target\n";
861
00ae96ca 862# Backward compatibility?
49e04548 863if ($target =~ m/^CygWin32(-.*)$/) {
00ae96ca 864 $target = "Cygwin".$1;
49e04548
RL
865}
866
906eb3d0
RL
867# Support for legacy targets having a name starting with 'debug-'
868my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
869if ($d) {
870 $config{build_type} = "debug";
871
872 # If we do not find debug-foo in the table, the target is set to foo.
873 if (!$table{$target}) {
874 $target = $t;
875 }
876}
877$config{target} = $target;
878my %target = resolve_config($target);
879
880&usage if (!%target || $target{template});
881
793077d0
RL
882%target = ( %{$table{DEFAULTS}}, %target );
883
884# Make the flags to build DSOs the same as for shared libraries unless they
885# are already defined
886$target{dso_cflags} = $target{shared_cflag} unless defined $target{dso_cflags};
887$target{dso_cxxflags} = $target{shared_cxxflag} unless defined $target{dso_cxxflags};
888$target{dso_lflags} = $target{shared_ldflag} unless defined $target{dso_lflags};
889{
890 my $shared_info_pl =
891 catfile(dirname($0), "Configurations", "shared-info.pl");
892 my %shared_info = read_eval_file($shared_info_pl);
893 push @{$target{_conf_fname_int}}, $shared_info_pl;
894 my $si = $target{shared_target};
895 while (ref $si ne "HASH") {
896 last if ! defined $si;
897 if (ref $si eq "CODE") {
898 $si = $si->();
899 } else {
900 $si = $shared_info{$si};
901 }
902 }
903
904 # Some of the 'shared_target' values don't have any entried in
905 # %shared_info. That's perfectly fine, AS LONG AS the build file
906 # template knows how to handle this. That is currently the case for
907 # Windows and VMS.
908 if (defined $si) {
909 # Just as above, copy certain shared_* attributes to the corresponding
910 # dso_ attribute unless the latter is already defined
911 $si->{dso_cflags} = $si->{shared_cflag} unless defined $si->{dso_cflags};
912 $si->{dso_cxxflags} = $si->{shared_cxxflag} unless defined $si->{dso_cxxflags};
913 $si->{dso_lflags} = $si->{shared_ldflag} unless defined $si->{dso_lflags};
914 foreach (sort keys %$si) {
915 $target{$_} = defined $target{$_}
916 ? add($si->{$_})->($target{$_})
917 : $si->{$_};
918 }
919 }
920}
921
906eb3d0
RL
922my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
923$config{conf_files} = [ sort keys %conf_files ];
906eb3d0
RL
924
925foreach my $feature (@{$target{disable}}) {
926 if (exists $deprecated_disablables{$feature}) {
927 warn "***** config $target disables deprecated feature $feature\n";
928 } elsif (!grep { $feature eq $_ } @disablables) {
929 die "***** config $target disables unknown feature $feature\n";
930 }
931 $disabled{$feature} = 'config';
932}
933foreach my $feature (@{$target{enable}}) {
934 if ("default" eq ($disabled{$_} // "")) {
935 if (exists $deprecated_disablables{$feature}) {
936 warn "***** config $target enables deprecated feature $feature\n";
937 } elsif (!grep { $feature eq $_ } @disablables) {
938 die "***** config $target enables unknown feature $feature\n";
939 }
940 delete $disabled{$_};
941 }
942}
943
c9a112f5
BM
944foreach (sort (keys %disabled))
945 {
3fa04f0d 946 $config{options} .= " no-$_";
c9a112f5
BM
947
948 printf " no-%-12s %-10s", $_, "[$disabled{$_}]";
949
950 if (/^dso$/)
721f9058 951 { }
c9a112f5 952 elsif (/^threads$/)
22bfe05e 953 { }
c9a112f5 954 elsif (/^shared$/)
84af1bae 955 { }
ae48242c
RL
956 elsif (/^pic$/)
957 { }
c9a112f5 958 elsif (/^zlib$/)
36a30909 959 { }
19ab5790 960 elsif (/^dynamic-engine$/)
fbf002bb 961 { }
09aa263a
RL
962 elsif (/^makedepend$/)
963 { }
c9a112f5
BM
964 elsif (/^zlib-dynamic$/)
965 { }
c9a112f5
BM
966 elsif (/^sse2$/)
967 { $no_sse2 = 1; }
107b5792 968 elsif (/^engine$/)
1288f26f
RS
969 {
970 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
971 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
972 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
3e2dd30d 973 print " OPENSSL_NO_ENGINE (skip engines)";
1288f26f 974 }
c9a112f5
BM
975 else
976 {
3e2dd30d 977 my ($WHAT, $what);
c9a112f5 978
3e2dd30d
RL
979 ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/;
980
981 # Fix up C macro end names
982 $WHAT = "RMD160" if $what eq "ripemd";
983
984 # fix-up crypto/directory name(s)
985 $what = "ripemd" if $what eq "rmd160";
986 $what = "whrlpool" if $what eq "whirlpool";
987
66fe388a
RL
988 if ($what ne "async" && $what ne "err"
989 && grep { $_ eq $what } @{$config{sdirs}})
c9a112f5 990 {
3e2dd30d
RL
991 push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT";
992 @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}};
fce0ba5f 993
3e2dd30d 994 print " OPENSSL_NO_$WHAT (skip dir)";
c9a112f5
BM
995 }
996 else
997 {
3e2dd30d
RL
998 push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
999 print " OPENSSL_NO_$WHAT";
2a4af947 1000
3e2dd30d 1001 if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; }
c9a112f5
BM
1002 }
1003 }
1004
1005 print "\n";
1006 }
1007
ea241958 1008$target{cxxflags}=$target{cflags} unless defined $target{cxxflags};
107b5792 1009$target{exe_extension}="";
f99f91f1
RL
1010$target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
1011 || $config{target} =~ /^(?:Cygwin|mingw)/);
107b5792 1012$target{exe_extension}=".pm" if ($config{target} =~ /vos/);
462ba4f6 1013
e987f9f2 1014($target{shared_extension_simple}=$target{shared_extension})
d4453024 1015 =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||;
e987f9f2
RL
1016$target{dso_extension}=$target{shared_extension_simple};
1017($target{shared_import_extension}=$target{shared_extension_simple}.".a")
1018 if ($config{target} =~ /^(?:Cygwin|mingw)/);
1019
1020
7ecdf18d 1021$config{cross_compile_prefix} = env('CROSS_COMPILE')
642a6138 1022 if $config{cross_compile_prefix} eq "";
f99f41cf 1023
b0a1e8bf 1024# Allow overriding the names of some tools. USE WITH CARE
d513369b
RL
1025# Note: only Unix cares about HASHBANGPERL... that explains
1026# the default string.
758baa3d 1027$config{perl} = ($^O ne "VMS" ? $^X : "perl");
d513369b 1028$config{hashbangperl} =
7ecdf18d
RL
1029 env('HASHBANGPERL') || env('PERL') || "/usr/bin/env perl";
1030$target{cc} = env('CC') || $target{cc} || "cc";
1031$target{cxx} = env('CXX') || $target{cxx} || "c++";
1032$target{ranlib} = env('RANLIB') || $target{ranlib} ||
656bbdc6 1033 (which("$config{cross_compile_prefix}ranlib") ?
f58a0acb 1034 "\$(CROSS_COMPILE)ranlib" : "true");
7ecdf18d
RL
1035$target{ar} = env('AR') || $target{ar} || "ar";
1036$target{nm} = env('NM') || $target{nm} || "nm";
8f41ff2d 1037$target{rc} =
7ecdf18d 1038 env('RC') || env('WINDRES') || $target{rc} || "windres";
aaf878cc 1039
8b5156d1 1040# Allow overriding the build file name
7ecdf18d 1041$target{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
8b5156d1
RL
1042
1043# Cache information necessary for reconfiguration
a66234bc 1044$config{cc} = $target{cc};
ea241958 1045$config{cxx} = $target{cxx};
8b5156d1 1046$config{build_file} = $target{build_file};
a66234bc 1047
bcb1977b
RL
1048# For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
1049# or release_ attributes.
aaf878cc 1050# Do it in such a way that no spurious space is appended (hence the grep).
2952b9b8
RL
1051$config{defines} = [];
1052$config{cflags} = "";
ea241958 1053$config{cxxflags} = "";
2952b9b8
RL
1054$config{ex_libs} = "";
1055$config{shared_ldflag} = "";
bd5192b1 1056
291e94df
RL
1057# Make sure build_scheme is consistent.
1058$target{build_scheme} = [ $target{build_scheme} ]
1059 if ref($target{build_scheme}) ne "ARRAY";
1060
ddf1847d
RL
1061my ($builder, $builder_platform, @builder_opts) =
1062 @{$target{build_scheme}};
1063
d192a3aa
RL
1064foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm",
1065 $builder_platform."-checker.pm")) {
1066 my $checker_path = catfile($srcdir, "Configurations", $checker);
1067 if (-f $checker_path) {
1068 my $fn = $ENV{CONFIGURE_CHECKER_WARN}
1069 ? sub { warn $@; } : sub { die $@; };
1070 if (! do $checker_path) {
1071 if ($@) {
1072 $fn->($@);
1073 } elsif ($!) {
1074 $fn->($!);
1075 } else {
1076 $fn->("The detected tools didn't match the platform\n");
1077 }
1078 }
1079 last;
1080 }
1081}
1082
488e2b0f
RL
1083push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
1084
68ab559a 1085if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
cbecd29a 1086 {
68ab559a 1087 $config{cflags} .= " -mno-cygwin";
2952b9b8 1088 $config{shared_ldflag} .= " -mno-cygwin";
cbecd29a
AP
1089 }
1090
00b0d663 1091if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
63d8834c 1092 # minimally required architecture flags for assembly modules
107b5792
RL
1093 $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
1094 $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
63d8834c
AP
1095}
1096
2964ba8c 1097my $no_shared_warn=0;
14bcdb08 1098my $no_user_cflags=0;
bcb1977b 1099my $no_user_defines=0;
2964ba8c 1100
bc2aadad
GT
1101# The DSO code currently always implements all functions so that no
1102# applications will have to worry about that from a compilation point
1103# of view. However, the "method"s may return zero unless that platform
1104# has support compiled in for them. Currently each method is enabled
1105# by a define "DSO_<name>" ... we translate the "dso_scheme" config
1106# string entry into using the following logic;
721f9058 1107if (!$disabled{dso} && $target{dso_scheme} ne "")
bc2aadad 1108 {
291e94df
RL
1109 $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
1110 if ($target{dso_scheme} eq "DLFCN")
bc2aadad 1111 {
2952b9b8 1112 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
bc2aadad 1113 }
291e94df 1114 elsif ($target{dso_scheme} eq "DLFCN_NO_H")
bc2aadad 1115 {
2952b9b8 1116 unshift @{$config{defines}}, "DSO_DLFCN";
bc2aadad
GT
1117 }
1118 else
1119 {
2952b9b8 1120 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
bc2aadad
GT
1121 }
1122 }
9ec0126e 1123
1740c162 1124$config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
d02b48c6 1125
9c62a279
RL
1126# If threads aren't disabled, check how possible they are
1127unless ($disabled{threads}) {
1128 if ($auto_threads) {
1129 # Enabled by default, disable it forcibly if unavailable
1130 if ($target{thread_scheme} eq "(unknown)") {
1131 $disabled{threads} = "unavailable";
1132 }
1133 } else {
8483a003 1134 # The user chose to enable threads explicitly, let's see
9c62a279
RL
1135 # if there's a chance that's possible
1136 if ($target{thread_scheme} eq "(unknown)") {
1137 # If the user asked for "threads" and we don't have internal
1138 # knowledge how to do it, [s]he is expected to provide any
1139 # system-dependent compiler options that are necessary. We
1140 # can't truly check that the given options are correct, but
1141 # we expect the user to know what [s]He is doing.
1142 if ($no_user_cflags && $no_user_defines) {
1143 die "You asked for multi-threading support, but didn't\n"
1144 ,"provide any system-specific compiler options\n";
1145 }
1146 }
1147 }
1148}
1149
1150# If threads still aren't disabled, add a C macro to ensure the source
1151# code knows about it. Any other flag is taken care of by the configs.
1152unless($disabled{threads}) {
1153 foreach (("defines", "openssl_thread_defines")) {
1154 push @{$config{$_}}, "OPENSSL_THREADS";
1155 }
1156}
e452de9d 1157
98186eb4
VD
1158# With "deprecated" disable all deprecated features.
1159if (defined($disabled{"deprecated"})) {
107b5792 1160 $config{api} = $maxapi;
98186eb4 1161}
07c4c14c 1162
291e94df 1163if ($target{shared_target} eq "")
6f7ac8e1 1164 {
ae48242c 1165 $no_shared_warn = 1
b53338cb 1166 if (!$disabled{shared} || !$disabled{"dynamic-engine"});
84af1bae 1167 $disabled{shared} = "no-shared-target";
ae48242c
RL
1168 $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1169 "no-shared-target";
6f7ac8e1 1170 }
b436a982 1171
19ab5790 1172if ($disabled{"dynamic-engine"}) {
343ec2b0
RL
1173 push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1174 $config{dynamic_engines} = 0;
19ab5790
RL
1175} else {
1176 push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1177 $config{dynamic_engines} = 1;
343ec2b0 1178}
ecd45314 1179
c38bb727
BL
1180unless ($disabled{asan}) {
1181 $config{cflags} .= "-fsanitize=address ";
1182}
1183
1184unless ($disabled{ubsan}) {
f430ba31 1185 # -DPEDANTIC or -fnosanitize=alignment may also be required on some
c38bb727
BL
1186 # platforms.
1187 $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
1188}
1189
29df3061
EK
1190unless ($disabled{msan}) {
1191 $config{cflags} .= "-fsanitize=memory ";
1192}
1193
65cc6d5c 1194unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
29df3061 1195 && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
c38bb727
BL
1196 $config{cflags} .= "-fno-omit-frame-pointer -g ";
1197}
c313e32a
AP
1198#
1199# Platform fix-ups
1200#
ae48242c
RL
1201
1202# This saves the build files from having to check
1203if ($disabled{pic})
1204 {
793077d0
RL
1205 foreach (qw(shared_cflag shared_cxxflag shared_ldflag
1206 dso_cflags dso_cxxflags dso_lflags))
1207 {
1208 $target{$_} = "";
1209 }
ae48242c 1210 }
4f16039e
RL
1211else
1212 {
1213 push @{$config{defines}}, "OPENSSL_PIC";
1214 }
ae48242c 1215
291e94df 1216if ($target{sys_id} ne "")
cf1b7d96 1217 {
642a6138 1218 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
cf1b7d96
RL
1219 }
1220
00b0d663 1221unless ($disabled{asm}) {
d2b2221a 1222 $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
9fe2bb77 1223 $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
f8c469de 1224
9e0724a1 1225 # bn-586 is the only one implementing bn_*_part_words
bcb1977b
RL
1226 push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1227 push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
dfeab068 1228
bcb1977b
RL
1229 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1230 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1231 push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
5ac7bde7 1232
9fe2bb77 1233 if ($target{sha1_asm_src}) {
bcb1977b
RL
1234 push @{$config{defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1235 push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1236 push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
9e0724a1 1237 }
216e8d91
RL
1238 if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
1239 push @{$config{defines}}, "RC4_ASM";
1240 }
9fe2bb77 1241 if ($target{md5_asm_src}) {
bcb1977b 1242 push @{$config{defines}}, "MD5_ASM";
9e0724a1 1243 }
d2b2221a 1244 $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
9fe2bb77 1245 if ($target{rmd160_asm_src}) {
bcb1977b 1246 push @{$config{defines}}, "RMD160_ASM";
9e0724a1 1247 }
9fe2bb77 1248 if ($target{aes_asm_src}) {
bcb1977b 1249 push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
9fe2bb77 1250 # aes-ctr.fake is not a real file, only indication that assembler
874a3757 1251 # module implements AES_ctr32_encrypt...
bcb1977b 1252 push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
9fe2bb77 1253 # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
bcb1977b 1254 push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
9fe2bb77 1255 $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
bcb1977b
RL
1256 push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1257 push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
9e0724a1 1258 }
9fe2bb77 1259 if ($target{wp_asm_src} =~ /mmx/) {
46d4d865 1260 if ($config{processor} eq "386") {
d2b2221a 1261 $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
46d4d865 1262 } elsif (!$disabled{"whirlpool"}) {
2952b9b8 1263 push @{$config{defines}}, "WHIRLPOOL_ASM";
46d4d865 1264 }
9e0724a1 1265 }
9fe2bb77 1266 if ($target{modes_asm_src} =~ /ghash-/) {
bcb1977b 1267 push @{$config{defines}}, "GHASH_ASM";
9e0724a1 1268 }
9fe2bb77 1269 if ($target{ec_asm_src} =~ /ecp_nistz256/) {
bcb1977b 1270 push @{$config{defines}}, "ECP_NISTZ256_ASM";
9e0724a1 1271 }
7b176a54
RL
1272 if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
1273 push @{$config{defines}}, "PADLOCK_ASM";
1274 }
9fe2bb77 1275 if ($target{poly1305_asm_src} ne "") {
bcb1977b 1276 push @{$config{defines}}, "POLY1305_ASM";
9e0724a1
RL
1277 }
1278}
d02b48c6 1279
6d75a83c 1280my %predefined = compiler_predefined($target{cc});
54cf3b98 1281
6d75a83c
RL
1282if (!$disabled{makedepend}) {
1283 # We know that GNU C version 3 and up as well as all clang
1284 # versions support dependency generation
1285 if ($predefined{__GNUC__} >= 3) {
1286 $config{makedepprog} = "\$(CROSS_COMPILE)$target{cc}";
1287 } else {
1288 $config{makedepprog} = which('makedepend');
1289 $disabled{makedepend} = "unavailable" unless $config{makedepprog};
54cf3b98 1290 }
f1f07a23 1291}
8ed40b83 1292
7d130f68
RL
1293
1294# Deal with bn_ops ###################################################
1295
7d130f68 1296$config{bn_ll} =0;
7d130f68
RL
1297$config{export_var_as_fn} =0;
1298my $def_int="unsigned int";
1299$config{rc4_int} =$def_int;
b4f35e5e 1300($config{b64l},$config{b64},$config{b32})=(0,0,1);
7d130f68 1301
94af0cd7 1302my $count = 0;
7d130f68 1303foreach (sort split(/\s+/,$target{bn_ops})) {
94af0cd7
RS
1304 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1305 $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN';
1306 $config{bn_ll}=1 if $_ eq 'BN_LLONG';
1307 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
1308 ($config{b64l},$config{b64},$config{b32})
1309 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
1310 ($config{b64l},$config{b64},$config{b32})
1311 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
1312 ($config{b64l},$config{b64},$config{b32})
1313 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
7d130f68 1314}
94af0cd7
RS
1315die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1316 if $count > 1;
7d130f68
RL
1317
1318
1319# Hack cflags for better warnings (dev option) #######################
1320
1ed0c662
RL
1321# "Stringify" the C flags string. This permits it to be made part of a string
1322# and works as well on command lines.
01d99976 1323$config{cflags} =~ s/([\\\"])/\\$1/g;
b436a982 1324
107b5792
RL
1325if (defined($config{api})) {
1326 $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
bcb1977b 1327 my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
bcb1977b 1328 push @{$config{defines}}, $apiflag;
98186eb4
VD
1329}
1330
3a154864
AP
1331if (defined($predefined{__clang__}) && !$disabled{asm}) {
1332 $config{cflags} .= " -Qunused-arguments";
1333}
1334
0c28f277
DSH
1335if ($strict_warnings)
1336 {
1337 my $wopt;
6d50589c
AP
1338 my $gccver = $predefined{__GNUC__} // -1;
1339
1340 die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
1341 unless $gccver >= 4;
1342 $gcc_devteam_warn .= " -Wmisleading-indentation" if $gccver >= 6;
0c28f277
DSH
1343 foreach $wopt (split /\s+/, $gcc_devteam_warn)
1344 {
d918f9cb 1345 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
0c28f277 1346 }
54cf3b98 1347 if (defined($predefined{__clang__}))
190c8c60
BL
1348 {
1349 foreach $wopt (split /\s+/, $clang_devteam_warn)
1350 {
d918f9cb 1351 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
190c8c60
BL
1352 }
1353 }
ef8ca6bd
RL
1354 }
1355
1356unless ($disabled{"crypto-mdebug-backtrace"})
1357 {
1358 foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
a1d3f3d1 1359 {
d918f9cb 1360 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
ef8ca6bd
RL
1361 }
1362 if ($target =~ /^BSD-/)
1363 {
1364 $config{ex_libs} .= " -lexecinfo";
291e94df 1365 }
0c28f277
DSH
1366 }
1367
7cb58c0f 1368if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; $config{cxxflags}="$config{cxxflags}$user_cflags";}
63994098
RL
1369else { $no_user_cflags=1; }
1370if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1371else { $no_user_defines=1; }
1372
1373# ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1374
c91a0a83
EK
1375unless ($disabled{afalgeng}) {
1376 $config{afalgeng}="";
79fff39d
RL
1377 if ($target =~ m/^linux/) {
1378 my $minver = 4*10000 + 1*100 + 0;
1379 if ($config{cross_compile_prefix} eq "") {
1380 my $verstr = `uname -r`;
1381 my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1382 ($mi2) = $mi2 =~ /(\d+)/;
1383 my $ver = $ma*10000 + $mi1*100 + $mi2;
1384 if ($ver < $minver) {
c91a0a83 1385 $disabled{afalgeng} = "too-old-kernel";
79fff39d
RL
1386 } else {
1387 push @{$config{engdirs}}, "afalg";
1388 }
68dc37c1
MC
1389 } else {
1390 $disabled{afalgeng} = "cross-compiling";
6cba4a66 1391 }
79fff39d 1392 } else {
c91a0a83 1393 $disabled{afalgeng} = "not-linux";
7f458a48 1394 }
1395}
8da00a38 1396
c91a0a83 1397push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
7f458a48 1398
9fe2bb77
RL
1399# If we use the unified build, collect information from build.info files
1400my %unified_info = ();
1401
2b6b606c 1402my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
ddf1847d 1403if ($builder eq "unified") {
9fe2bb77
RL
1404 use with_fallback qw(Text::Template);
1405
9fe2bb77 1406 sub cleandir {
2e963849 1407 my $base = shift;
9fe2bb77 1408 my $dir = shift;
2e963849
RL
1409 my $relativeto = shift || ".";
1410
1411 $dir = catdir($base,$dir) unless isabsolute($dir);
9fe2bb77 1412
ec182ef0
RL
1413 # Make sure the directories we're building in exists
1414 mkpath($dir);
1415
2e963849 1416 my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
9fe2bb77
RL
1417 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1418 return $res;
1419 }
1420
1421 sub cleanfile {
2e963849 1422 my $base = shift;
9fe2bb77 1423 my $file = shift;
2e963849
RL
1424 my $relativeto = shift || ".";
1425
1426 $file = catfile($base,$file) unless isabsolute($file);
1427
9fe2bb77
RL
1428 my $d = dirname($file);
1429 my $f = basename($file);
1430
ec182ef0
RL
1431 # Make sure the directories we're building in exists
1432 mkpath($d);
1433
2e963849 1434 my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
9fe2bb77
RL
1435 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1436 return $res;
1437 }
1438
1967a42e
RL
1439 # Store the name of the template file we will build the build file from
1440 # in %config. This may be useful for the build file itself.
1441 my @build_file_template_names =
1442 ( $builder_platform."-".$target{build_file}.".tmpl",
1443 $target{build_file}.".tmpl" );
1444 my @build_file_templates = ();
1445
1446 # First, look in the user provided directory, if given
7ecdf18d 1447 if (defined env($local_config_envname)) {
1967a42e
RL
1448 @build_file_templates =
1449 map {
1450 if ($^O eq 'VMS') {
1451 # VMS environment variables are logical names,
1452 # which can be used as is
1453 $local_config_envname . ':' . $_;
1454 } else {
7ecdf18d 1455 catfile(env($local_config_envname), $_);
1967a42e
RL
1456 }
1457 }
1458 @build_file_template_names;
1459 }
1460 # Then, look in our standard directory
1461 push @build_file_templates,
1462 ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1463 @build_file_template_names );
1464
1465 my $build_file_template;
1466 for $_ (@build_file_templates) {
1467 $build_file_template = $_;
1468 last if -f $build_file_template;
1469
1470 $build_file_template = undef;
1471 }
1472 if (!defined $build_file_template) {
1473 die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1474 }
1475 $config{build_file_templates}
1476 = [ $build_file_template,
1477 cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1478 $blddir) ];
1479
9fe2bb77
RL
1480 my @build_infos = ( [ ".", "build.info" ] );
1481 foreach (@{$config{dirs}}) {
1482 push @build_infos, [ $_, "build.info" ]
1483 if (-f catfile($srcdir, $_, "build.info"));
1484 }
1485 foreach (@{$config{sdirs}}) {
1486 push @build_infos, [ catdir("crypto", $_), "build.info" ]
1487 if (-f catfile($srcdir, "crypto", $_, "build.info"));
1488 }
1489 foreach (@{$config{engdirs}}) {
1490 push @build_infos, [ catdir("engines", $_), "build.info" ]
1491 if (-f catfile($srcdir, "engines", $_, "build.info"));
1492 }
cfa76979
RL
1493 foreach (@{$config{tdirs}}) {
1494 push @build_infos, [ catdir("test", $_), "build.info" ]
1495 if (-f catfile($srcdir, "test", $_, "build.info"));
1496 }
9fe2bb77 1497
2e0956ba
RL
1498 $config{build_infos} = [ ];
1499
9fe2bb77
RL
1500 foreach (@build_infos) {
1501 my $sourced = catdir($srcdir, $_->[0]);
1502 my $buildd = catdir($blddir, $_->[0]);
1503
dca99383 1504 mkpath($buildd);
9fe2bb77
RL
1505
1506 my $f = $_->[1];
1507 # The basic things we're trying to build
1508 my @programs = ();
7f5af797 1509 my @programs_install = ();
9fe2bb77 1510 my @libraries = ();
7f5af797 1511 my @libraries_install = ();
9fe2bb77 1512 my @engines = ();
7f5af797 1513 my @engines_install = ();
9fe2bb77 1514 my @scripts = ();
7f5af797 1515 my @scripts_install = ();
9fe2bb77 1516 my @extra = ();
8a67946e 1517 my @overrides = ();
9fe2bb77
RL
1518 my @intermediates = ();
1519 my @rawlines = ();
1520
1521 my %ordinals = ();
1522 my %sources = ();
2a08d1a0 1523 my %shared_sources = ();
9fe2bb77
RL
1524 my %includes = ();
1525 my %depends = ();
1526 my %renames = ();
1527 my %sharednames = ();
ae4c7450 1528 my %generate = ();
9fe2bb77 1529
2e0956ba 1530 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
cb6afcd6
RL
1531 my $template =
1532 Text::Template->new(TYPE => 'FILE',
1533 SOURCE => catfile($sourced, $f),
1534 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
9fe2bb77
RL
1535 die "Something went wrong with $sourced/$f: $!\n" unless $template;
1536 my @text =
1537 split /^/m,
1538 $template->fill_in(HASH => { config => \%config,
1539 target => \%target,
9e04edf2 1540 disabled => \%disabled,
f59d0131 1541 withargs => \%withargs,
9fe2bb77
RL
1542 builddir => abs2rel($buildd, $blddir),
1543 sourcedir => abs2rel($sourced, $blddir),
1544 buildtop => abs2rel($blddir, $blddir),
1545 sourcetop => abs2rel($srcdir, $blddir) },
1546 DELIMITERS => [ "{-", "-}" ]);
1547
1548 # The top item of this stack has the following values
1549 # -2 positive already run and we found ELSE (following ELSIF should fail)
1550 # -1 positive already run (skip until ENDIF)
1551 # 0 negatives so far (if we're at a condition, check it)
1552 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1553 # 2 positive ELSE (following ELSIF should fail)
1554 my @skip = ();
1555 collect_information(
1556 collect_from_array([ @text ],
1557 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1558 $l1 =~ s/\\$//; $l1.$l2 }),
1559 # Info we're looking for
1560 qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
635bd409 1561 => sub {
c5798e0e 1562 if (! @skip || $skip[$#skip] > 0) {
635bd409
RL
1563 push @skip, !! $1;
1564 } else {
1565 push @skip, -1;
1566 }
1567 },
9fe2bb77
RL
1568 qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1569 => sub { die "ELSIF out of scope" if ! @skip;
1570 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1571 $skip[$#skip] = -1 if $skip[$#skip] != 0;
1572 $skip[$#skip] = !! $1
1573 if $skip[$#skip] == 0; },
1574 qr/^\s*ELSE\s*$/
1575 => sub { die "ELSE out of scope" if ! @skip;
1576 $skip[$#skip] = -2 if $skip[$#skip] != 0;
1577 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1578 qr/^\s*ENDIF\s*$/
1579 => sub { die "ENDIF out of scope" if ! @skip;
1580 pop @skip; },
7f5af797
RL
1581 qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1582 => sub {
1583 if (!@skip || $skip[$#skip] > 0) {
1584 my $install = $1;
1585 my @x = tokenize($2);
1586 push @programs, @x;
1587 push @programs_install, @x unless $install;
1588 }
1589 },
1590 qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1591 => sub {
1592 if (!@skip || $skip[$#skip] > 0) {
1593 my $install = $1;
1594 my @x = tokenize($2);
1595 push @libraries, @x;
1596 push @libraries_install, @x unless $install;
1597 }
1598 },
1599 qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1600 => sub {
1601 if (!@skip || $skip[$#skip] > 0) {
1602 my $install = $1;
1603 my @x = tokenize($2);
1604 push @engines, @x;
1605 push @engines_install, @x unless $install;
1606 }
1607 },
1608 qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1609 => sub {
1610 if (!@skip || $skip[$#skip] > 0) {
1611 my $install = $1;
1612 my @x = tokenize($2);
1613 push @scripts, @x;
1614 push @scripts_install, @x unless $install;
1615 }
1616 },
9fe2bb77 1617 qr/^\s*EXTRA\s*=\s*(.*)\s*$/
ce959812 1618 => sub { push @extra, tokenize($1)
9fe2bb77 1619 if !@skip || $skip[$#skip] > 0 },
8a67946e 1620 qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
ce959812 1621 => sub { push @overrides, tokenize($1)
8a67946e 1622 if !@skip || $skip[$#skip] > 0 },
9fe2bb77
RL
1623
1624 qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
ce959812 1625 => sub { push @{$ordinals{$1}}, tokenize($2)
9fe2bb77
RL
1626 if !@skip || $skip[$#skip] > 0 },
1627 qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
ce959812 1628 => sub { push @{$sources{$1}}, tokenize($2)
9fe2bb77 1629 if !@skip || $skip[$#skip] > 0 },
2a08d1a0 1630 qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
ce959812 1631 => sub { push @{$shared_sources{$1}}, tokenize($2)
2a08d1a0 1632 if !@skip || $skip[$#skip] > 0 },
9fe2bb77 1633 qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
ce959812 1634 => sub { push @{$includes{$1}}, tokenize($2)
9fe2bb77 1635 if !@skip || $skip[$#skip] > 0 },
4f858293 1636 qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
ce959812 1637 => sub { push @{$depends{$1}}, tokenize($2)
9fe2bb77 1638 if !@skip || $skip[$#skip] > 0 },
ae4c7450
RL
1639 qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1640 => sub { push @{$generate{$1}}, $2
1641 if !@skip || $skip[$#skip] > 0 },
9fe2bb77 1642 qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
ce959812 1643 => sub { push @{$renames{$1}}, tokenize($2)
9fe2bb77
RL
1644 if !@skip || $skip[$#skip] > 0 },
1645 qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
ce959812 1646 => sub { push @{$sharednames{$1}}, tokenize($2)
9fe2bb77
RL
1647 if !@skip || $skip[$#skip] > 0 },
1648 qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1649 => sub {
1650 my $lineiterator = shift;
1651 my $target_kind = $1;
1652 while (defined $lineiterator->()) {
04f171c0 1653 s|\R$||;
9fe2bb77
RL
1654 if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1655 die "ENDRAW doesn't match BEGINRAW"
1656 if $1 ne $target_kind;
1657 last;
1658 }
1659 next if @skip && $skip[$#skip] <= 0;
1660 push @rawlines, $_
1661 if ($target_kind eq $target{build_file}
ddf1847d 1662 || $target_kind eq $target{build_file}."(".$builder_platform.")");
9fe2bb77
RL
1663 }
1664 },
ab6e147c 1665 qr/^\s*(?:#.*)?$/ => sub { },
2b6b606c
RL
1666 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1667 "BEFORE" => sub {
1668 if ($buildinfo_debug) {
1669 print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1670 print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1671 }
1672 },
1673 "AFTER" => sub {
1674 if ($buildinfo_debug) {
1675 print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1676 }
1677 },
9fe2bb77
RL
1678 );
1679 die "runaway IF?" if (@skip);
1680
1681 foreach (keys %renames) {
1682 die "$_ renamed to more than one thing: "
1683 ,join(" ", @{$renames{$_}}),"\n"
1684 if scalar @{$renames{$_}} > 1;
2e963849
RL
1685 my $dest = cleanfile($buildd, $_, $blddir);
1686 my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
9fe2bb77
RL
1687 die "$dest renamed to more than one thing: "
1688 ,$unified_info{rename}->{$dest}, $to
1689 unless !defined($unified_info{rename}->{$dest})
1690 or $unified_info{rename}->{$dest} eq $to;
1691 $unified_info{rename}->{$dest} = $to;
1692 }
1693
1694 foreach (@programs) {
2e963849 1695 my $program = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1696 if ($unified_info{rename}->{$program}) {
1697 $program = $unified_info{rename}->{$program};
1698 }
1699 $unified_info{programs}->{$program} = 1;
1700 }
1701
7f5af797
RL
1702 foreach (@programs_install) {
1703 my $program = cleanfile($buildd, $_, $blddir);
1704 if ($unified_info{rename}->{$program}) {
1705 $program = $unified_info{rename}->{$program};
1706 }
1707 $unified_info{install}->{programs}->{$program} = 1;
1708 }
1709
9fe2bb77 1710 foreach (@libraries) {
2e963849 1711 my $library = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1712 if ($unified_info{rename}->{$library}) {
1713 $library = $unified_info{rename}->{$library};
1714 }
1715 $unified_info{libraries}->{$library} = 1;
1716 }
1717
7f5af797
RL
1718 foreach (@libraries_install) {
1719 my $library = cleanfile($buildd, $_, $blddir);
1720 if ($unified_info{rename}->{$library}) {
1721 $library = $unified_info{rename}->{$library};
1722 }
1723 $unified_info{install}->{libraries}->{$library} = 1;
1724 }
1725
343ec2b0 1726 die <<"EOF" if scalar @engines and !$config{dynamic_engines};
19ab5790 1727ENGINES can only be used if configured with 'dynamic-engine'.
9fe2bb77
RL
1728This is usually a fault in a build.info file.
1729EOF
1730 foreach (@engines) {
2e963849 1731 my $library = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1732 if ($unified_info{rename}->{$library}) {
1733 $library = $unified_info{rename}->{$library};
1734 }
1735 $unified_info{engines}->{$library} = 1;
1736 }
1737
7f5af797
RL
1738 foreach (@engines_install) {
1739 my $library = cleanfile($buildd, $_, $blddir);
1740 if ($unified_info{rename}->{$library}) {
1741 $library = $unified_info{rename}->{$library};
1742 }
1743 $unified_info{install}->{engines}->{$library} = 1;
1744 }
1745
9fe2bb77 1746 foreach (@scripts) {
2e963849 1747 my $script = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1748 if ($unified_info{rename}->{$script}) {
1749 $script = $unified_info{rename}->{$script};
1750 }
1751 $unified_info{scripts}->{$script} = 1;
1752 }
1753
7f5af797
RL
1754 foreach (@scripts_install) {
1755 my $script = cleanfile($buildd, $_, $blddir);
1756 if ($unified_info{rename}->{$script}) {
1757 $script = $unified_info{rename}->{$script};
1758 }
1759 $unified_info{install}->{scripts}->{$script} = 1;
1760 }
1761
9fe2bb77 1762 foreach (@extra) {
2e963849 1763 my $extra = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1764 $unified_info{extra}->{$extra} = 1;
1765 }
1766
8a67946e
RL
1767 foreach (@overrides) {
1768 my $override = cleanfile($buildd, $_, $blddir);
1769 $unified_info{overrides}->{$override} = 1;
1770 }
1771
9fe2bb77
RL
1772 push @{$unified_info{rawlines}}, @rawlines;
1773
84af1bae 1774 unless ($disabled{shared}) {
9fe2bb77
RL
1775 # Check sharednames.
1776 foreach (keys %sharednames) {
2e963849 1777 my $dest = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1778 if ($unified_info{rename}->{$dest}) {
1779 $dest = $unified_info{rename}->{$dest};
1780 }
1781 die "shared_name for $dest with multiple values: "
1782 ,join(" ", @{$sharednames{$_}}),"\n"
1783 if scalar @{$sharednames{$_}} > 1;
2e963849 1784 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
9fe2bb77
RL
1785 die "shared_name found for a library $dest that isn't defined\n"
1786 unless $unified_info{libraries}->{$dest};
1787 die "shared_name for $dest with multiple values: "
1788 ,$unified_info{sharednames}->{$dest}, ", ", $to
1789 unless !defined($unified_info{sharednames}->{$dest})
1790 or $unified_info{sharednames}->{$dest} eq $to;
1791 $unified_info{sharednames}->{$dest} = $to;
1792 }
1793
1794 # Additionally, we set up sharednames for libraries that don't
33105818 1795 # have any, as themselves. Only for libraries that aren't
46f4e1be 1796 # explicitly static.
33105818 1797 foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) {
9fe2bb77
RL
1798 if (!defined $unified_info{sharednames}->{$_}) {
1799 $unified_info{sharednames}->{$_} = $_
1800 }
1801 }
33105818
RL
1802
1803 # Check that we haven't defined any library as both shared and
46f4e1be 1804 # explicitly static. That is forbidden.
33105818
RL
1805 my @doubles = ();
1806 foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
1807 (my $l = $_) =~ s/\.a$//;
1808 push @doubles, $l if defined $unified_info{sharednames}->{$l};
1809 }
46f4e1be 1810 die "these libraries are both explicitly static and shared:\n ",
33105818
RL
1811 join(" ", @doubles), "\n"
1812 if @doubles;
9fe2bb77
RL
1813 }
1814
1815 foreach (keys %ordinals) {
1816 my $dest = $_;
2e963849 1817 my $ddest = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1818 if ($unified_info{rename}->{$ddest}) {
1819 $ddest = $unified_info{rename}->{$ddest};
1820 }
1821 foreach (@{$ordinals{$dest}}) {
1822 my %known_ordinals =
1823 (
1824 crypto =>
6928b617 1825 cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
9fe2bb77 1826 ssl =>
6928b617 1827 cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
9fe2bb77
RL
1828 );
1829 my $o = $known_ordinals{$_};
1830 die "Ordinals for $ddest defined more than once\n"
1831 if $unified_info{ordinals}->{$ddest};
1832 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1833 }
1834 }
1835
1836 foreach (keys %sources) {
1837 my $dest = $_;
2e963849 1838 my $ddest = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1839 if ($unified_info{rename}->{$ddest}) {
1840 $ddest = $unified_info{rename}->{$ddest};
1841 }
1842 foreach (@{$sources{$dest}}) {
2e963849 1843 my $s = cleanfile($sourced, $_, $blddir);
9fe2bb77
RL
1844
1845 # If it isn't in the source tree, we assume it's generated
1846 # in the build tree
1847 if (! -f $s) {
2e963849 1848 $s = cleanfile($buildd, $_, $blddir);
9fe2bb77 1849 }
ea241958
RL
1850 # We recognise C++, C and asm files
1851 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1852 my $o = $_;
1853 $o =~ s/\.[csS]$/.o/; # C and assembler
1854 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2e963849 1855 $o = cleanfile($buildd, $o, $blddir);
9fe2bb77
RL
1856 $unified_info{sources}->{$ddest}->{$o} = 1;
1857 $unified_info{sources}->{$o}->{$s} = 1;
1858 } else {
1859 $unified_info{sources}->{$ddest}->{$s} = 1;
1860 }
1861 }
1862 }
1863
2a08d1a0
RL
1864 foreach (keys %shared_sources) {
1865 my $dest = $_;
1866 my $ddest = cleanfile($buildd, $_, $blddir);
1867 if ($unified_info{rename}->{$ddest}) {
1868 $ddest = $unified_info{rename}->{$ddest};
1869 }
1870 foreach (@{$shared_sources{$dest}}) {
1871 my $s = cleanfile($sourced, $_, $blddir);
1872
1873 # If it isn't in the source tree, we assume it's generated
1874 # in the build tree
1875 if (! -f $s) {
1876 $s = cleanfile($buildd, $_, $blddir);
1877 }
ea241958
RL
1878 # We recognise C++, C and asm files
1879 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1880 my $o = $_;
1881 $o =~ s/\.[csS]$/.o/; # C and assembler
1882 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2a08d1a0
RL
1883 $o = cleanfile($buildd, $o, $blddir);
1884 $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1885 $unified_info{sources}->{$o}->{$s} = 1;
1886 } else {
1887 die "unrecognised source file type for shared library: $s\n";
1888 }
1889 }
1890 }
1891
ae4c7450
RL
1892 foreach (keys %generate) {
1893 my $dest = $_;
1894 my $ddest = cleanfile($buildd, $_, $blddir);
1895 if ($unified_info{rename}->{$ddest}) {
1896 $ddest = $unified_info{rename}->{$ddest};
1897 }
1898 die "more than one generator for $dest: "
1899 ,join(" ", @{$generate{$_}}),"\n"
1900 if scalar @{$generate{$_}} > 1;
1901 my @generator = split /\s+/, $generate{$dest}->[0];
1902 $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1903 $unified_info{generate}->{$ddest} = [ @generator ];
1904 }
1905
9fe2bb77
RL
1906 foreach (keys %depends) {
1907 my $dest = $_;
4f858293 1908 my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
8d34daf0
RL
1909
1910 # If the destination doesn't exist in source, it can only be
1911 # a generated file in the build tree.
4f858293 1912 if ($ddest ne "" && ! -f $ddest) {
8d34daf0
RL
1913 $ddest = cleanfile($buildd, $_, $blddir);
1914 if ($unified_info{rename}->{$ddest}) {
1915 $ddest = $unified_info{rename}->{$ddest};
1916 }
9fe2bb77
RL
1917 }
1918 foreach (@{$depends{$dest}}) {
2e963849 1919 my $d = cleanfile($sourced, $_, $blddir);
9fe2bb77 1920
e737d7b1
RL
1921 # If we know it's generated, or assume it is because we can't
1922 # find it in the source tree, we set file we depend on to be
1923 # in the build tree rather than the source tree, and assume
1924 # and that there are lines to build it in a BEGINRAW..ENDRAW
1925 # section or in the Makefile template.
1926 if (! -f $d
da1f2104
RL
1927 || (grep { $d eq $_ }
1928 map { cleanfile($srcdir, $_, $blddir) }
4f858293 1929 grep { /\.h$/ } keys %{$unified_info{generate}})) {
2e963849 1930 $d = cleanfile($buildd, $_, $blddir);
9fe2bb77
RL
1931 }
1932 # Take note if the file to depend on is being renamed
186a31e5
RL
1933 # Take extra care with files ending with .a, they should
1934 # be treated without that extension, and the extension
1935 # should be added back after treatment.
1936 $d =~ /(\.a)?$/;
1937 my $e = $1 // "";
1938 $d = $`;
9fe2bb77
RL
1939 if ($unified_info{rename}->{$d}) {
1940 $d = $unified_info{rename}->{$d};
1941 }
186a31e5 1942 $d .= $e;
9fe2bb77 1943 $unified_info{depends}->{$ddest}->{$d} = 1;
8d34daf0
RL
1944 # If we depend on a header file or a perl module, let's make
1945 # sure it can get included
4f858293 1946 if ($dest ne "" && $d =~ /\.(h|pm)$/) {
9fe2bb77 1947 my $i = dirname($d);
4748f890
RL
1948 push @{$unified_info{includes}->{$ddest}->{source}}, $i
1949 unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}};
9fe2bb77
RL
1950 }
1951 }
1952 }
1953
1954 foreach (keys %includes) {
1955 my $dest = $_;
8d34daf0
RL
1956 my $ddest = cleanfile($sourced, $_, $blddir);
1957
1958 # If the destination doesn't exist in source, it can only be
1959 # a generated file in the build tree.
1960 if (! -f $ddest) {
1961 $ddest = cleanfile($buildd, $_, $blddir);
1962 if ($unified_info{rename}->{$ddest}) {
1963 $ddest = $unified_info{rename}->{$ddest};
1964 }
9fe2bb77
RL
1965 }
1966 foreach (@{$includes{$dest}}) {
4748f890
RL
1967 my $is = cleandir($sourced, $_, $blddir);
1968 my $ib = cleandir($buildd, $_, $blddir);
1969 push @{$unified_info{includes}->{$ddest}->{source}}, $is
1970 unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
1971 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
1972 unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
9fe2bb77
RL
1973 }
1974 }
1975 }
1976
1977 ### Make unified_info a bit more efficient
1978 # One level structures
8a67946e 1979 foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
9fe2bb77
RL
1980 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1981 }
1982 # Two level structures
7f5af797 1983 foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
9fe2bb77
RL
1984 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1985 $unified_info{$l1}->{$l2} =
1986 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1987 }
1988 }
4748f890
RL
1989 # Includes
1990 foreach my $dest (sort keys %{$unified_info{includes}}) {
1991 if (defined($unified_info{includes}->{$dest}->{build})) {
1992 my @source_includes =
1993 ( @{$unified_info{includes}->{$dest}->{source}} );
1994 $unified_info{includes}->{$dest} =
1995 [ @{$unified_info{includes}->{$dest}->{build}} ];
1996 foreach my $inc (@source_includes) {
1997 push @{$unified_info{includes}->{$dest}}, $inc
1998 unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
1999 }
2000 } else {
2001 $unified_info{includes}->{$dest} =
2002 [ @{$unified_info{includes}->{$dest}->{source}} ];
2003 }
2004 }
9fe2bb77
RL
2005}
2006
2007# For the schemes that need it, we provide the old *_obj configs
2008# from the *_asm_obj ones
3a55c92b 2009foreach (grep /_(asm|aux)_src$/, keys %target) {
9fe2bb77 2010 my $src = $_;
3a55c92b 2011 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
ea241958
RL
2012 $target{$obj} = $target{$src};
2013 $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
2014 $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
9fe2bb77
RL
2015}
2016
291e94df
RL
2017# Write down our configuration where it fits #########################
2018
2019open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
2020print OUT <<"EOF";
2021package configdata;
2022
2023use strict;
2024use warnings;
2025
2026use Exporter;
2027#use vars qw(\@ISA \@EXPORT);
2028our \@ISA = qw(Exporter);
3850f8cb 2029our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
291e94df
RL
2030
2031EOF
2032print OUT "our %config = (\n";
2033foreach (sort keys %config) {
2034 if (ref($config{$_}) eq "ARRAY") {
2035 print OUT " ", $_, " => [ ", join(", ",
2036 map { quotify("perl", $_) }
2037 @{$config{$_}}), " ],\n";
7ecdf18d
RL
2038 } elsif (ref($config{$_}) eq "HASH") {
2039 print OUT " ", $_, " => {";
2040 if (scalar keys %{$config{$_}} > 0) {
2041 print OUT "\n";
2042 foreach my $key (sort keys %{$config{$_}}) {
2043 print OUT " ",
2044 join(" => ",
2045 quotify("perl", $key),
2046 defined $config{$_}->{$key}
2047 ? quotify("perl", $config{$_}->{$key})
2048 : "undef");
2049 print OUT ",\n";
2050 }
2051 print OUT " ";
2052 }
2053 print OUT "},\n";
291e94df
RL
2054 } else {
2055 print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n"
2056 }
2057}
2058print OUT <<"EOF";
2059);
2060
2061EOF
2062print OUT "our %target = (\n";
2063foreach (sort keys %target) {
2064 if (ref($target{$_}) eq "ARRAY") {
2065 print OUT " ", $_, " => [ ", join(", ",
2066 map { quotify("perl", $_) }
2067 @{$target{$_}}), " ],\n";
2068 } else {
2069 print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n"
2070 }
2071}
2072print OUT <<"EOF";
2073);
2074
96d2d7bc
RL
2075EOF
2076print OUT "our \%available_protocols = (\n";
2077print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
2078print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
2079print OUT <<"EOF";
2080);
2081
3850f8cb
RL
2082EOF
2083print OUT "our \@disablables = (\n";
2084foreach (@disablables) {
2085 print OUT " ", quotify("perl", $_), ",\n";
2086}
2087print OUT <<"EOF";
2088);
2089
96d2d7bc
RL
2090EOF
2091print OUT "our \%disabled = (\n";
2092foreach (sort keys %disabled) {
2093 print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
2094}
2095print OUT <<"EOF";
2096);
2097
291e94df 2098EOF
107b5792
RL
2099print OUT "our %withargs = (\n";
2100foreach (sort keys %withargs) {
2101 if (ref($withargs{$_}) eq "ARRAY") {
2102 print OUT " ", $_, " => [ ", join(", ",
2103 map { quotify("perl", $_) }
2104 @{$withargs{$_}}), " ],\n";
2105 } else {
2106 print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
2107 }
2108}
2109print OUT <<"EOF";
2110);
edd4d402 2111
107b5792 2112EOF
ddf1847d 2113if ($builder eq "unified") {
9fe2bb77
RL
2114 my $recurse;
2115 $recurse = sub {
2116 my $indent = shift;
2117 foreach (@_) {
2118 if (ref $_ eq "ARRAY") {
2119 print OUT " "x$indent, "[\n";
2120 foreach (@$_) {
2121 $recurse->($indent + 4, $_);
2122 }
2123 print OUT " "x$indent, "],\n";
2124 } elsif (ref $_ eq "HASH") {
2125 my %h = %$_;
2126 print OUT " "x$indent, "{\n";
2127 foreach (sort keys %h) {
2128 if (ref $h{$_} eq "") {
2129 print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
2130 } else {
2131 print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
2132 $recurse->($indent + 8, $h{$_});
2133 }
2134 }
2135 print OUT " "x$indent, "},\n";
2136 } else {
2137 print OUT " "x$indent, quotify("perl", $_), ",\n";
2138 }
2139 }
2140 };
2141 print OUT "our %unified_info = (\n";
2142 foreach (sort keys %unified_info) {
2143 if (ref $unified_info{$_} eq "") {
2144 print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
2145 } else {
2146 print OUT " "x4, quotify("perl", $_), " =>\n";
2147 $recurse->(8, $unified_info{$_});
2148 }
2149 }
2150 print OUT <<"EOF";
2151);
2152
2153EOF
2154}
2155print OUT "1;\n";
d02b48c6 2156close(OUT);
f2d4be3b 2157
141d7325
RS
2158print "\n";
2159print "PROCESSOR =$config{processor}\n" if $config{processor};
2160print "PERL =$config{perl}\n";
758baa3d 2161print "PERLVERSION =$Config{version} for $Config{archname}\n";
141d7325 2162print "HASHBANGPERL =$config{hashbangperl}\n";
f58a0acb 2163print "CC =$config{cross_compile_prefix}$target{cc}\n";
2952b9b8 2164print "CFLAG =$target{cflags} $config{cflags}\n";
ea241958
RL
2165print "CXX =$config{cross_compile_prefix}$target{cxx}\n"
2166 if defined $target{cxx};
2167print "CXXFLAG =$target{cxxflags} $config{cxxflags}\n"
2168 if defined $target{cxx};
2952b9b8 2169print "DEFINES =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
141d7325
RS
2170#print "RANLIB =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
2171# "$config{cross_compile_prefix}ranlib" :
2172# "$target{ranlib}", "\n";
2952b9b8 2173print "EX_LIBS =$target{ex_libs} $config{ex_libs}\n";
cba5068d 2174
88087414 2175my %builders = (
9fe2bb77 2176 unified => sub {
ddf1847d 2177 run_dofile(catfile($blddir, $target{build_file}),
1967a42e 2178 @{$config{build_file_templates}});
9fe2bb77 2179 },
88087414
RL
2180 );
2181
ddf1847d 2182$builders{$builder}->($builder_platform, @builder_opts);
fce0ba5f 2183
9c62a279 2184print <<"EOF" if ($disabled{threads} eq "unavailable");
5f8d5c96
BM
2185
2186The library could not be configured for supporting multi-threaded
2187applications as the compiler options required on this system are not known.
ff1b7e09 2188See file INSTALL for details if you need multi-threading.
ec577822
BM
2189EOF
2190
76ffb43d 2191print <<"EOF" if ($no_shared_warn);
2964ba8c 2192
ae48242c
RL
2193The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2194platform, so we will pretend you gave the option 'no-pic', which also disables
2195'shared' and 'dynamic-engine'. If you know how to implement shared libraries
2196or position independent code, please let us know (but please first make sure
2197you have tried with a current version of OpenSSL).
2e31ef03
RS
2198EOF
2199
ddc606c9
RL
2200print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2201
2202WARNING: there are indications that another build was made in the source
2203directory. This build may have picked up artifacts from that build, the
2204safest course of action is to clean the source directory and redo this
2205configuration.
2206EOF
2207
d02b48c6
RE
2208exit(0);
2209
bd5192b1
RL
2210######################################################################
2211#
2212# Helpers and utility functions
2213#
2214
2215# Configuration file reading #########################################
2216
1f2e1cd5
RL
2217# Note: All of the helper functions are for lazy evaluation. They all
2218# return a CODE ref, which will return the intended value when evaluated.
2219# Thus, whenever there's mention of a returned value, it's about that
2220# intended value.
2221
bd5192b1 2222# Helper function to implement conditional inheritance depending on the
00b0d663 2223# value of $disabled{asm}. Used in inherit_from values as follows:
bd5192b1
RL
2224#
2225# inherit_from => [ "template", asm("asm_tmpl") ]
2226#
2227sub asm {
2228 my @x = @_;
2229 sub {
00b0d663 2230 $disabled{asm} ? () : @x;
bd5192b1
RL
2231 }
2232}
2233
1f2e1cd5
RL
2234# Helper function to implement conditional value variants, with a default
2235# plus additional values based on the value of $config{build_type}.
2236# Arguments are given in hash table form:
2237#
2238# picker(default => "Basic string: ",
2239# debug => "debug",
2240# release => "release")
2241#
2242# When configuring with --debug, the resulting string will be
2243# "Basic string: debug", and when not, it will be "Basic string: release"
2244#
2245# This can be used to create variants of sets of flags according to the
2246# build type:
2247#
2248# cflags => picker(default => "-Wall",
2249# debug => "-g -O0",
2250# release => "-O3")
2251#
2252sub picker {
2253 my %opts = @_;
2254 return sub { add($opts{default} || (),
2255 $opts{$config{build_type}} || ())->(); }
2256}
2257
2258# Helper function to combine several values of different types into one.
2259# This is useful if you want to combine a string with the result of a
2260# lazy function, such as:
2261#
2262# cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2263#
2264sub combine {
2265 my @stuff = @_;
2266 return sub { add(@stuff)->(); }
2267}
2268
2269# Helper function to implement conditional values depending on the value
2270# of $disabled{threads}. Can be used as follows:
2271#
2272# cflags => combine("-Wall", threads("-pthread"))
2273#
2274sub threads {
2275 my @flags = @_;
2276 return sub { add($disabled{threads} ? () : @flags)->(); }
2277}
2278
2279
2280
9c62a279 2281our $add_called = 0;
88087414
RL
2282# Helper function to implement adding values to already existing configuration
2283# values. It handles elements that are ARRAYs, CODEs and scalars
2284sub _add {
2285 my $separator = shift;
2286
bcb1977b
RL
2287 # If there's any ARRAY in the collection of values OR the separator
2288 # is undef, we will return an ARRAY of combined values, otherwise a
2289 # string of joined values with $separator as the separator.
2290 my $found_array = !defined($separator);
88087414
RL
2291
2292 my @values =
2293 map {
b0b92a5b
RL
2294 my $res = $_;
2295 while (ref($res) eq "CODE") {
2296 $res = $res->();
2297 }
2298 if (defined($res)) {
2299 if (ref($res) eq "ARRAY") {
2300 $found_array = 1;
2301 @$res;
2302 } else {
2303 $res;
2304 }
88087414 2305 } else {
b0b92a5b 2306 ();
88087414
RL
2307 }
2308 } (@_);
2309
9c62a279
RL
2310 $add_called = 1;
2311
88087414
RL
2312 if ($found_array) {
2313 [ @values ];
2314 } else {
b0b92a5b 2315 join($separator, grep { defined($_) && $_ ne "" } @values);
88087414
RL
2316 }
2317}
2318sub add_before {
bdcd83e1
RL
2319 my $separator = " ";
2320 if (ref($_[$#_]) eq "HASH") {
2321 my $opts = pop;
2322 $separator = $opts->{separator};
2323 }
88087414
RL
2324 my @x = @_;
2325 sub { _add($separator, @x, @_) };
2326}
2327sub add {
bdcd83e1
RL
2328 my $separator = " ";
2329 if (ref($_[$#_]) eq "HASH") {
2330 my $opts = pop;
2331 $separator = $opts->{separator};
2332 }
88087414
RL
2333 my @x = @_;
2334 sub { _add($separator, @_, @x) };
2335}
2336
3b6c4b07
RL
2337sub read_eval_file {
2338 my $fname = shift;
2339 my $content;
2340 my @result;
2341
2342 open F, "< $fname" or die "Can't open '$fname': $!\n";
2343 {
2344 undef local $/;
2345 $content = <F>;
2346 }
2347 close F;
2348 {
2349 local $@;
2350
2351 @result = ( eval $content );
2352 warn $@ if $@;
2353 }
2354 return wantarray ? @result : $result[0];
2355}
2356
bd5192b1
RL
2357# configuration reader, evaluates the input file as a perl script and expects
2358# it to fill %targets with target configurations. Those are then added to
2359# %table.
2360sub read_config {
2361 my $fname = shift;
3b6c4b07
RL
2362 my %targets;
2363
bd5192b1 2364 {
ee9b0bbb 2365 # Protect certain tables from tampering
3b6c4b07 2366 local %table = ();
bd5192b1 2367
3b6c4b07 2368 %targets = read_eval_file($fname);
bd5192b1
RL
2369 }
2370
2371 # For each target, check that it's configured with a hash table.
2372 foreach (keys %targets) {
2373 if (ref($targets{$_}) ne "HASH") {
2374 if (ref($targets{$_}) eq "") {
2375 warn "Deprecated target configuration for $_, ignoring...\n";
2376 } else {
2377 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2378 }
2379 delete $targets{$_};
ee9b0bbb
RL
2380 } else {
2381 $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2382 }
bd5192b1
RL
2383 }
2384
2385 %table = (%table, %targets);
2386
2387}
2388
8483a003
F
2389# configuration resolver. Will only resolve all the lazy evaluation
2390# codeblocks for the chosen target and all those it inherits from,
bd5192b1
RL
2391# recursively
2392sub resolve_config {
2393 my $target = shift;
2394 my @breadcrumbs = @_;
2395
c4718849 2396# my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
9c62a279 2397
bd5192b1
RL
2398 if (grep { $_ eq $target } @breadcrumbs) {
2399 die "inherit_from loop! target backtrace:\n "
2400 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
2401 }
2402
2403 if (!defined($table{$target})) {
2404 warn "Warning! target $target doesn't exist!\n";
2405 return ();
2406 }
2407 # Recurse through all inheritances. They will be resolved on the
2408 # fly, so when this operation is done, they will all just be a
2409 # bunch of attributes with string values.
2410 # What we get here, though, are keys with references to lists of
2411 # the combined values of them all. We will deal with lists after
2412 # this stage is done.
2413 my %combined_inheritance = ();
2414 if ($table{$target}->{inherit_from}) {
2415 my @inherit_from =
2416 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2417 foreach (@inherit_from) {
2418 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2419
2420 # 'template' is a marker that's considered private to
2421 # the config that had it.
2422 delete $inherited_config{template};
2423
2110febb 2424 foreach (keys %inherited_config) {
bd5192b1
RL
2425 if (!$combined_inheritance{$_}) {
2426 $combined_inheritance{$_} = [];
2427 }
2428 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2110febb 2429 }
bd5192b1
RL
2430 }
2431 }
2432
2433 # We won't need inherit_from in this target any more, since we've
2434 # resolved all the inheritances that lead to this
2435 delete $table{$target}->{inherit_from};
2436
2437 # Now is the time to deal with those lists. Here's the place to
2438 # decide what shall be done with those lists, all based on the
2439 # values of the target we're currently dealing with.
2440 # - If a value is a coderef, it will be executed with the list of
2441 # inherited values as arguments.
2442 # - If the corresponding key doesn't have a value at all or is the
8483a003 2443 # empty string, the inherited value list will be run through the
bd5192b1
RL
2444 # default combiner (below), and the result becomes this target's
2445 # value.
2446 # - Otherwise, this target's value is assumed to be a string that
2447 # will simply override the inherited list of values.
a26d8be9 2448 my $default_combiner = add();
bd5192b1
RL
2449
2450 my %all_keys =
2451 map { $_ => 1 } (keys %combined_inheritance,
2452 keys %{$table{$target}});
b0b92a5b
RL
2453
2454 sub process_values {
2455 my $object = shift;
2456 my $inherited = shift; # Always a [ list ]
2457 my $target = shift;
2458 my $entry = shift;
2459
9c62a279
RL
2460 $add_called = 0;
2461
b0b92a5b
RL
2462 while(ref($object) eq "CODE") {
2463 $object = $object->(@$inherited);
2464 }
2465 if (!defined($object)) {
2466 return ();
2467 }
2468 elsif (ref($object) eq "ARRAY") {
9c62a279 2469 local $add_called; # To make sure recursive calls don't affect it
b0b92a5b
RL
2470 return [ map { process_values($_, $inherited, $target, $entry) }
2471 @$object ];
2472 } elsif (ref($object) eq "") {
2473 return $object;
2474 } else {
2475 die "cannot handle reference type ",ref($object)
2476 ," found in target ",$target," -> ",$entry,"\n";
2477 }
2478 }
2479
bd5192b1 2480 foreach (sort keys %all_keys) {
9c62a279 2481 my $previous = $combined_inheritance{$_};
bd5192b1
RL
2482
2483 # Current target doesn't have a value for the current key?
2484 # Assign it the default combiner, the rest of this loop body
2485 # will handle it just like any other coderef.
2486 if (!exists $table{$target}->{$_}) {
2487 $table{$target}->{$_} = $default_combiner;
2488 }
2489
b0b92a5b
RL
2490 $table{$target}->{$_} = process_values($table{$target}->{$_},
2491 $combined_inheritance{$_},
2492 $target, $_);
2493 unless(defined($table{$target}->{$_})) {
2494 delete $table{$target}->{$_};
2495 }
c4718849
RL
2496# if ($extra_checks &&
2497# $previous && !($add_called || $previous ~~ $table{$target}->{$_})) {
2498# warn "$_ got replaced in $target\n";
2499# }
bd5192b1
RL
2500 }
2501
2502 # Finally done, return the result.
2503 return %{$table{$target}};
2504}
2505
462ba4f6 2506sub usage
d02b48c6 2507 {
462ba4f6 2508 print STDERR $usage;
10a926c1 2509 print STDERR "\npick os/compiler from:\n";
1641cb60 2510 my $j=0;
6457ad15 2511 my $i;
10a926c1 2512 my $k=0;
6457ad15 2513 foreach $i (sort keys %table)
d02b48c6 2514 {
bd5192b1 2515 next if $table{$i}->{template};
462ba4f6 2516 next if $i =~ /^debug/;
10a926c1
UM
2517 $k += length($i) + 1;
2518 if ($k > 78)
2519 {
2520 print STDERR "\n";
2521 $k=length($i);
2522 }
2523 print STDERR $i . " ";
462ba4f6
UM
2524 }
2525 foreach $i (sort keys %table)
2526 {
bd5192b1 2527 next if $table{$i}->{template};
462ba4f6 2528 next if $i !~ /^debug/;
10a926c1
UM
2529 $k += length($i) + 1;
2530 if ($k > 78)
2531 {
2532 print STDERR "\n";
2533 $k=length($i);
2534 }
2535 print STDERR $i . " ";
d02b48c6 2536 }
10a926c1 2537 print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
462ba4f6 2538 exit(1);
d02b48c6
RE
2539 }
2540
01d99976 2541sub run_dofile
107b5792 2542{
107b5792 2543 my $out = shift;
9fe2bb77 2544 my @templates = @_;
107b5792 2545
ced2c2c5
RS
2546 unlink $out || warn "Can't remove $out, $!"
2547 if -f $out;
9fe2bb77
RL
2548 foreach (@templates) {
2549 die "Can't open $_, $!" unless -f $_;
2550 }
f879d5ff
RL
2551 my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2552 my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
9fe2bb77
RL
2553 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2554 system($cmd);
107b5792
RL
2555 exit 1 if $? != 0;
2556 rename("$out.new", $out) || die "Can't rename $out.new, $!";
2557}
2558
6d75a83c
RL
2559sub compiler_predefined {
2560 state %predefined;
2561 my $default_compiler = shift;
2562
2563 return () if $^O eq 'VMS';
2564
2565 die 'compiler_predefines called without a default compiler'
2566 unless $default_compiler;
2567
2568 if (! $predefined{$default_compiler}) {
2569 my $cc = "$config{cross_compile_prefix}$default_compiler";
2570
2571 $predefined{$default_compiler} = {};
2572
2573 # collect compiler pre-defines from gcc or gcc-alike...
2574 open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
2575 while (my $l = <PIPE>) {
2576 $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
2577 $predefined{$default_compiler}->{$1} = $2 // '';
2578 }
2579 close(PIPE);
2580 }
2581
2582 return %{$predefined{$default_compiler}};
2583}
2584
656bbdc6
AP
2585sub which
2586{
2587 my ($name)=@_;
2588
2589 if (eval { require IPC::Cmd; 1; }) {
2590 IPC::Cmd->import();
2591 return scalar IPC::Cmd::can_run($name);
2592 } else {
2593 # if there is $directories component in splitpath,
2594 # then it's not something to test with $PATH...
2595 return $name if (File::Spec->splitpath($name))[1];
2596
2597 foreach (File::Spec->path()) {
2598 my $fullpath = catfile($_, "$name$target{exe_extension}");
2599 if (-f $fullpath and -x $fullpath) {
2600 return $fullpath;
2601 }
2602 }
2603 }
2604}
2605
7ecdf18d
RL
2606sub env
2607{
2608 my $name = shift;
2609
89bea083
RL
2610 # Note that if $ENV{$name} doesn't exist or is undefined,
2611 # $config{perlenv}->{$name} will be created with the value
2612 # undef. This is intentional.
2613
2614 $config{perlenv}->{$name} = $ENV{$name}
2615 if ! exists $config{perlenv}->{$name};
7ecdf18d
RL
2616 return $config{perlenv}->{$name};
2617}
2618
00ae96ca
RL
2619# Configuration printer ##############################################
2620
2621sub print_table_entry
2622{
2623 my $target = shift;
2624 my %target = resolve_config($target);
2625 my $type = shift;
2626
2627 # Don't print the templates
2628 return if $target{template};
2629
2630 my @sequence = (
f0bd4686 2631 "sys_id",
00ae96ca
RL
2632 "cc",
2633 "cflags",
bcb1977b 2634 "defines",
f0bd4686
RL
2635 "unistd",
2636 "ld",
00ae96ca 2637 "lflags",
0c0d78b8 2638 "loutflag",
c86ddbe6 2639 "plib_lflags",
1740c162 2640 "ex_libs",
00ae96ca 2641 "bn_ops",
0c0d78b8
RL
2642 "apps_aux_src",
2643 "cpuid_asm_src",
2644 "uplink_aux_src",
2645 "bn_asm_src",
2646 "ec_asm_src",
2647 "des_asm_src",
2648 "aes_asm_src",
2649 "bf_asm_src",
2650 "md5_asm_src",
2651 "cast_asm_src",
2652 "sha1_asm_src",
2653 "rc4_asm_src",
2654 "rmd160_asm_src",
2655 "rc5_asm_src",
2656 "wp_asm_src",
2657 "cmll_asm_src",
2658 "modes_asm_src",
2659 "padlock_asm_src",
2660 "chacha_asm_src",
2661 "poly1035_asm_src",
9c62a279 2662 "thread_scheme",
00ae96ca
RL
2663 "perlasm_scheme",
2664 "dso_scheme",
2665 "shared_target",
2666 "shared_cflag",
0c0d78b8 2667 "shared_defines",
00ae96ca 2668 "shared_ldflag",
64c443e3 2669 "shared_rcflag",
00ae96ca 2670 "shared_extension",
e987f9f2 2671 "dso_extension",
f0bd4686
RL
2672 "obj_extension",
2673 "exe_extension",
00ae96ca 2674 "ranlib",
f0bd4686 2675 "ar",
00ae96ca 2676 "arflags",
0c0d78b8
RL
2677 "aroutflag",
2678 "rc",
2679 "rcflags",
2680 "rcoutflag",
2681 "mt",
2682 "mtflags",
2683 "mtinflag",
2684 "mtoutflag",
00ae96ca 2685 "multilib",
f0bd4686 2686 "build_scheme",
00ae96ca
RL
2687 );
2688
2689 if ($type eq "TABLE") {
2690 print "\n";
2691 print "*** $target\n";
cb212f23
RL
2692 foreach (@sequence) {
2693 if (ref($target{$_}) eq "ARRAY") {
2694 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2695 } else {
2696 printf "\$%-12s = %s\n", $_, $target{$_};
2697 }
2698 }
00ae96ca
RL
2699 } elsif ($type eq "HASH") {
2700 my $largest =
2701 length((sort { length($a) <=> length($b) } @sequence)[-1]);
2702 print " '$target' => {\n";
2703 foreach (@sequence) {
2704 if ($target{$_}) {
cb212f23
RL
2705 if (ref($target{$_}) eq "ARRAY") {
2706 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2707 } else {
2708 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2709 }
00ae96ca
RL
2710 }
2711 }
2712 print " },\n";
2713 }
2714}
2715
2716# Utility routines ###################################################
2717
2e963849
RL
2718# On VMS, if the given file is a logical name, File::Spec::Functions
2719# will consider it an absolute path. There are cases when we want a
2720# purely syntactic check without checking the environment.
2721sub isabsolute {
2722 my $file = shift;
2723
2724 # On non-platforms, we just use file_name_is_absolute().
2725 return file_name_is_absolute($file) unless $^O eq "VMS";
2726
69687aa8 2727 # If the file spec includes a device or a directory spec,
2e963849
RL
2728 # file_name_is_absolute() is perfectly safe.
2729 return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2730
2731 # Here, we know the given file spec isn't absolute
2732 return 0;
2733}
2734
ec182ef0
RL
2735# Makes a directory absolute and cleans out /../ in paths like foo/../bar
2736# On some platforms, this uses rel2abs(), while on others, realpath() is used.
2737# realpath() requires that at least all path components except the last is an
2738# existing directory. On VMS, the last component of the directory spec must
2739# exist.
2740sub absolutedir {
2741 my $dir = shift;
2742
2743 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
2744 # will return the volume name for the device, no matter what. Also,
2745 # it will return an incorrect directory spec if the argument is a
2746 # directory that doesn't exist.
2747 if ($^O eq "VMS") {
2748 return rel2abs($dir);
2749 }
2750
2751 # We use realpath() on Unix, since no other will properly clean out
2752 # a directory spec.
2753 use Cwd qw/realpath/;
2754
2755 return realpath($dir);
2756}
2757
fe05264e
RL
2758sub quotify {
2759 my %processors = (
2760 perl => sub { my $x = shift;
2761 $x =~ s/([\\\$\@"])/\\$1/g;
2762 return '"'.$x.'"'; },
f879d5ff
RL
2763 maybeshell => sub { my $x = shift;
2764 (my $y = $x) =~ s/([\\\"])/\\$1/g;
2765 if ($x ne $y || $x =~ m|\s|) {
2766 return '"'.$y.'"';
2767 } else {
2768 return $x;
2769 }
2770 },
fe05264e
RL
2771 );
2772 my $for = shift;
2773 my $processor =
2774 defined($processors{$for}) ? $processors{$for} : sub { shift; };
2775
2110febb 2776 return map { $processor->($_); } @_;
fe05264e 2777}
107b5792 2778
9fe2bb77
RL
2779# collect_from_file($filename, $line_concat_cond_re, $line_concat)
2780# $filename is a file name to read from
2781# $line_concat_cond_re is a regexp detecting a line continuation ending
2782# $line_concat is a CODEref that takes care of concatenating two lines
2783sub collect_from_file {
2784 my $filename = shift;
2785 my $line_concat_cond_re = shift;
2786 my $line_concat = shift;
2787
2788 open my $fh, $filename || die "unable to read $filename: $!\n";
2789 return sub {
2790 my $saved_line = "";
2791 $_ = "";
2792 while (<$fh>) {
04f171c0 2793 s|\R$||;
9fe2bb77
RL
2794 if (defined $line_concat) {
2795 $_ = $line_concat->($saved_line, $_);
2796 $saved_line = "";
2797 }
2798 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2799 $saved_line = $_;
2800 next;
2801 }
2802 return $_;
2803 }
2804 die "$filename ending with continuation line\n" if $_;
2805 close $fh;
2806 return undef;
2807 }
2808}
2809
2810# collect_from_array($array, $line_concat_cond_re, $line_concat)
2811# $array is an ARRAYref of lines
2812# $line_concat_cond_re is a regexp detecting a line continuation ending
2813# $line_concat is a CODEref that takes care of concatenating two lines
2814sub collect_from_array {
2815 my $array = shift;
2816 my $line_concat_cond_re = shift;
2817 my $line_concat = shift;
2818 my @array = (@$array);
2819
2820 return sub {
2821 my $saved_line = "";
2822 $_ = "";
2823 while (defined($_ = shift @array)) {
04f171c0 2824 s|\R$||;
9fe2bb77
RL
2825 if (defined $line_concat) {
2826 $_ = $line_concat->($saved_line, $_);
2827 $saved_line = "";
2828 }
2829 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2830 $saved_line = $_;
2831 next;
2832 }
2833 return $_;
2834 }
2835 die "input text ending with continuation line\n" if $_;
2836 return undef;
2837 }
2838}
2839
2840# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2841# $lineiterator is a CODEref that delivers one line at a time.
107b5792
RL
2842# All following arguments are regex/CODEref pairs, where the regexp detects a
2843# line and the CODEref does something with the result of the regexp.
2844sub collect_information {
9fe2bb77 2845 my $lineiterator = shift;
107b5792
RL
2846 my %collectors = @_;
2847
9fe2bb77 2848 while(defined($_ = $lineiterator->())) {
04f171c0 2849 s|\R$||;
9fe2bb77 2850 my $found = 0;
2b6b606c
RL
2851 if ($collectors{"BEFORE"}) {
2852 $collectors{"BEFORE"}->($_);
2853 }
9fe2bb77 2854 foreach my $re (keys %collectors) {
2b6b606c 2855 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
9fe2bb77
RL
2856 $collectors{$re}->($lineiterator);
2857 $found = 1;
2858 };
2859 }
2860 if ($collectors{"OTHERWISE"}) {
2861 $collectors{"OTHERWISE"}->($lineiterator, $_)
2862 unless $found || !defined $collectors{"OTHERWISE"};
2863 }
2b6b606c
RL
2864 if ($collectors{"AFTER"}) {
2865 $collectors{"AFTER"}->($_);
2866 }
107b5792 2867 }
107b5792 2868}
ce959812
RL
2869
2870# tokenize($line)
2871# $line is a line of text to split up into tokens
2872# returns a list of tokens
2873#
2874# Tokens are divided by spaces. If the tokens include spaces, they
2875# have to be quoted with single or double quotes. Double quotes
2876# inside a double quoted token must be escaped. Escaping is done
2877# with backslash.
2878# Basically, the same quoting rules apply for " and ' as in any
2879# Unix shell.
2880sub tokenize {
2881 my $line = my $debug_line = shift;
2882 my @result = ();
2883
2884 while ($line =~ s|^\s+||, $line ne "") {
2885 my $token = "";
2886 while ($line ne "" && $line !~ m|^\s|) {
2887 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2888 $token .= $1;
2889 $line = $';
2890 } elsif ($line =~ m/^'([^']*)'/) {
2891 $token .= $1;
2892 $line = $';
2893 } elsif ($line =~ m/^(\S+)/) {
2894 $token .= $1;
2895 $line = $';
2896 }
2897 }
2898 push @result, $token;
2899 }
2900
2901 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2902 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2903 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
2904 }
2905 return @result;
2906}