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