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