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