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