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