xref: /third_party/openssl/Configure (revision e1051a39)
1e1051a39Sopenharmony_ci#! /usr/bin/env perl
2e1051a39Sopenharmony_ci# -*- mode: perl; -*-
3e1051a39Sopenharmony_ci# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
4e1051a39Sopenharmony_ci#
5e1051a39Sopenharmony_ci# Licensed under the Apache License 2.0 (the "License").  You may not use
6e1051a39Sopenharmony_ci# this file except in compliance with the License.  You can obtain a copy
7e1051a39Sopenharmony_ci# in the file LICENSE in the source distribution or at
8e1051a39Sopenharmony_ci# https://www.openssl.org/source/license.html
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci##  Configure -- OpenSSL source tree configuration script
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ciuse 5.10.0;
13e1051a39Sopenharmony_ciuse strict;
14e1051a39Sopenharmony_ciuse Config;
15e1051a39Sopenharmony_ciuse FindBin;
16e1051a39Sopenharmony_ciuse lib "$FindBin::Bin/util/perl";
17e1051a39Sopenharmony_ciuse File::Basename;
18e1051a39Sopenharmony_ciuse File::Spec::Functions qw/:DEFAULT abs2rel rel2abs splitdir/;
19e1051a39Sopenharmony_ciuse File::Path qw/mkpath/;
20e1051a39Sopenharmony_ciuse OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt";
21e1051a39Sopenharmony_ciuse OpenSSL::Glob;
22e1051a39Sopenharmony_ciuse OpenSSL::Template;
23e1051a39Sopenharmony_ciuse OpenSSL::config;
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci# see INSTALL.md for instructions.
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_cimy $orig_death_handler = $SIG{__DIE__};
28e1051a39Sopenharmony_ci$SIG{__DIE__} = \&death_handler;
29e1051a39Sopenharmony_ci
30e1051a39Sopenharmony_cimy $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-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
31e1051a39Sopenharmony_ci
32e1051a39Sopenharmony_cimy $banner = <<"EOF";
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_ci**********************************************************************
35e1051a39Sopenharmony_ci***                                                                ***
36e1051a39Sopenharmony_ci***   OpenSSL has been successfully configured                     ***
37e1051a39Sopenharmony_ci***                                                                ***
38e1051a39Sopenharmony_ci***   If you encounter a problem while building, please open an    ***
39e1051a39Sopenharmony_ci***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
40e1051a39Sopenharmony_ci***   and include the output from the following command:           ***
41e1051a39Sopenharmony_ci***                                                                ***
42e1051a39Sopenharmony_ci***       perl configdata.pm --dump                                ***
43e1051a39Sopenharmony_ci***                                                                ***
44e1051a39Sopenharmony_ci***   (If you are new to OpenSSL, you might want to consult the    ***
45e1051a39Sopenharmony_ci***   'Troubleshooting' section in the INSTALL.md file first)      ***
46e1051a39Sopenharmony_ci***                                                                ***
47e1051a39Sopenharmony_ci**********************************************************************
48e1051a39Sopenharmony_ciEOF
49e1051a39Sopenharmony_ci
50e1051a39Sopenharmony_ci# Options:
51e1051a39Sopenharmony_ci#
52e1051a39Sopenharmony_ci# --config      add the given configuration file, which will be read after
53e1051a39Sopenharmony_ci#               any "Configurations*" files that are found in the same
54e1051a39Sopenharmony_ci#               directory as this script.
55e1051a39Sopenharmony_ci# --prefix      prefix for the OpenSSL installation, which includes the
56e1051a39Sopenharmony_ci#               directories bin, lib, include, share/man, share/doc/openssl
57e1051a39Sopenharmony_ci#               This becomes the value of INSTALLTOP in Makefile
58e1051a39Sopenharmony_ci#               (Default: /usr/local)
59e1051a39Sopenharmony_ci# --openssldir  OpenSSL data area, such as openssl.cnf, certificates and keys.
60e1051a39Sopenharmony_ci#               If it's a relative directory, it will be added on the directory
61e1051a39Sopenharmony_ci#               given with --prefix.
62e1051a39Sopenharmony_ci#               This becomes the value of OPENSSLDIR in Makefile and in C.
63e1051a39Sopenharmony_ci#               (Default: PREFIX/ssl)
64e1051a39Sopenharmony_ci# --banner=".." Output specified text instead of default completion banner
65e1051a39Sopenharmony_ci#
66e1051a39Sopenharmony_ci# -w            Don't wait after showing a Configure warning
67e1051a39Sopenharmony_ci#
68e1051a39Sopenharmony_ci# --cross-compile-prefix Add specified prefix to binutils components.
69e1051a39Sopenharmony_ci#
70e1051a39Sopenharmony_ci# --api         One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0
71e1051a39Sopenharmony_ci#               Define the public APIs as they were for that version
72e1051a39Sopenharmony_ci#               including patch releases.  If 'no-deprecated' is also
73e1051a39Sopenharmony_ci#               given, do not compile support for interfaces deprecated
74e1051a39Sopenharmony_ci#               up to and including the specified OpenSSL version.
75e1051a39Sopenharmony_ci#
76e1051a39Sopenharmony_ci# no-hw-xxx     do not compile support for specific crypto hardware.
77e1051a39Sopenharmony_ci#               Generic OpenSSL-style methods relating to this support
78e1051a39Sopenharmony_ci#               are always compiled but return NULL if the hardware
79e1051a39Sopenharmony_ci#               support isn't compiled.
80e1051a39Sopenharmony_ci# no-hw         do not compile support for any crypto hardware.
81e1051a39Sopenharmony_ci# [no-]threads  [don't] try to create a library that is suitable for
82e1051a39Sopenharmony_ci#               multithreaded applications (default is "threads" if we
83e1051a39Sopenharmony_ci#               know how to do it)
84e1051a39Sopenharmony_ci# [no-]shared   [don't] try to create shared libraries when supported.
85e1051a39Sopenharmony_ci# [no-]pic      [don't] try to build position independent code when supported.
86e1051a39Sopenharmony_ci#               If disabled, it also disables shared and dynamic-engine.
87e1051a39Sopenharmony_ci# no-asm        do not use assembler
88e1051a39Sopenharmony_ci# no-egd        do not compile support for the entropy-gathering daemon APIs
89e1051a39Sopenharmony_ci# [no-]zlib     [don't] compile support for zlib compression.
90e1051a39Sopenharmony_ci# zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
91e1051a39Sopenharmony_ci#               library and will be loaded in run-time by the OpenSSL library.
92e1051a39Sopenharmony_ci# sctp          include SCTP support
93e1051a39Sopenharmony_ci# no-uplink     Don't build support for UPLINK interface.
94e1051a39Sopenharmony_ci# enable-weak-ssl-ciphers
95e1051a39Sopenharmony_ci#               Enable weak ciphers that are disabled by default.
96e1051a39Sopenharmony_ci# 386           generate 80386 code in assembly modules
97e1051a39Sopenharmony_ci# no-sse2       disables IA-32 SSE2 code in assembly modules, the above
98e1051a39Sopenharmony_ci#               mentioned '386' option implies this one
99e1051a39Sopenharmony_ci# no-<cipher>   build without specified algorithm (dsa, idea, rc5, ...)
100e1051a39Sopenharmony_ci# -<xxx> +<xxx> All options which are unknown to the 'Configure' script are
101e1051a39Sopenharmony_ci# /<xxx>        passed through to the compiler. Unix-style options beginning
102e1051a39Sopenharmony_ci#               with a '-' or '+' are recognized, as well as Windows-style
103e1051a39Sopenharmony_ci#               options beginning with a '/'. If the option contains arguments
104e1051a39Sopenharmony_ci#               separated by spaces, then the URL-style notation %20 can be
105e1051a39Sopenharmony_ci#               used for the space character in order to avoid having to quote
106e1051a39Sopenharmony_ci#               the option. For example, -opt%20arg gets expanded to -opt arg.
107e1051a39Sopenharmony_ci#               In fact, any ASCII character can be encoded as %xx using its
108e1051a39Sopenharmony_ci#               hexadecimal encoding.
109e1051a39Sopenharmony_ci# -static       while -static is also a pass-through compiler option (and
110e1051a39Sopenharmony_ci#               as such is limited to environments where it's actually
111e1051a39Sopenharmony_ci#               meaningful), it triggers a number configuration options,
112e1051a39Sopenharmony_ci#               namely no-pic, no-shared and no-threads. It is
113e1051a39Sopenharmony_ci#               argued that the only reason to produce statically linked
114e1051a39Sopenharmony_ci#               binaries (and in context it means executables linked with
115e1051a39Sopenharmony_ci#               -static flag, and not just executables linked with static
116e1051a39Sopenharmony_ci#               libcrypto.a) is to eliminate dependency on specific run-time,
117e1051a39Sopenharmony_ci#               a.k.a. libc version. The mentioned config options are meant
118e1051a39Sopenharmony_ci#               to achieve just that. Unfortunately on Linux it's impossible
119e1051a39Sopenharmony_ci#               to eliminate the dependency completely for openssl executable
120e1051a39Sopenharmony_ci#               because of getaddrinfo and gethostbyname calls, which can
121e1051a39Sopenharmony_ci#               invoke dynamically loadable library facility anyway to meet
122e1051a39Sopenharmony_ci#               the lookup requests. For this reason on Linux statically
123e1051a39Sopenharmony_ci#               linked openssl executable has rather debugging value than
124e1051a39Sopenharmony_ci#               production quality.
125e1051a39Sopenharmony_ci#
126e1051a39Sopenharmony_ci# BN_LLONG      use the type 'long long' in crypto/bn/bn.h
127e1051a39Sopenharmony_ci# RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
128e1051a39Sopenharmony_ci# Following are set automatically by this script
129e1051a39Sopenharmony_ci#
130e1051a39Sopenharmony_ci# MD5_ASM       use some extra md5 assembler,
131e1051a39Sopenharmony_ci# SHA1_ASM      use some extra sha1 assembler, must define L_ENDIAN for x86
132e1051a39Sopenharmony_ci# RMD160_ASM    use some extra ripemd160 assembler,
133e1051a39Sopenharmony_ci# SHA256_ASM    sha256_block is implemented in assembler
134e1051a39Sopenharmony_ci# SHA512_ASM    sha512_block is implemented in assembler
135e1051a39Sopenharmony_ci# AES_ASM       AES_[en|de]crypt is implemented in assembler
136e1051a39Sopenharmony_ci
137e1051a39Sopenharmony_ci# Minimum warning options... any contributions to OpenSSL should at least
138e1051a39Sopenharmony_ci# get past these.  Note that we only use these with C compilers, not with
139e1051a39Sopenharmony_ci# C++ compilers.
140e1051a39Sopenharmony_ci
141e1051a39Sopenharmony_ci# -DPEDANTIC complements -pedantic and is meant to mask code that
142e1051a39Sopenharmony_ci# is not strictly standard-compliant and/or implementation-specific,
143e1051a39Sopenharmony_ci# e.g. inline assembly, disregards to alignment requirements, such
144e1051a39Sopenharmony_ci# that -pedantic would complain about. Incidentally -DPEDANTIC has
145e1051a39Sopenharmony_ci# to be used even in sanitized builds, because sanitizer too is
146e1051a39Sopenharmony_ci# supposed to and does take notice of non-standard behaviour. Then
147e1051a39Sopenharmony_ci# -pedantic with pre-C9x compiler would also complain about 'long
148e1051a39Sopenharmony_ci# long' not being supported. As 64-bit algorithms are common now,
149e1051a39Sopenharmony_ci# it grew impossible to resolve this without sizeable additional
150e1051a39Sopenharmony_ci# code, so we just tell compiler to be pedantic about everything
151e1051a39Sopenharmony_ci# but 'long long' type.
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_cimy @gcc_devteam_warn = qw(
154e1051a39Sopenharmony_ci    -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG
155e1051a39Sopenharmony_ci    -Wall
156e1051a39Sopenharmony_ci    -Wmissing-declarations
157e1051a39Sopenharmony_ci    -Wextra
158e1051a39Sopenharmony_ci    -Wno-unused-parameter
159e1051a39Sopenharmony_ci    -Wno-missing-field-initializers
160e1051a39Sopenharmony_ci    -Wswitch
161e1051a39Sopenharmony_ci    -Wsign-compare
162e1051a39Sopenharmony_ci    -Wshadow
163e1051a39Sopenharmony_ci    -Wformat
164e1051a39Sopenharmony_ci    -Wtype-limits
165e1051a39Sopenharmony_ci    -Wundef
166e1051a39Sopenharmony_ci    -Werror
167e1051a39Sopenharmony_ci    -Wmissing-prototypes
168e1051a39Sopenharmony_ci    -Wstrict-prototypes
169e1051a39Sopenharmony_ci);
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_ci# These are used in addition to $gcc_devteam_warn when the compiler is clang.
172e1051a39Sopenharmony_ci# TODO(openssl-team): fix problems and investigate if (at least) the
173e1051a39Sopenharmony_ci# following warnings can also be enabled:
174e1051a39Sopenharmony_ci#       -Wcast-align
175e1051a39Sopenharmony_ci#       -Wunreachable-code -- no, too ugly/compiler-specific
176e1051a39Sopenharmony_ci#       -Wlanguage-extension-token -- no, we use asm()
177e1051a39Sopenharmony_ci#       -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
178e1051a39Sopenharmony_ci#       -Wextended-offsetof -- no, needed in CMS ASN1 code
179e1051a39Sopenharmony_cimy @clang_devteam_warn = qw(
180e1051a39Sopenharmony_ci    -Wno-unknown-warning-option
181e1051a39Sopenharmony_ci    -Wswitch-default
182e1051a39Sopenharmony_ci    -Wno-parentheses-equality
183e1051a39Sopenharmony_ci    -Wno-language-extension-token
184e1051a39Sopenharmony_ci    -Wno-extended-offsetof
185e1051a39Sopenharmony_ci    -Wconditional-uninitialized
186e1051a39Sopenharmony_ci    -Wincompatible-pointer-types-discards-qualifiers
187e1051a39Sopenharmony_ci    -Wmissing-variable-declarations
188e1051a39Sopenharmony_ci);
189e1051a39Sopenharmony_ci
190e1051a39Sopenharmony_cimy @cl_devteam_warn = qw(
191e1051a39Sopenharmony_ci    /WX
192e1051a39Sopenharmony_ci);
193e1051a39Sopenharmony_ci
194e1051a39Sopenharmony_cimy $strict_warnings = 0;
195e1051a39Sopenharmony_ci
196e1051a39Sopenharmony_ci# As for $BSDthreads. Idea is to maintain "collective" set of flags,
197e1051a39Sopenharmony_ci# which would cover all BSD flavors. -pthread applies to them all,
198e1051a39Sopenharmony_ci# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
199e1051a39Sopenharmony_ci# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
200e1051a39Sopenharmony_ci# which has to be accompanied by explicit -D_THREAD_SAFE and
201e1051a39Sopenharmony_ci# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
202e1051a39Sopenharmony_ci# seems to be sufficient?
203e1051a39Sopenharmony_ciour $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
204e1051a39Sopenharmony_ci
205e1051a39Sopenharmony_ci#
206e1051a39Sopenharmony_ci# API compatibility name to version number mapping.
207e1051a39Sopenharmony_ci#
208e1051a39Sopenharmony_cimy $apitable = {
209e1051a39Sopenharmony_ci    # This table expresses when API additions or changes can occur.
210e1051a39Sopenharmony_ci    # The numbering used changes from 3.0 and on because we updated
211e1051a39Sopenharmony_ci    # (solidified) our version numbering scheme at that point.
212e1051a39Sopenharmony_ci
213e1051a39Sopenharmony_ci    # From 3.0 and on, we internalise the given version number in decimal
214e1051a39Sopenharmony_ci    # as MAJOR * 10000 + MINOR * 100 + 0
215e1051a39Sopenharmony_ci    "3.0.0" => 30000,
216e1051a39Sopenharmony_ci    "3.0"   => 30000,
217e1051a39Sopenharmony_ci
218e1051a39Sopenharmony_ci    # Note that before 3.0, we didn't have the same version number scheme.
219e1051a39Sopenharmony_ci    # Still, the numbering we use here covers what we need.
220e1051a39Sopenharmony_ci    "1.1.1" => 10101,
221e1051a39Sopenharmony_ci    "1.1.0" => 10100,
222e1051a39Sopenharmony_ci    "1.0.2" => 10002,
223e1051a39Sopenharmony_ci    "1.0.1" => 10001,
224e1051a39Sopenharmony_ci    "1.0.0" => 10000,
225e1051a39Sopenharmony_ci    "0.9.8" =>   908,
226e1051a39Sopenharmony_ci};
227e1051a39Sopenharmony_ci
228e1051a39Sopenharmony_ci# For OpenSSL::config::get_platform
229e1051a39Sopenharmony_cimy %guess_opts = ();
230e1051a39Sopenharmony_ci
231e1051a39Sopenharmony_cimy $dryrun = 0;
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ciour %table = ();
234e1051a39Sopenharmony_ciour %config = ();
235e1051a39Sopenharmony_ciour %withargs = ();
236e1051a39Sopenharmony_ciour $now_printing;      # set to current entry's name in print_table_entry
237e1051a39Sopenharmony_ci                        # (todo: right thing would be to encapsulate name
238e1051a39Sopenharmony_ci                        # into %target [class] and make print_table_entry
239e1051a39Sopenharmony_ci                        # a method)
240e1051a39Sopenharmony_ci
241e1051a39Sopenharmony_ci# Forward declarations ###############################################
242e1051a39Sopenharmony_ci
243e1051a39Sopenharmony_ci# read_config(filename)
244e1051a39Sopenharmony_ci#
245e1051a39Sopenharmony_ci# Reads a configuration file and populates %table with the contents
246e1051a39Sopenharmony_ci# (which the configuration file places in %targets).
247e1051a39Sopenharmony_cisub read_config;
248e1051a39Sopenharmony_ci
249e1051a39Sopenharmony_ci# resolve_config(target)
250e1051a39Sopenharmony_ci#
251e1051a39Sopenharmony_ci# Resolves all the late evaluations, inheritances and so on for the
252e1051a39Sopenharmony_ci# chosen target and any target it inherits from.
253e1051a39Sopenharmony_cisub resolve_config;
254e1051a39Sopenharmony_ci
255e1051a39Sopenharmony_ci
256e1051a39Sopenharmony_ci# Information collection #############################################
257e1051a39Sopenharmony_ci
258e1051a39Sopenharmony_ci# Unified build supports separate build dir
259e1051a39Sopenharmony_cimy $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
260e1051a39Sopenharmony_cimy $blddir = catdir(absolutedir("."));         # catdir ensures local syntax
261e1051a39Sopenharmony_ci
262e1051a39Sopenharmony_ci# File::Spec::Unix doesn't detect case insensitivity, so we make sure to
263e1051a39Sopenharmony_ci# check if the source and build directory are really the same, and make
264e1051a39Sopenharmony_ci# them so.  This avoids all kinds of confusion later on.
265e1051a39Sopenharmony_ci# We must check @File::Spec::ISA rather than using File::Spec->isa() to
266e1051a39Sopenharmony_ci# know if File::Spec ended up loading File::Spec::Unix.
267e1051a39Sopenharmony_ci$srcdir = $blddir
268e1051a39Sopenharmony_ci    if (grep(/::Unix$/, @File::Spec::ISA)
269e1051a39Sopenharmony_ci        && samedir($srcdir, $blddir));
270e1051a39Sopenharmony_ci
271e1051a39Sopenharmony_cimy $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
272e1051a39Sopenharmony_ci
273e1051a39Sopenharmony_cimy $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
274e1051a39Sopenharmony_ci
275e1051a39Sopenharmony_ci$config{sourcedir} = abs2rel($srcdir, $blddir);
276e1051a39Sopenharmony_ci$config{builddir} = abs2rel($blddir, $blddir);
277e1051a39Sopenharmony_ci# echo -n 'holy hand grenade of antioch' | openssl sha256
278e1051a39Sopenharmony_ci$config{FIPSKEY} =
279e1051a39Sopenharmony_ci    'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
280e1051a39Sopenharmony_ci
281e1051a39Sopenharmony_ci# Collect reconfiguration information if needed
282e1051a39Sopenharmony_cimy @argvcopy=@ARGV;
283e1051a39Sopenharmony_ci
284e1051a39Sopenharmony_ciif (grep /^reconf(igure)?$/, @argvcopy) {
285e1051a39Sopenharmony_ci    die "reconfiguring with other arguments present isn't supported"
286e1051a39Sopenharmony_ci        if scalar @argvcopy > 1;
287e1051a39Sopenharmony_ci    if (-f "./configdata.pm") {
288e1051a39Sopenharmony_ci        my $file = "./configdata.pm";
289e1051a39Sopenharmony_ci        unless (my $return = do $file) {
290e1051a39Sopenharmony_ci            die "couldn't parse $file: $@" if $@;
291e1051a39Sopenharmony_ci            die "couldn't do $file: $!"    unless defined $return;
292e1051a39Sopenharmony_ci            die "couldn't run $file"       unless $return;
293e1051a39Sopenharmony_ci        }
294e1051a39Sopenharmony_ci
295e1051a39Sopenharmony_ci        @argvcopy = defined($configdata::config{perlargv}) ?
296e1051a39Sopenharmony_ci            @{$configdata::config{perlargv}} : ();
297e1051a39Sopenharmony_ci        die "Incorrect data to reconfigure, please do a normal configuration\n"
298e1051a39Sopenharmony_ci            if (grep(/^reconf/,@argvcopy));
299e1051a39Sopenharmony_ci        $config{perlenv} = $configdata::config{perlenv} // {};
300e1051a39Sopenharmony_ci    } else {
301e1051a39Sopenharmony_ci        die "Insufficient data to reconfigure, please do a normal configuration\n";
302e1051a39Sopenharmony_ci    }
303e1051a39Sopenharmony_ci}
304e1051a39Sopenharmony_ci
305e1051a39Sopenharmony_ci$config{perlargv} = [ @argvcopy ];
306e1051a39Sopenharmony_ci
307e1051a39Sopenharmony_ci# Historical: if known directories in crypto/ have been removed, it means
308e1051a39Sopenharmony_ci# that those sub-systems are disabled.
309e1051a39Sopenharmony_ci# (the other option would be to removed them from the SUBDIRS statement in
310e1051a39Sopenharmony_ci# crypto/build.info)
311e1051a39Sopenharmony_ci# We reverse the input list for cosmetic purely reasons, to compensate that
312e1051a39Sopenharmony_ci# 'unshift' adds at the front of the list (i.e. in reverse input order).
313e1051a39Sopenharmony_ciforeach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh',
314e1051a39Sopenharmony_ci                        'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2',
315e1051a39Sopenharmony_ci                        'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha',
316e1051a39Sopenharmony_ci                        'sm2', 'sm3', 'sm4') ) {
317e1051a39Sopenharmony_ci    unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_);
318e1051a39Sopenharmony_ci}
319e1051a39Sopenharmony_ci
320e1051a39Sopenharmony_ci# Collect version numbers
321e1051a39Sopenharmony_cimy %version = ();
322e1051a39Sopenharmony_ci
323e1051a39Sopenharmony_cicollect_information(
324e1051a39Sopenharmony_ci    collect_from_file(catfile($srcdir,'VERSION.dat')),
325e1051a39Sopenharmony_ci    qr/\s*(\w+)\s*=\s*(.*?)\s*$/ =>
326e1051a39Sopenharmony_ci        sub {
327e1051a39Sopenharmony_ci            # Only define it if there is a value at all
328e1051a39Sopenharmony_ci            if ($2 ne '') {
329e1051a39Sopenharmony_ci                my $k = $1;
330e1051a39Sopenharmony_ci                my $v = $2;
331e1051a39Sopenharmony_ci                # Some values are quoted.  Trim the quotes
332e1051a39Sopenharmony_ci                $v = $1 if $v =~ /^"(.*)"$/;
333e1051a39Sopenharmony_ci                $version{uc $k} = $v;
334e1051a39Sopenharmony_ci            }
335e1051a39Sopenharmony_ci        },
336e1051a39Sopenharmony_ci    "OTHERWISE" =>
337e1051a39Sopenharmony_ci        sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" },
338e1051a39Sopenharmony_ci    );
339e1051a39Sopenharmony_ci
340e1051a39Sopenharmony_ci$config{major} = $version{MAJOR} // 'unknown';
341e1051a39Sopenharmony_ci$config{minor} = $version{MINOR} // 'unknown';
342e1051a39Sopenharmony_ci$config{patch} = $version{PATCH} // 'unknown';
343e1051a39Sopenharmony_ci$config{prerelease} =
344e1051a39Sopenharmony_ci    defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : '';
345e1051a39Sopenharmony_ci$config{build_metadata} =
346e1051a39Sopenharmony_ci    defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : '';
347e1051a39Sopenharmony_ci$config{shlib_version} = $version{SHLIB_VERSION} // 'unknown';
348e1051a39Sopenharmony_ci$config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx';
349e1051a39Sopenharmony_ci
350e1051a39Sopenharmony_ci$config{version} = "$config{major}.$config{minor}.$config{patch}";
351e1051a39Sopenharmony_ci$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
352e1051a39Sopenharmony_ci
353e1051a39Sopenharmony_cidie "erroneous version information in VERSION.dat: ",
354e1051a39Sopenharmony_ci    "$config{version}, $config{shlib_version}\n"
355e1051a39Sopenharmony_ci    unless (defined $version{MAJOR}
356e1051a39Sopenharmony_ci            && defined $version{MINOR}
357e1051a39Sopenharmony_ci            && defined $version{PATCH}
358e1051a39Sopenharmony_ci            && defined $version{SHLIB_VERSION});
359e1051a39Sopenharmony_ci
360e1051a39Sopenharmony_ci# Collect target configurations
361e1051a39Sopenharmony_ci
362e1051a39Sopenharmony_cimy $pattern = catfile(dirname($0), "Configurations", "*.conf");
363e1051a39Sopenharmony_ciforeach (sort glob($pattern)) {
364e1051a39Sopenharmony_ci    &read_config($_);
365e1051a39Sopenharmony_ci}
366e1051a39Sopenharmony_ci
367e1051a39Sopenharmony_ciif (defined env($local_config_envname)) {
368e1051a39Sopenharmony_ci    if ($^O eq 'VMS') {
369e1051a39Sopenharmony_ci        # VMS environment variables are logical names,
370e1051a39Sopenharmony_ci        # which can be used as is
371e1051a39Sopenharmony_ci        $pattern = $local_config_envname . ':' . '*.conf';
372e1051a39Sopenharmony_ci    } else {
373e1051a39Sopenharmony_ci        $pattern = catfile(env($local_config_envname), '*.conf');
374e1051a39Sopenharmony_ci    }
375e1051a39Sopenharmony_ci
376e1051a39Sopenharmony_ci    foreach (sort glob($pattern)) {
377e1051a39Sopenharmony_ci        &read_config($_);
378e1051a39Sopenharmony_ci    }
379e1051a39Sopenharmony_ci}
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_ci# Save away perl command information
382e1051a39Sopenharmony_ci$config{perl_cmd} = $^X;
383e1051a39Sopenharmony_ci$config{perl_version} = $Config{version};
384e1051a39Sopenharmony_ci$config{perl_archname} = $Config{archname};
385e1051a39Sopenharmony_ci
386e1051a39Sopenharmony_ci$config{prefix}="";
387e1051a39Sopenharmony_ci$config{openssldir}="";
388e1051a39Sopenharmony_ci$config{processor}="";
389e1051a39Sopenharmony_ci$config{libdir}="";
390e1051a39Sopenharmony_cimy $auto_threads=1;    # enable threads automatically? true by default
391e1051a39Sopenharmony_cimy $default_ranlib;
392e1051a39Sopenharmony_ci
393e1051a39Sopenharmony_ci# Known TLS and DTLS protocols
394e1051a39Sopenharmony_cimy @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
395e1051a39Sopenharmony_cimy @dtls = qw(dtls1 dtls1_2);
396e1051a39Sopenharmony_ci
397e1051a39Sopenharmony_ci# Explicitly known options that are possible to disable.  They can
398e1051a39Sopenharmony_ci# be regexps, and will be used like this: /^no-${option}$/
399e1051a39Sopenharmony_ci# For developers: keep it sorted alphabetically
400e1051a39Sopenharmony_ci
401e1051a39Sopenharmony_cimy @disablables = (
402e1051a39Sopenharmony_ci    "acvp-tests",
403e1051a39Sopenharmony_ci    "afalgeng",
404e1051a39Sopenharmony_ci    "aria",
405e1051a39Sopenharmony_ci    "asan",
406e1051a39Sopenharmony_ci    "asm",
407e1051a39Sopenharmony_ci    "async",
408e1051a39Sopenharmony_ci    "autoalginit",
409e1051a39Sopenharmony_ci    "autoerrinit",
410e1051a39Sopenharmony_ci    "autoload-config",
411e1051a39Sopenharmony_ci    "bf",
412e1051a39Sopenharmony_ci    "blake2",
413e1051a39Sopenharmony_ci    "buildtest-c++",
414e1051a39Sopenharmony_ci    "bulk",
415e1051a39Sopenharmony_ci    "cached-fetch",
416e1051a39Sopenharmony_ci    "camellia",
417e1051a39Sopenharmony_ci    "capieng",
418e1051a39Sopenharmony_ci    "cast",
419e1051a39Sopenharmony_ci    "chacha",
420e1051a39Sopenharmony_ci    "cmac",
421e1051a39Sopenharmony_ci    "cmp",
422e1051a39Sopenharmony_ci    "cms",
423e1051a39Sopenharmony_ci    "comp",
424e1051a39Sopenharmony_ci    "crypto-mdebug",
425e1051a39Sopenharmony_ci    "ct",
426e1051a39Sopenharmony_ci    "deprecated",
427e1051a39Sopenharmony_ci    "des",
428e1051a39Sopenharmony_ci    "devcryptoeng",
429e1051a39Sopenharmony_ci    "dgram",
430e1051a39Sopenharmony_ci    "dh",
431e1051a39Sopenharmony_ci    "dsa",
432e1051a39Sopenharmony_ci    "dso",
433e1051a39Sopenharmony_ci    "dtls",
434e1051a39Sopenharmony_ci    "dynamic-engine",
435e1051a39Sopenharmony_ci    "ec",
436e1051a39Sopenharmony_ci    "ec2m",
437e1051a39Sopenharmony_ci    "ec_nistp_64_gcc_128",
438e1051a39Sopenharmony_ci    "ecdh",
439e1051a39Sopenharmony_ci    "ecdsa",
440e1051a39Sopenharmony_ci    "egd",
441e1051a39Sopenharmony_ci    "engine",
442e1051a39Sopenharmony_ci    "err",
443e1051a39Sopenharmony_ci    "external-tests",
444e1051a39Sopenharmony_ci    "filenames",
445e1051a39Sopenharmony_ci    "fips",
446e1051a39Sopenharmony_ci    "fips-securitychecks",
447e1051a39Sopenharmony_ci    "fuzz-afl",
448e1051a39Sopenharmony_ci    "fuzz-libfuzzer",
449e1051a39Sopenharmony_ci    "gost",
450e1051a39Sopenharmony_ci    "idea",
451e1051a39Sopenharmony_ci    "ktls",
452e1051a39Sopenharmony_ci    "legacy",
453e1051a39Sopenharmony_ci    "loadereng",
454e1051a39Sopenharmony_ci    "makedepend",
455e1051a39Sopenharmony_ci    "md2",
456e1051a39Sopenharmony_ci    "md4",
457e1051a39Sopenharmony_ci    "mdc2",
458e1051a39Sopenharmony_ci    "module",
459e1051a39Sopenharmony_ci    "msan",
460e1051a39Sopenharmony_ci    "multiblock",
461e1051a39Sopenharmony_ci    "nextprotoneg",
462e1051a39Sopenharmony_ci    "ocb",
463e1051a39Sopenharmony_ci    "ocsp",
464e1051a39Sopenharmony_ci    "padlockeng",
465e1051a39Sopenharmony_ci    "pic",
466e1051a39Sopenharmony_ci    "pinshared",
467e1051a39Sopenharmony_ci    "poly1305",
468e1051a39Sopenharmony_ci    "posix-io",
469e1051a39Sopenharmony_ci    "psk",
470e1051a39Sopenharmony_ci    "rc2",
471e1051a39Sopenharmony_ci    "rc4",
472e1051a39Sopenharmony_ci    "rc5",
473e1051a39Sopenharmony_ci    "rdrand",
474e1051a39Sopenharmony_ci    "rfc3779",
475e1051a39Sopenharmony_ci    "rmd160",
476e1051a39Sopenharmony_ci    "scrypt",
477e1051a39Sopenharmony_ci    "sctp",
478e1051a39Sopenharmony_ci    "secure-memory",
479e1051a39Sopenharmony_ci    "seed",
480e1051a39Sopenharmony_ci    "shared",
481e1051a39Sopenharmony_ci    "siphash",
482e1051a39Sopenharmony_ci    "siv",
483e1051a39Sopenharmony_ci    "sm2",
484e1051a39Sopenharmony_ci    "sm3",
485e1051a39Sopenharmony_ci    "sm4",
486e1051a39Sopenharmony_ci    "sock",
487e1051a39Sopenharmony_ci    "srp",
488e1051a39Sopenharmony_ci    "srtp",
489e1051a39Sopenharmony_ci    "sse2",
490e1051a39Sopenharmony_ci    "ssl",
491e1051a39Sopenharmony_ci    "ssl-trace",
492e1051a39Sopenharmony_ci    "static-engine",
493e1051a39Sopenharmony_ci    "stdio",
494e1051a39Sopenharmony_ci    "tests",
495e1051a39Sopenharmony_ci    "threads",
496e1051a39Sopenharmony_ci    "tls",
497e1051a39Sopenharmony_ci    "trace",
498e1051a39Sopenharmony_ci    "ts",
499e1051a39Sopenharmony_ci    "ubsan",
500e1051a39Sopenharmony_ci    "ui-console",
501e1051a39Sopenharmony_ci    "unit-test",
502e1051a39Sopenharmony_ci    "uplink",
503e1051a39Sopenharmony_ci    "weak-ssl-ciphers",
504e1051a39Sopenharmony_ci    "whirlpool",
505e1051a39Sopenharmony_ci    "zlib",
506e1051a39Sopenharmony_ci    "zlib-dynamic",
507e1051a39Sopenharmony_ci    );
508e1051a39Sopenharmony_ciforeach my $proto ((@tls, @dtls))
509e1051a39Sopenharmony_ci        {
510e1051a39Sopenharmony_ci        push(@disablables, $proto);
511e1051a39Sopenharmony_ci        push(@disablables, "$proto-method") unless $proto eq "tls1_3";
512e1051a39Sopenharmony_ci        }
513e1051a39Sopenharmony_ci
514e1051a39Sopenharmony_ci# Internal disablables, for aliasing purposes.  They serve no special
515e1051a39Sopenharmony_ci# purpose here, but allow scripts to get to know them through configdata.pm,
516e1051a39Sopenharmony_ci# where these are merged with @disablables.
517e1051a39Sopenharmony_ci# The actual aliasing mechanism is done via %disable_cascades
518e1051a39Sopenharmony_cimy @disablables_int = qw(
519e1051a39Sopenharmony_ci    crmf
520e1051a39Sopenharmony_ci    );
521e1051a39Sopenharmony_ci
522e1051a39Sopenharmony_cimy %deprecated_disablables = (
523e1051a39Sopenharmony_ci    "ssl2" => undef,
524e1051a39Sopenharmony_ci    "buf-freelists" => undef,
525e1051a39Sopenharmony_ci    "crypto-mdebug-backtrace" => undef,
526e1051a39Sopenharmony_ci    "hw" => "hw",               # causes cascade, but no macro
527e1051a39Sopenharmony_ci    "hw-padlock" => "padlockeng",
528e1051a39Sopenharmony_ci    "ripemd" => "rmd160",
529e1051a39Sopenharmony_ci    "ui" => "ui-console",
530e1051a39Sopenharmony_ci    "heartbeats" => undef,
531e1051a39Sopenharmony_ci    );
532e1051a39Sopenharmony_ci
533e1051a39Sopenharmony_ci# All of the following are disabled by default:
534e1051a39Sopenharmony_ci
535e1051a39Sopenharmony_ciour %disabled = ( # "what"         => "comment"
536e1051a39Sopenharmony_ci                  "fips"                => "default",
537e1051a39Sopenharmony_ci                  "asan"                => "default",
538e1051a39Sopenharmony_ci                  "buildtest-c++"       => "default",
539e1051a39Sopenharmony_ci                  "crypto-mdebug"       => "default",
540e1051a39Sopenharmony_ci                  "crypto-mdebug-backtrace" => "default",
541e1051a39Sopenharmony_ci                  "devcryptoeng"        => "default",
542e1051a39Sopenharmony_ci                  "ec_nistp_64_gcc_128" => "default",
543e1051a39Sopenharmony_ci                  "egd"                 => "default",
544e1051a39Sopenharmony_ci                  "external-tests"      => "default",
545e1051a39Sopenharmony_ci                  "fuzz-afl"            => "default",
546e1051a39Sopenharmony_ci                  "fuzz-libfuzzer"      => "default",
547e1051a39Sopenharmony_ci                  "ktls"                => "default",
548e1051a39Sopenharmony_ci                  "md2"                 => "default",
549e1051a39Sopenharmony_ci                  "msan"                => "default",
550e1051a39Sopenharmony_ci                  "rc5"                 => "default",
551e1051a39Sopenharmony_ci                  "sctp"                => "default",
552e1051a39Sopenharmony_ci                  "ssl3"                => "default",
553e1051a39Sopenharmony_ci                  "ssl3-method"         => "default",
554e1051a39Sopenharmony_ci                  "trace"               => "default",
555e1051a39Sopenharmony_ci                  "ubsan"               => "default",
556e1051a39Sopenharmony_ci                  "unit-test"           => "default",
557e1051a39Sopenharmony_ci                  "weak-ssl-ciphers"    => "default",
558e1051a39Sopenharmony_ci                  "zlib"                => "default",
559e1051a39Sopenharmony_ci                  "zlib-dynamic"        => "default",
560e1051a39Sopenharmony_ci                );
561e1051a39Sopenharmony_ci
562e1051a39Sopenharmony_ci# Note: => pair form used for aesthetics, not to truly make a hash table
563e1051a39Sopenharmony_cimy @disable_cascades = (
564e1051a39Sopenharmony_ci    # "what"            => [ "cascade", ... ]
565e1051a39Sopenharmony_ci    "bulk"              => [ "shared", "dso",
566e1051a39Sopenharmony_ci                             "aria", "async", "autoload-config",
567e1051a39Sopenharmony_ci                             "blake2", "bf", "camellia", "cast", "chacha",
568e1051a39Sopenharmony_ci                             "cmac", "cms", "cmp", "comp", "ct",
569e1051a39Sopenharmony_ci                             "des", "dgram", "dh", "dsa",
570e1051a39Sopenharmony_ci                             "ec", "engine",
571e1051a39Sopenharmony_ci                             "filenames",
572e1051a39Sopenharmony_ci                             "idea", "ktls",
573e1051a39Sopenharmony_ci                             "md4", "multiblock", "nextprotoneg",
574e1051a39Sopenharmony_ci                             "ocsp", "ocb", "poly1305", "psk",
575e1051a39Sopenharmony_ci                             "rc2", "rc4", "rmd160",
576e1051a39Sopenharmony_ci                             "seed", "siphash", "siv",
577e1051a39Sopenharmony_ci                             "sm3", "sm4", "srp",
578e1051a39Sopenharmony_ci                             "srtp", "ssl3-method", "ssl-trace",
579e1051a39Sopenharmony_ci                             "ts", "ui-console", "whirlpool",
580e1051a39Sopenharmony_ci                             "fips-securitychecks" ],
581e1051a39Sopenharmony_ci    sub { $config{processor} eq "386" }
582e1051a39Sopenharmony_ci                        => [ "sse2" ],
583e1051a39Sopenharmony_ci    "ssl"               => [ "ssl3" ],
584e1051a39Sopenharmony_ci    "ssl3-method"       => [ "ssl3" ],
585e1051a39Sopenharmony_ci    "zlib"              => [ "zlib-dynamic" ],
586e1051a39Sopenharmony_ci    "des"               => [ "mdc2" ],
587e1051a39Sopenharmony_ci    "ec"                => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ],
588e1051a39Sopenharmony_ci    "dgram"             => [ "dtls", "sctp" ],
589e1051a39Sopenharmony_ci    "sock"              => [ "dgram" ],
590e1051a39Sopenharmony_ci    "dtls"              => [ @dtls ],
591e1051a39Sopenharmony_ci    sub { 0 == scalar grep { !$disabled{$_} } @dtls }
592e1051a39Sopenharmony_ci                        => [ "dtls" ],
593e1051a39Sopenharmony_ci
594e1051a39Sopenharmony_ci    "tls"               => [ @tls ],
595e1051a39Sopenharmony_ci    sub { 0 == scalar grep { !$disabled{$_} } @tls }
596e1051a39Sopenharmony_ci                        => [ "tls" ],
597e1051a39Sopenharmony_ci
598e1051a39Sopenharmony_ci    "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
599e1051a39Sopenharmony_ci
600e1051a39Sopenharmony_ci    # If no modules, then no dynamic engines either
601e1051a39Sopenharmony_ci    "module"            => [ "dynamic-engine" ],
602e1051a39Sopenharmony_ci
603e1051a39Sopenharmony_ci    # Without shared libraries, dynamic engines aren't possible.
604e1051a39Sopenharmony_ci    # This is due to them having to link with libcrypto and register features
605e1051a39Sopenharmony_ci    # using the ENGINE functionality, and since that relies on global tables,
606e1051a39Sopenharmony_ci    # those *have* to be exacty the same as the ones accessed from the app,
607e1051a39Sopenharmony_ci    # which cannot be guaranteed if shared libraries aren't present.
608e1051a39Sopenharmony_ci    # (note that even with shared libraries, both the app and dynamic engines
609e1051a39Sopenharmony_ci    # must be linked with the same library)
610e1051a39Sopenharmony_ci    "shared"            => [ "dynamic-engine", "uplink" ],
611e1051a39Sopenharmony_ci    "dso"               => [ "dynamic-engine", "module" ],
612e1051a39Sopenharmony_ci    # Other modules don't necessarily have to link with libcrypto, so shared
613e1051a39Sopenharmony_ci    # libraries do not have to be a condition to produce those.
614e1051a39Sopenharmony_ci
615e1051a39Sopenharmony_ci    # Without position independent code, there can be no shared libraries
616e1051a39Sopenharmony_ci    # or modules.
617e1051a39Sopenharmony_ci    "pic"               => [ "shared", "module" ],
618e1051a39Sopenharmony_ci
619e1051a39Sopenharmony_ci    "module"            => [ "fips", "dso" ],
620e1051a39Sopenharmony_ci
621e1051a39Sopenharmony_ci    "engine"            => [ "dynamic-engine", grep(/eng$/, @disablables) ],
622e1051a39Sopenharmony_ci    "dynamic-engine"    => [ "loadereng" ],
623e1051a39Sopenharmony_ci    "hw"                => [ "padlockeng" ],
624e1051a39Sopenharmony_ci
625e1051a39Sopenharmony_ci    # no-autoalginit is only useful when building non-shared
626e1051a39Sopenharmony_ci    "autoalginit"       => [ "shared", "apps", "fips" ],
627e1051a39Sopenharmony_ci
628e1051a39Sopenharmony_ci    "stdio"             => [ "apps", "capieng", "egd" ],
629e1051a39Sopenharmony_ci    "apps"              => [ "tests" ],
630e1051a39Sopenharmony_ci    "tests"             => [ "external-tests" ],
631e1051a39Sopenharmony_ci    "comp"              => [ "zlib" ],
632e1051a39Sopenharmony_ci    "sm3"               => [ "sm2" ],
633e1051a39Sopenharmony_ci    sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
634e1051a39Sopenharmony_ci
635e1051a39Sopenharmony_ci    sub { !$disabled{"msan"} } => [ "asm" ],
636e1051a39Sopenharmony_ci
637e1051a39Sopenharmony_ci    "cmac"              => [ "siv" ],
638e1051a39Sopenharmony_ci    "legacy"            => [ "md2" ],
639e1051a39Sopenharmony_ci
640e1051a39Sopenharmony_ci    "cmp"               => [ "crmf" ],
641e1051a39Sopenharmony_ci
642e1051a39Sopenharmony_ci    "fips"              => [ "fips-securitychecks", "acvp-tests" ],
643e1051a39Sopenharmony_ci
644e1051a39Sopenharmony_ci    "deprecated-3.0"    => [ "engine", "srp" ]
645e1051a39Sopenharmony_ci    );
646e1051a39Sopenharmony_ci
647e1051a39Sopenharmony_ci# Avoid protocol support holes.  Also disable all versions below N, if version
648e1051a39Sopenharmony_ci# N is disabled while N+1 is enabled.
649e1051a39Sopenharmony_ci#
650e1051a39Sopenharmony_cimy @list = (reverse @tls);
651e1051a39Sopenharmony_ciwhile ((my $first, my $second) = (shift @list, shift @list)) {
652e1051a39Sopenharmony_ci    last unless @list;
653e1051a39Sopenharmony_ci    push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
654e1051a39Sopenharmony_ci                              => [ @list ] );
655e1051a39Sopenharmony_ci    unshift @list, $second;
656e1051a39Sopenharmony_ci}
657e1051a39Sopenharmony_cimy @list = (reverse @dtls);
658e1051a39Sopenharmony_ciwhile ((my $first, my $second) = (shift @list, shift @list)) {
659e1051a39Sopenharmony_ci    last unless @list;
660e1051a39Sopenharmony_ci    push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
661e1051a39Sopenharmony_ci                              => [ @list ] );
662e1051a39Sopenharmony_ci    unshift @list, $second;
663e1051a39Sopenharmony_ci}
664e1051a39Sopenharmony_ci
665e1051a39Sopenharmony_ci# Explicit "no-..." options will be collected in %disabled along with the defaults.
666e1051a39Sopenharmony_ci# To remove something from %disabled, use "enable-foo".
667e1051a39Sopenharmony_ci# For symmetry, "disable-foo" is a synonym for "no-foo".
668e1051a39Sopenharmony_ci
669e1051a39Sopenharmony_ci# For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with
670e1051a39Sopenharmony_ci# platform specific list separators.  Users from those platforms should
671e1051a39Sopenharmony_ci# recognise those separators from how you set up the PATH to find executables.
672e1051a39Sopenharmony_ci# The default is the Unix like separator, :, but as an exception, we also
673e1051a39Sopenharmony_ci# support the space as separator.
674e1051a39Sopenharmony_cimy $list_separator_re =
675e1051a39Sopenharmony_ci    { VMS           => qr/(?<!\^),/,
676e1051a39Sopenharmony_ci      MSWin32       => qr/(?<!\\);/ } -> {$^O} // qr/(?<!\\)[:\s]/;
677e1051a39Sopenharmony_ci# All the "make variables" we support
678e1051a39Sopenharmony_ci# Some get pre-populated for the sake of backward compatibility
679e1051a39Sopenharmony_ci# (we supported those before the change to "make variable" support.
680e1051a39Sopenharmony_cimy %user = (
681e1051a39Sopenharmony_ci    AR          => env('AR'),
682e1051a39Sopenharmony_ci    ARFLAGS     => [],
683e1051a39Sopenharmony_ci    AS          => undef,
684e1051a39Sopenharmony_ci    ASFLAGS     => [],
685e1051a39Sopenharmony_ci    CC          => env('CC'),
686e1051a39Sopenharmony_ci    CFLAGS      => [ env('CFLAGS') || () ],
687e1051a39Sopenharmony_ci    CXX         => env('CXX'),
688e1051a39Sopenharmony_ci    CXXFLAGS    => [ env('CXXFLAGS') || () ],
689e1051a39Sopenharmony_ci    CPP         => undef,
690e1051a39Sopenharmony_ci    CPPFLAGS    => [ env('CPPFLAGS') || () ],  # -D, -I, -Wp,
691e1051a39Sopenharmony_ci    CPPDEFINES  => [],  # Alternative for -D
692e1051a39Sopenharmony_ci    CPPINCLUDES => [],  # Alternative for -I
693e1051a39Sopenharmony_ci    CROSS_COMPILE => env('CROSS_COMPILE'),
694e1051a39Sopenharmony_ci    HASHBANGPERL=> env('HASHBANGPERL') || env('PERL'),
695e1051a39Sopenharmony_ci    LD          => undef,
696e1051a39Sopenharmony_ci    LDFLAGS     => [ env('LDFLAGS') || () ],  # -L, -Wl,
697e1051a39Sopenharmony_ci    LDLIBS      => [ env('LDLIBS') || () ],  # -l
698e1051a39Sopenharmony_ci    MT          => undef,
699e1051a39Sopenharmony_ci    MTFLAGS     => [],
700e1051a39Sopenharmony_ci    PERL        => env('PERL') || ($^O ne "VMS" ? $^X : "perl"),
701e1051a39Sopenharmony_ci    RANLIB      => env('RANLIB'),
702e1051a39Sopenharmony_ci    RC          => env('RC') || env('WINDRES'),
703e1051a39Sopenharmony_ci    RCFLAGS     => [ env('RCFLAGS') || () ],
704e1051a39Sopenharmony_ci    RM          => undef,
705e1051a39Sopenharmony_ci   );
706e1051a39Sopenharmony_ci# Info about what "make variables" may be prefixed with the cross compiler
707e1051a39Sopenharmony_ci# prefix.  This should NEVER mention any such variable with a list for value.
708e1051a39Sopenharmony_cimy @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC );
709e1051a39Sopenharmony_ci# The same but for flags given as Configure options.  These are *additional*
710e1051a39Sopenharmony_ci# input, as opposed to the VAR=string option that override the corresponding
711e1051a39Sopenharmony_ci# config target attributes
712e1051a39Sopenharmony_cimy %useradd = (
713e1051a39Sopenharmony_ci    CPPDEFINES  => [],
714e1051a39Sopenharmony_ci    CPPINCLUDES => [],
715e1051a39Sopenharmony_ci    CPPFLAGS    => [],
716e1051a39Sopenharmony_ci    CFLAGS      => [],
717e1051a39Sopenharmony_ci    CXXFLAGS    => [],
718e1051a39Sopenharmony_ci    LDFLAGS     => [],
719e1051a39Sopenharmony_ci    LDLIBS      => [],
720e1051a39Sopenharmony_ci    RCFLAGS     => [],
721e1051a39Sopenharmony_ci   );
722e1051a39Sopenharmony_ci
723e1051a39Sopenharmony_cimy %user_synonyms = (
724e1051a39Sopenharmony_ci    HASHBANGPERL=> 'PERL',
725e1051a39Sopenharmony_ci    RC          => 'WINDRES',
726e1051a39Sopenharmony_ci   );
727e1051a39Sopenharmony_ci
728e1051a39Sopenharmony_ci# Some target attributes have been renamed, this is the translation table
729e1051a39Sopenharmony_cimy %target_attr_translate =(
730e1051a39Sopenharmony_ci    ar          => 'AR',
731e1051a39Sopenharmony_ci    as          => 'AS',
732e1051a39Sopenharmony_ci    cc          => 'CC',
733e1051a39Sopenharmony_ci    cxx         => 'CXX',
734e1051a39Sopenharmony_ci    cpp         => 'CPP',
735e1051a39Sopenharmony_ci    hashbangperl => 'HASHBANGPERL',
736e1051a39Sopenharmony_ci    ld          => 'LD',
737e1051a39Sopenharmony_ci    mt          => 'MT',
738e1051a39Sopenharmony_ci    ranlib      => 'RANLIB',
739e1051a39Sopenharmony_ci    rc          => 'RC',
740e1051a39Sopenharmony_ci    rm          => 'RM',
741e1051a39Sopenharmony_ci   );
742e1051a39Sopenharmony_ci
743e1051a39Sopenharmony_ci# Initialisers coming from 'config' scripts
744e1051a39Sopenharmony_ci$config{defines} = [ split(/$list_separator_re/, env('__CNF_CPPDEFINES')) ];
745e1051a39Sopenharmony_ci$config{includes} = [ split(/$list_separator_re/, env('__CNF_CPPINCLUDES')) ];
746e1051a39Sopenharmony_ci$config{cppflags} = [ env('__CNF_CPPFLAGS') || () ];
747e1051a39Sopenharmony_ci$config{cflags} = [ env('__CNF_CFLAGS') || () ];
748e1051a39Sopenharmony_ci$config{cxxflags} = [ env('__CNF_CXXFLAGS') || () ];
749e1051a39Sopenharmony_ci$config{lflags} = [ env('__CNF_LDFLAGS') || () ];
750e1051a39Sopenharmony_ci$config{ex_libs} = [ env('__CNF_LDLIBS') || () ];
751e1051a39Sopenharmony_ci
752e1051a39Sopenharmony_ci$config{openssl_api_defines}=[];
753e1051a39Sopenharmony_ci$config{openssl_sys_defines}=[];
754e1051a39Sopenharmony_ci$config{openssl_feature_defines}=[];
755e1051a39Sopenharmony_ci$config{options}="";
756e1051a39Sopenharmony_ci$config{build_type} = "release";
757e1051a39Sopenharmony_cimy $target="";
758e1051a39Sopenharmony_ci
759e1051a39Sopenharmony_cimy %cmdvars = ();               # Stores FOO='blah' type arguments
760e1051a39Sopenharmony_cimy %unsupported_options = ();
761e1051a39Sopenharmony_cimy %deprecated_options = ();
762e1051a39Sopenharmony_ci# If you change this, update apps/version.c
763e1051a39Sopenharmony_cimy @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
764e1051a39Sopenharmony_cimy @seed_sources = ();
765e1051a39Sopenharmony_ciwhile (@argvcopy)
766e1051a39Sopenharmony_ci        {
767e1051a39Sopenharmony_ci        $_ = shift @argvcopy;
768e1051a39Sopenharmony_ci
769e1051a39Sopenharmony_ci        # Support env variable assignments among the options
770e1051a39Sopenharmony_ci        if (m|^(\w+)=(.+)?$|)
771e1051a39Sopenharmony_ci                {
772e1051a39Sopenharmony_ci                $cmdvars{$1} = $2;
773e1051a39Sopenharmony_ci                # Every time a variable is given as a configuration argument,
774e1051a39Sopenharmony_ci                # it acts as a reset if the variable.
775e1051a39Sopenharmony_ci                if (exists $user{$1})
776e1051a39Sopenharmony_ci                        {
777e1051a39Sopenharmony_ci                        $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef;
778e1051a39Sopenharmony_ci                        }
779e1051a39Sopenharmony_ci                #if (exists $useradd{$1})
780e1051a39Sopenharmony_ci                #       {
781e1051a39Sopenharmony_ci                #       $useradd{$1} = [];
782e1051a39Sopenharmony_ci                #       }
783e1051a39Sopenharmony_ci                next;
784e1051a39Sopenharmony_ci                }
785e1051a39Sopenharmony_ci
786e1051a39Sopenharmony_ci        # VMS is a case insensitive environment, and depending on settings
787e1051a39Sopenharmony_ci        # out of our control, we may receive options uppercased.  Let's
788e1051a39Sopenharmony_ci        # downcase at least the part before any equal sign.
789e1051a39Sopenharmony_ci        if ($^O eq "VMS")
790e1051a39Sopenharmony_ci                {
791e1051a39Sopenharmony_ci                s/^([^=]*)/lc($1)/e;
792e1051a39Sopenharmony_ci                }
793e1051a39Sopenharmony_ci
794e1051a39Sopenharmony_ci        # some people just can't read the instructions, clang people have to...
795e1051a39Sopenharmony_ci        s/^-no-(?!integrated-as)/no-/;
796e1051a39Sopenharmony_ci
797e1051a39Sopenharmony_ci        # rewrite some options in "enable-..." form
798e1051a39Sopenharmony_ci        s /^-?-?shared$/enable-shared/;
799e1051a39Sopenharmony_ci        s /^sctp$/enable-sctp/;
800e1051a39Sopenharmony_ci        s /^threads$/enable-threads/;
801e1051a39Sopenharmony_ci        s /^zlib$/enable-zlib/;
802e1051a39Sopenharmony_ci        s /^zlib-dynamic$/enable-zlib-dynamic/;
803e1051a39Sopenharmony_ci        s /^fips$/enable-fips/;
804e1051a39Sopenharmony_ci
805e1051a39Sopenharmony_ci        if (/^(no|disable|enable)-(.+)$/)
806e1051a39Sopenharmony_ci                {
807e1051a39Sopenharmony_ci                my $word = $2;
808e1051a39Sopenharmony_ci                if ($word !~ m|hw(?:-.+)| # special treatment for hw regexp opt
809e1051a39Sopenharmony_ci                        && !exists $deprecated_disablables{$word}
810e1051a39Sopenharmony_ci                        && !grep { $word eq $_ } @disablables)
811e1051a39Sopenharmony_ci                        {
812e1051a39Sopenharmony_ci                        $unsupported_options{$_} = 1;
813e1051a39Sopenharmony_ci                        next;
814e1051a39Sopenharmony_ci                        }
815e1051a39Sopenharmony_ci                }
816e1051a39Sopenharmony_ci        if (/^no-(.+)$/ || /^disable-(.+)$/)
817e1051a39Sopenharmony_ci                {
818e1051a39Sopenharmony_ci                foreach my $proto ((@tls, @dtls))
819e1051a39Sopenharmony_ci                        {
820e1051a39Sopenharmony_ci                        if ($1 eq "$proto-method")
821e1051a39Sopenharmony_ci                                {
822e1051a39Sopenharmony_ci                                $disabled{"$proto"} = "option($proto-method)";
823e1051a39Sopenharmony_ci                                last;
824e1051a39Sopenharmony_ci                                }
825e1051a39Sopenharmony_ci                        }
826e1051a39Sopenharmony_ci                if ($1 eq "dtls")
827e1051a39Sopenharmony_ci                        {
828e1051a39Sopenharmony_ci                        foreach my $proto (@dtls)
829e1051a39Sopenharmony_ci                                {
830e1051a39Sopenharmony_ci                                $disabled{$proto} = "option(dtls)";
831e1051a39Sopenharmony_ci                                }
832e1051a39Sopenharmony_ci                        $disabled{"dtls"} = "option(dtls)";
833e1051a39Sopenharmony_ci                        }
834e1051a39Sopenharmony_ci                elsif ($1 eq "ssl")
835e1051a39Sopenharmony_ci                        {
836e1051a39Sopenharmony_ci                        # Last one of its kind
837e1051a39Sopenharmony_ci                        $disabled{"ssl3"} = "option(ssl)";
838e1051a39Sopenharmony_ci                        }
839e1051a39Sopenharmony_ci                elsif ($1 eq "tls")
840e1051a39Sopenharmony_ci                        {
841e1051a39Sopenharmony_ci                        # XXX: Tests will fail if all SSL/TLS
842e1051a39Sopenharmony_ci                        # protocols are disabled.
843e1051a39Sopenharmony_ci                        foreach my $proto (@tls)
844e1051a39Sopenharmony_ci                                {
845e1051a39Sopenharmony_ci                                $disabled{$proto} = "option(tls)";
846e1051a39Sopenharmony_ci                                }
847e1051a39Sopenharmony_ci                        }
848e1051a39Sopenharmony_ci                elsif ($1 eq "static-engine")
849e1051a39Sopenharmony_ci                        {
850e1051a39Sopenharmony_ci                        delete $disabled{"dynamic-engine"};
851e1051a39Sopenharmony_ci                        }
852e1051a39Sopenharmony_ci                elsif ($1 eq "dynamic-engine")
853e1051a39Sopenharmony_ci                        {
854e1051a39Sopenharmony_ci                        $disabled{"dynamic-engine"} = "option";
855e1051a39Sopenharmony_ci                        }
856e1051a39Sopenharmony_ci                elsif (exists $deprecated_disablables{$1})
857e1051a39Sopenharmony_ci                        {
858e1051a39Sopenharmony_ci                        $deprecated_options{$_} = 1;
859e1051a39Sopenharmony_ci                        if (defined $deprecated_disablables{$1})
860e1051a39Sopenharmony_ci                                {
861e1051a39Sopenharmony_ci                                $disabled{$deprecated_disablables{$1}} = "option";
862e1051a39Sopenharmony_ci                                }
863e1051a39Sopenharmony_ci                        }
864e1051a39Sopenharmony_ci                elsif ($1 =~ m|hw(?:-.+)|) # deprecate hw options in regexp form
865e1051a39Sopenharmony_ci                        {
866e1051a39Sopenharmony_ci                        $deprecated_options{$_} = 1;
867e1051a39Sopenharmony_ci                        }
868e1051a39Sopenharmony_ci                else
869e1051a39Sopenharmony_ci                        {
870e1051a39Sopenharmony_ci                        $disabled{$1} = "option";
871e1051a39Sopenharmony_ci                        }
872e1051a39Sopenharmony_ci                # No longer an automatic choice
873e1051a39Sopenharmony_ci                $auto_threads = 0 if ($1 eq "threads");
874e1051a39Sopenharmony_ci                }
875e1051a39Sopenharmony_ci        elsif (/^enable-(.+)$/)
876e1051a39Sopenharmony_ci                {
877e1051a39Sopenharmony_ci                if ($1 eq "static-engine")
878e1051a39Sopenharmony_ci                        {
879e1051a39Sopenharmony_ci                        $disabled{"dynamic-engine"} = "option";
880e1051a39Sopenharmony_ci                        }
881e1051a39Sopenharmony_ci                elsif ($1 eq "dynamic-engine")
882e1051a39Sopenharmony_ci                        {
883e1051a39Sopenharmony_ci                        delete $disabled{"dynamic-engine"};
884e1051a39Sopenharmony_ci                        }
885e1051a39Sopenharmony_ci                elsif ($1 eq "zlib-dynamic")
886e1051a39Sopenharmony_ci                        {
887e1051a39Sopenharmony_ci                        delete $disabled{"zlib"};
888e1051a39Sopenharmony_ci                        }
889e1051a39Sopenharmony_ci                my $algo = $1;
890e1051a39Sopenharmony_ci                delete $disabled{$algo};
891e1051a39Sopenharmony_ci
892e1051a39Sopenharmony_ci                # No longer an automatic choice
893e1051a39Sopenharmony_ci                $auto_threads = 0 if ($1 eq "threads");
894e1051a39Sopenharmony_ci                }
895e1051a39Sopenharmony_ci        elsif (/^-d$/)          # From older 'config'
896e1051a39Sopenharmony_ci                {
897e1051a39Sopenharmony_ci                $config{build_type} = "debug";
898e1051a39Sopenharmony_ci                }
899e1051a39Sopenharmony_ci        elsif (/^-v$/)          # From older 'config'
900e1051a39Sopenharmony_ci                {
901e1051a39Sopenharmony_ci                $guess_opts{verbose} = 1;
902e1051a39Sopenharmony_ci                }
903e1051a39Sopenharmony_ci        elsif (/^-w$/)
904e1051a39Sopenharmony_ci                {
905e1051a39Sopenharmony_ci                $guess_opts{nowait} = 1;
906e1051a39Sopenharmony_ci                }
907e1051a39Sopenharmony_ci        elsif (/^-t$/)          # From older 'config'
908e1051a39Sopenharmony_ci                {
909e1051a39Sopenharmony_ci                $dryrun = 1;
910e1051a39Sopenharmony_ci                }
911e1051a39Sopenharmony_ci        elsif (/^--strict-warnings$/)
912e1051a39Sopenharmony_ci                {
913e1051a39Sopenharmony_ci                # Pretend that our strict flags is a C flag, and replace it
914e1051a39Sopenharmony_ci                # with the proper flags later on
915e1051a39Sopenharmony_ci                push @{$useradd{CFLAGS}}, '--ossl-strict-warnings';
916e1051a39Sopenharmony_ci                $strict_warnings=1;
917e1051a39Sopenharmony_ci                }
918e1051a39Sopenharmony_ci        elsif (/^--debug$/)
919e1051a39Sopenharmony_ci                {
920e1051a39Sopenharmony_ci                $config{build_type} = "debug";
921e1051a39Sopenharmony_ci                }
922e1051a39Sopenharmony_ci        elsif (/^--release$/)
923e1051a39Sopenharmony_ci                {
924e1051a39Sopenharmony_ci                $config{build_type} = "release";
925e1051a39Sopenharmony_ci                }
926e1051a39Sopenharmony_ci        elsif (/^386$/)
927e1051a39Sopenharmony_ci                { $config{processor}=386; }
928e1051a39Sopenharmony_ci        elsif (/^rsaref$/)
929e1051a39Sopenharmony_ci                {
930e1051a39Sopenharmony_ci                # No RSAref support any more since it's not needed.
931e1051a39Sopenharmony_ci                # The check for the option is there so scripts aren't
932e1051a39Sopenharmony_ci                # broken
933e1051a39Sopenharmony_ci                }
934e1051a39Sopenharmony_ci        elsif (m|^[-+/]|)
935e1051a39Sopenharmony_ci                {
936e1051a39Sopenharmony_ci                if (/^--prefix=(.*)$/)
937e1051a39Sopenharmony_ci                        {
938e1051a39Sopenharmony_ci                        $config{prefix}=$1;
939e1051a39Sopenharmony_ci                        die "Directory given with --prefix MUST be absolute\n"
940e1051a39Sopenharmony_ci                                unless file_name_is_absolute($config{prefix});
941e1051a39Sopenharmony_ci                        }
942e1051a39Sopenharmony_ci                elsif (/^--api=(.*)$/)
943e1051a39Sopenharmony_ci                        {
944e1051a39Sopenharmony_ci                        my $api = $1;
945e1051a39Sopenharmony_ci                        die "Unknown API compatibility level $api"
946e1051a39Sopenharmony_ci                                unless defined $apitable->{$api};
947e1051a39Sopenharmony_ci                        $config{api}=$apitable->{$api};
948e1051a39Sopenharmony_ci                        }
949e1051a39Sopenharmony_ci                elsif (/^--libdir=(.*)$/)
950e1051a39Sopenharmony_ci                        {
951e1051a39Sopenharmony_ci                        $config{libdir}=$1;
952e1051a39Sopenharmony_ci                        }
953e1051a39Sopenharmony_ci                elsif (/^--openssldir=(.*)$/)
954e1051a39Sopenharmony_ci                        {
955e1051a39Sopenharmony_ci                        $config{openssldir}=$1;
956e1051a39Sopenharmony_ci                        }
957e1051a39Sopenharmony_ci                elsif (/^--with-zlib-lib=(.*)$/)
958e1051a39Sopenharmony_ci                        {
959e1051a39Sopenharmony_ci                        $withargs{zlib_lib}=$1;
960e1051a39Sopenharmony_ci                        }
961e1051a39Sopenharmony_ci                elsif (/^--with-zlib-include=(.*)$/)
962e1051a39Sopenharmony_ci                        {
963e1051a39Sopenharmony_ci                        $withargs{zlib_include}=$1;
964e1051a39Sopenharmony_ci                        }
965e1051a39Sopenharmony_ci                elsif (/^--with-fuzzer-lib=(.*)$/)
966e1051a39Sopenharmony_ci                        {
967e1051a39Sopenharmony_ci                        $withargs{fuzzer_lib}=$1;
968e1051a39Sopenharmony_ci                        }
969e1051a39Sopenharmony_ci                elsif (/^--with-fuzzer-include=(.*)$/)
970e1051a39Sopenharmony_ci                        {
971e1051a39Sopenharmony_ci                        $withargs{fuzzer_include}=$1;
972e1051a39Sopenharmony_ci                        }
973e1051a39Sopenharmony_ci                elsif (/^--with-rand-seed=(.*)$/)
974e1051a39Sopenharmony_ci                        {
975e1051a39Sopenharmony_ci                        foreach my $x (split(m|,|, $1))
976e1051a39Sopenharmony_ci                            {
977e1051a39Sopenharmony_ci                            die "Unknown --with-rand-seed choice $x\n"
978e1051a39Sopenharmony_ci                                if ! grep { $x eq $_ } @known_seed_sources;
979e1051a39Sopenharmony_ci                            push @seed_sources, $x;
980e1051a39Sopenharmony_ci                            }
981e1051a39Sopenharmony_ci                        }
982e1051a39Sopenharmony_ci                elsif (/^--fips-key=(.*)$/)
983e1051a39Sopenharmony_ci                        {
984e1051a39Sopenharmony_ci                        $user{FIPSKEY}=lc($1);
985e1051a39Sopenharmony_ci                        die "Non-hex character in FIPS key\n"
986e1051a39Sopenharmony_ci                           if $user{FIPSKEY} =~ /[^a-f0-9]/;
987e1051a39Sopenharmony_ci                        die "FIPS key must have even number of characters\n"
988e1051a39Sopenharmony_ci                           if length $1 & 1;
989e1051a39Sopenharmony_ci                        die "FIPS key too long (64 bytes max)\n"
990e1051a39Sopenharmony_ci                           if length $1 > 64;
991e1051a39Sopenharmony_ci                        }
992e1051a39Sopenharmony_ci                elsif (/^--banner=(.*)$/)
993e1051a39Sopenharmony_ci                        {
994e1051a39Sopenharmony_ci                        $banner = $1 . "\n";
995e1051a39Sopenharmony_ci                        }
996e1051a39Sopenharmony_ci                elsif (/^--cross-compile-prefix=(.*)$/)
997e1051a39Sopenharmony_ci                        {
998e1051a39Sopenharmony_ci                        $user{CROSS_COMPILE}=$1;
999e1051a39Sopenharmony_ci                        }
1000e1051a39Sopenharmony_ci                elsif (/^--config=(.*)$/)
1001e1051a39Sopenharmony_ci                        {
1002e1051a39Sopenharmony_ci                        read_config $1;
1003e1051a39Sopenharmony_ci                        }
1004e1051a39Sopenharmony_ci                elsif (/^-l(.*)$/)
1005e1051a39Sopenharmony_ci                        {
1006e1051a39Sopenharmony_ci                        push @{$useradd{LDLIBS}}, $_;
1007e1051a39Sopenharmony_ci                        }
1008e1051a39Sopenharmony_ci                elsif (/^-framework$/)
1009e1051a39Sopenharmony_ci                        {
1010e1051a39Sopenharmony_ci                        push @{$useradd{LDLIBS}}, $_, shift(@argvcopy);
1011e1051a39Sopenharmony_ci                        }
1012e1051a39Sopenharmony_ci                elsif (/^-L(.*)$/ or /^-Wl,/)
1013e1051a39Sopenharmony_ci                        {
1014e1051a39Sopenharmony_ci                        push @{$useradd{LDFLAGS}}, $_;
1015e1051a39Sopenharmony_ci                        }
1016e1051a39Sopenharmony_ci                elsif (/^-rpath$/ or /^-R$/)
1017e1051a39Sopenharmony_ci                        # -rpath is the OSF1 rpath flag
1018e1051a39Sopenharmony_ci                        # -R is the old Solaris rpath flag
1019e1051a39Sopenharmony_ci                        {
1020e1051a39Sopenharmony_ci                        my $rpath = shift(@argvcopy) || "";
1021e1051a39Sopenharmony_ci                        $rpath .= " " if $rpath ne "";
1022e1051a39Sopenharmony_ci                        push @{$useradd{LDFLAGS}}, $_, $rpath;
1023e1051a39Sopenharmony_ci                        }
1024e1051a39Sopenharmony_ci                elsif (/^-static$/)
1025e1051a39Sopenharmony_ci                        {
1026e1051a39Sopenharmony_ci                        push @{$useradd{LDFLAGS}}, $_;
1027e1051a39Sopenharmony_ci                        }
1028e1051a39Sopenharmony_ci                elsif (m|^[-/]D(.*)$|)
1029e1051a39Sopenharmony_ci                        {
1030e1051a39Sopenharmony_ci                        push @{$useradd{CPPDEFINES}}, $1;
1031e1051a39Sopenharmony_ci                        }
1032e1051a39Sopenharmony_ci                elsif (m|^[-/]I(.*)$|)
1033e1051a39Sopenharmony_ci                        {
1034e1051a39Sopenharmony_ci                        push @{$useradd{CPPINCLUDES}}, $1;
1035e1051a39Sopenharmony_ci                        }
1036e1051a39Sopenharmony_ci                elsif (/^-Wp,$/)
1037e1051a39Sopenharmony_ci                        {
1038e1051a39Sopenharmony_ci                        push @{$useradd{CPPFLAGS}}, $1;
1039e1051a39Sopenharmony_ci                        }
1040e1051a39Sopenharmony_ci                else    # common if (/^[-+]/), just pass down...
1041e1051a39Sopenharmony_ci                        {
1042e1051a39Sopenharmony_ci                        # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1043e1051a39Sopenharmony_ci                        # This provides a simple way to pass options with arguments separated
1044e1051a39Sopenharmony_ci                        # by spaces without quoting (e.g. -opt%20arg translates to -opt arg).
1045e1051a39Sopenharmony_ci                        $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1046e1051a39Sopenharmony_ci                        push @{$useradd{CFLAGS}}, $_;
1047e1051a39Sopenharmony_ci                        push @{$useradd{CXXFLAGS}}, $_;
1048e1051a39Sopenharmony_ci                        }
1049e1051a39Sopenharmony_ci                }
1050e1051a39Sopenharmony_ci        elsif (m|^/|)
1051e1051a39Sopenharmony_ci                {
1052e1051a39Sopenharmony_ci                # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1053e1051a39Sopenharmony_ci                # This provides a simple way to pass options with arguments separated
1054e1051a39Sopenharmony_ci                # by spaces without quoting (e.g. /opt%20arg translates to /opt arg).
1055e1051a39Sopenharmony_ci                $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1056e1051a39Sopenharmony_ci                push @{$useradd{CFLAGS}}, $_;
1057e1051a39Sopenharmony_ci                push @{$useradd{CXXFLAGS}}, $_;
1058e1051a39Sopenharmony_ci                }
1059e1051a39Sopenharmony_ci        else
1060e1051a39Sopenharmony_ci                {
1061e1051a39Sopenharmony_ci                die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
1062e1051a39Sopenharmony_ci                $target=$_;
1063e1051a39Sopenharmony_ci                }
1064e1051a39Sopenharmony_ci        unless ($_ eq $target || /^no-/ || /^disable-/)
1065e1051a39Sopenharmony_ci                {
1066e1051a39Sopenharmony_ci                # "no-..." follows later after implied deactivations
1067e1051a39Sopenharmony_ci                # have been derived.  (Don't take this too seriously,
1068e1051a39Sopenharmony_ci                # we really only write OPTIONS to the Makefile out of
1069e1051a39Sopenharmony_ci                # nostalgia.)
1070e1051a39Sopenharmony_ci
1071e1051a39Sopenharmony_ci                if ($config{options} eq "")
1072e1051a39Sopenharmony_ci                        { $config{options} = $_; }
1073e1051a39Sopenharmony_ci                else
1074e1051a39Sopenharmony_ci                        { $config{options} .= " ".$_; }
1075e1051a39Sopenharmony_ci                }
1076e1051a39Sopenharmony_ci        }
1077e1051a39Sopenharmony_ci
1078e1051a39Sopenharmony_ciif (keys %deprecated_options)
1079e1051a39Sopenharmony_ci        {
1080e1051a39Sopenharmony_ci        warn "***** Deprecated options: ",
1081e1051a39Sopenharmony_ci                join(", ", keys %deprecated_options), "\n";
1082e1051a39Sopenharmony_ci        }
1083e1051a39Sopenharmony_ciif (keys %unsupported_options)
1084e1051a39Sopenharmony_ci        {
1085e1051a39Sopenharmony_ci        die "***** Unsupported options: ",
1086e1051a39Sopenharmony_ci                join(", ", keys %unsupported_options), "\n";
1087e1051a39Sopenharmony_ci        }
1088e1051a39Sopenharmony_ci
1089e1051a39Sopenharmony_ci# If any %useradd entry has been set, we must check that the "make
1090e1051a39Sopenharmony_ci# variables" haven't been set.  We start by checking of any %useradd entry
1091e1051a39Sopenharmony_ci# is set.
1092e1051a39Sopenharmony_ciif (grep { scalar @$_ > 0 } values %useradd) {
1093e1051a39Sopenharmony_ci    # Hash of env / make variables names.  The possible values are:
1094e1051a39Sopenharmony_ci    # 1 - "make vars"
1095e1051a39Sopenharmony_ci    # 2 - %useradd entry set
1096e1051a39Sopenharmony_ci    # 3 - both set
1097e1051a39Sopenharmony_ci    my %detected_vars =
1098e1051a39Sopenharmony_ci        map { my $v = 0;
1099e1051a39Sopenharmony_ci              $v += 1 if $cmdvars{$_};
1100e1051a39Sopenharmony_ci              $v += 2 if @{$useradd{$_}};
1101e1051a39Sopenharmony_ci              $_ => $v }
1102e1051a39Sopenharmony_ci        keys %useradd;
1103e1051a39Sopenharmony_ci
1104e1051a39Sopenharmony_ci    # If any of the corresponding "make variables" is set, we error
1105e1051a39Sopenharmony_ci    if (grep { $_ & 1 } values %detected_vars) {
1106e1051a39Sopenharmony_ci        my $names = join(', ', grep { $detected_vars{$_} > 0 }
1107e1051a39Sopenharmony_ci                               sort keys %detected_vars);
1108e1051a39Sopenharmony_ci        die <<"_____";
1109e1051a39Sopenharmony_ci***** Mixing make variables and additional compiler/linker flags as
1110e1051a39Sopenharmony_ci***** configure command line option is not permitted.
1111e1051a39Sopenharmony_ci***** Affected make variables: $names
1112e1051a39Sopenharmony_ci_____
1113e1051a39Sopenharmony_ci    }
1114e1051a39Sopenharmony_ci}
1115e1051a39Sopenharmony_ci
1116e1051a39Sopenharmony_ci# Check through all supported command line variables to see if any of them
1117e1051a39Sopenharmony_ci# were set, and canonicalise the values we got.  If no compiler or linker
1118e1051a39Sopenharmony_ci# flag or anything else that affects %useradd was set, we also check the
1119e1051a39Sopenharmony_ci# environment for values.
1120e1051a39Sopenharmony_cimy $anyuseradd =
1121e1051a39Sopenharmony_ci    grep { defined $_ && (ref $_ ne 'ARRAY' || @$_) } values %useradd;
1122e1051a39Sopenharmony_ciforeach (keys %user) {
1123e1051a39Sopenharmony_ci    my $value = $cmdvars{$_};
1124e1051a39Sopenharmony_ci    $value //= env($_) unless $anyuseradd;
1125e1051a39Sopenharmony_ci    $value //=
1126e1051a39Sopenharmony_ci        defined $user_synonyms{$_} ? $cmdvars{$user_synonyms{$_}} : undef;
1127e1051a39Sopenharmony_ci    $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef
1128e1051a39Sopenharmony_ci        unless $anyuseradd;
1129e1051a39Sopenharmony_ci
1130e1051a39Sopenharmony_ci    if (defined $value) {
1131e1051a39Sopenharmony_ci        if (ref $user{$_} eq 'ARRAY') {
1132e1051a39Sopenharmony_ci            if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') {
1133e1051a39Sopenharmony_ci                $user{$_} = [ split /$list_separator_re/, $value ];
1134e1051a39Sopenharmony_ci            } else {
1135e1051a39Sopenharmony_ci                $user{$_} = [ $value ];
1136e1051a39Sopenharmony_ci            }
1137e1051a39Sopenharmony_ci        } elsif (!defined $user{$_}) {
1138e1051a39Sopenharmony_ci            $user{$_} = $value;
1139e1051a39Sopenharmony_ci        }
1140e1051a39Sopenharmony_ci    }
1141e1051a39Sopenharmony_ci}
1142e1051a39Sopenharmony_ci
1143e1051a39Sopenharmony_ciif (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ())
1144e1051a39Sopenharmony_ci    && !$disabled{shared}
1145e1051a39Sopenharmony_ci    && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
1146e1051a39Sopenharmony_ci    die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
1147e1051a39Sopenharmony_ci        "***** any of asan, msan or ubsan\n";
1148e1051a39Sopenharmony_ci}
1149e1051a39Sopenharmony_ci
1150e1051a39Sopenharmony_ci# If no target was given, try guessing.
1151e1051a39Sopenharmony_ciunless ($target) {
1152e1051a39Sopenharmony_ci    my %system_config = OpenSSL::config::get_platform(%guess_opts, %user);
1153e1051a39Sopenharmony_ci
1154e1051a39Sopenharmony_ci    # The $system_config{disable} is used to populate %disabled with
1155e1051a39Sopenharmony_ci    # entries that aren't already there.
1156e1051a39Sopenharmony_ci    foreach ( @{$system_config{disable} // []} ) {
1157e1051a39Sopenharmony_ci        $disabled{$_} = 'system' unless defined $disabled{$_};
1158e1051a39Sopenharmony_ci    }
1159e1051a39Sopenharmony_ci    delete $system_config{disable};
1160e1051a39Sopenharmony_ci
1161e1051a39Sopenharmony_ci    # Override config entries with stuff from the guesser.
1162e1051a39Sopenharmony_ci    # It's assumed that this really is nothing new.
1163e1051a39Sopenharmony_ci    %config = ( %config, %system_config );
1164e1051a39Sopenharmony_ci    $target = $system_config{target};
1165e1051a39Sopenharmony_ci}
1166e1051a39Sopenharmony_ci
1167e1051a39Sopenharmony_cisub disable {
1168e1051a39Sopenharmony_ci    my $disable_type = shift;
1169e1051a39Sopenharmony_ci
1170e1051a39Sopenharmony_ci    for (@_) {
1171e1051a39Sopenharmony_ci        $disabled{$_} = $disable_type;
1172e1051a39Sopenharmony_ci    }
1173e1051a39Sopenharmony_ci
1174e1051a39Sopenharmony_ci    my @tocheckfor = (@_ ? @_ : keys %disabled);
1175e1051a39Sopenharmony_ci    while (@tocheckfor) {
1176e1051a39Sopenharmony_ci        my %new_tocheckfor = ();
1177e1051a39Sopenharmony_ci        my @cascade_copy = (@disable_cascades);
1178e1051a39Sopenharmony_ci        while (@cascade_copy) {
1179e1051a39Sopenharmony_ci            my ($test, $descendents) =
1180e1051a39Sopenharmony_ci                (shift @cascade_copy, shift @cascade_copy);
1181e1051a39Sopenharmony_ci            if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
1182e1051a39Sopenharmony_ci                foreach (grep { !defined($disabled{$_}) } @$descendents) {
1183e1051a39Sopenharmony_ci                    $new_tocheckfor{$_} = 1; $disabled{$_} = "cascade";
1184e1051a39Sopenharmony_ci                }
1185e1051a39Sopenharmony_ci            }
1186e1051a39Sopenharmony_ci        }
1187e1051a39Sopenharmony_ci        @tocheckfor = (keys %new_tocheckfor);
1188e1051a39Sopenharmony_ci    }
1189e1051a39Sopenharmony_ci}
1190e1051a39Sopenharmony_cidisable();                     # First cascade run
1191e1051a39Sopenharmony_ci
1192e1051a39Sopenharmony_ciour $die = sub { die @_; };
1193e1051a39Sopenharmony_ciif ($target eq "TABLE") {
1194e1051a39Sopenharmony_ci    local $die = sub { warn @_; };
1195e1051a39Sopenharmony_ci    foreach (sort keys %table) {
1196e1051a39Sopenharmony_ci        print_table_entry($_, "TABLE");
1197e1051a39Sopenharmony_ci    }
1198e1051a39Sopenharmony_ci    exit 0;
1199e1051a39Sopenharmony_ci}
1200e1051a39Sopenharmony_ci
1201e1051a39Sopenharmony_ciif ($target eq "LIST") {
1202e1051a39Sopenharmony_ci    foreach (sort keys %table) {
1203e1051a39Sopenharmony_ci        print $_,"\n" unless $table{$_}->{template};
1204e1051a39Sopenharmony_ci    }
1205e1051a39Sopenharmony_ci    exit 0;
1206e1051a39Sopenharmony_ci}
1207e1051a39Sopenharmony_ci
1208e1051a39Sopenharmony_ciif ($target eq "HASH") {
1209e1051a39Sopenharmony_ci    local $die = sub { warn @_; };
1210e1051a39Sopenharmony_ci    print "%table = (\n";
1211e1051a39Sopenharmony_ci    foreach (sort keys %table) {
1212e1051a39Sopenharmony_ci        print_table_entry($_, "HASH");
1213e1051a39Sopenharmony_ci    }
1214e1051a39Sopenharmony_ci    exit 0;
1215e1051a39Sopenharmony_ci}
1216e1051a39Sopenharmony_ci
1217e1051a39Sopenharmony_ciprint "Configuring OpenSSL version $config{full_version} ";
1218e1051a39Sopenharmony_ciprint "for target $target\n";
1219e1051a39Sopenharmony_ci
1220e1051a39Sopenharmony_ciif (scalar(@seed_sources) == 0) {
1221e1051a39Sopenharmony_ci    print "Using os-specific seed configuration\n";
1222e1051a39Sopenharmony_ci    push @seed_sources, 'os';
1223e1051a39Sopenharmony_ci}
1224e1051a39Sopenharmony_ciif (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) {
1225e1051a39Sopenharmony_ci    delete $disabled{'egd'};
1226e1051a39Sopenharmony_ci}
1227e1051a39Sopenharmony_ciif (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
1228e1051a39Sopenharmony_ci    die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
1229e1051a39Sopenharmony_ci    warn <<_____ if scalar(@seed_sources) == 1;
1230e1051a39Sopenharmony_ci
1231e1051a39Sopenharmony_ci============================== WARNING ===============================
1232e1051a39Sopenharmony_ciYou have selected the --with-rand-seed=none option, which effectively
1233e1051a39Sopenharmony_cidisables automatic reseeding of the OpenSSL random generator.
1234e1051a39Sopenharmony_ciAll operations depending on the random generator such as creating keys
1235e1051a39Sopenharmony_ciwill not work unless the random generator is seeded manually by the
1236e1051a39Sopenharmony_ciapplication.
1237e1051a39Sopenharmony_ci
1238e1051a39Sopenharmony_ciPlease read the 'Note on random number generation' section in the
1239e1051a39Sopenharmony_ciINSTALL.md instructions and the RAND_DRBG(7) manual page for more
1240e1051a39Sopenharmony_cidetails.
1241e1051a39Sopenharmony_ci============================== WARNING ===============================
1242e1051a39Sopenharmony_ci
1243e1051a39Sopenharmony_ci_____
1244e1051a39Sopenharmony_ci}
1245e1051a39Sopenharmony_cipush @{$config{openssl_feature_defines}},
1246e1051a39Sopenharmony_ci     map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
1247e1051a39Sopenharmony_ci        @seed_sources;
1248e1051a39Sopenharmony_ci
1249e1051a39Sopenharmony_ci# Backward compatibility?
1250e1051a39Sopenharmony_ciif ($target =~ m/^CygWin32(-.*)$/) {
1251e1051a39Sopenharmony_ci    $target = "Cygwin".$1;
1252e1051a39Sopenharmony_ci}
1253e1051a39Sopenharmony_ci
1254e1051a39Sopenharmony_ci# Support for legacy targets having a name starting with 'debug-'
1255e1051a39Sopenharmony_cimy ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
1256e1051a39Sopenharmony_ciif ($d) {
1257e1051a39Sopenharmony_ci    $config{build_type} = "debug";
1258e1051a39Sopenharmony_ci
1259e1051a39Sopenharmony_ci    # If we do not find debug-foo in the table, the target is set to foo.
1260e1051a39Sopenharmony_ci    if (!$table{$target}) {
1261e1051a39Sopenharmony_ci        $target = $t;
1262e1051a39Sopenharmony_ci    }
1263e1051a39Sopenharmony_ci}
1264e1051a39Sopenharmony_ci
1265e1051a39Sopenharmony_ciif ($target) {
1266e1051a39Sopenharmony_ci    # It's possible that we have different config targets for specific
1267e1051a39Sopenharmony_ci    # toolchains, so we try to detect them, and go for the plain config
1268e1051a39Sopenharmony_ci    # target if not.
1269e1051a39Sopenharmony_ci    my $found;
1270e1051a39Sopenharmony_ci    foreach ( ( "$target-$user{CC}", "$target", undef ) ) {
1271e1051a39Sopenharmony_ci        $found=$_ if $table{$_} && !$table{$_}->{template};
1272e1051a39Sopenharmony_ci        last if $found;
1273e1051a39Sopenharmony_ci    }
1274e1051a39Sopenharmony_ci    $target = $found;
1275e1051a39Sopenharmony_ci} else {
1276e1051a39Sopenharmony_ci    # If we don't have a config target now, we try the C compiler as we
1277e1051a39Sopenharmony_ci    # fallback
1278e1051a39Sopenharmony_ci    my $cc = $user{CC} // 'cc';
1279e1051a39Sopenharmony_ci    $target = $cc if $table{$cc} && !$table{$cc}->{template};
1280e1051a39Sopenharmony_ci}
1281e1051a39Sopenharmony_ci
1282e1051a39Sopenharmony_ci&usage unless $target;
1283e1051a39Sopenharmony_ci
1284e1051a39Sopenharmony_ciexit 0 if $dryrun;              # From older 'config'
1285e1051a39Sopenharmony_ci
1286e1051a39Sopenharmony_ci$config{target} = $target;
1287e1051a39Sopenharmony_cimy %target = resolve_config($target);
1288e1051a39Sopenharmony_ci
1289e1051a39Sopenharmony_ciforeach (keys %target_attr_translate) {
1290e1051a39Sopenharmony_ci    $target{$target_attr_translate{$_}} = $target{$_}
1291e1051a39Sopenharmony_ci        if $target{$_};
1292e1051a39Sopenharmony_ci    delete $target{$_};
1293e1051a39Sopenharmony_ci}
1294e1051a39Sopenharmony_ci
1295e1051a39Sopenharmony_ci%target = ( %{$table{DEFAULTS}}, %target );
1296e1051a39Sopenharmony_ci
1297e1051a39Sopenharmony_cimy %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
1298e1051a39Sopenharmony_ci$config{conf_files} = [ sort keys %conf_files ];
1299e1051a39Sopenharmony_ci
1300e1051a39Sopenharmony_ci# Using sub disable within these loops may prove fragile, so we run
1301e1051a39Sopenharmony_ci# a cascade afterwards
1302e1051a39Sopenharmony_ciforeach my $feature (@{$target{disable}}) {
1303e1051a39Sopenharmony_ci    if (exists $deprecated_disablables{$feature}) {
1304e1051a39Sopenharmony_ci        warn "***** config $target disables deprecated feature $feature\n";
1305e1051a39Sopenharmony_ci    } elsif (!grep { $feature eq $_ } @disablables) {
1306e1051a39Sopenharmony_ci        die "***** config $target disables unknown feature $feature\n";
1307e1051a39Sopenharmony_ci    }
1308e1051a39Sopenharmony_ci    $disabled{$feature} = 'config';
1309e1051a39Sopenharmony_ci}
1310e1051a39Sopenharmony_ciforeach my $feature (@{$target{enable}}) {
1311e1051a39Sopenharmony_ci    if ("default" eq ($disabled{$feature} // "")) {
1312e1051a39Sopenharmony_ci        if (exists $deprecated_disablables{$feature}) {
1313e1051a39Sopenharmony_ci            warn "***** config $target enables deprecated feature $feature\n";
1314e1051a39Sopenharmony_ci        } elsif (!grep { $feature eq $_ } @disablables) {
1315e1051a39Sopenharmony_ci            die "***** config $target enables unknown feature $feature\n";
1316e1051a39Sopenharmony_ci        }
1317e1051a39Sopenharmony_ci        delete $disabled{$feature};
1318e1051a39Sopenharmony_ci    }
1319e1051a39Sopenharmony_ci}
1320e1051a39Sopenharmony_ci
1321e1051a39Sopenharmony_ci# If uplink_arch isn't defined, disable uplink
1322e1051a39Sopenharmony_ci$disabled{uplink} = 'no uplink_arch' unless (defined $target{uplink_arch});
1323e1051a39Sopenharmony_ci# If asm_arch isn't defined, disable asm
1324e1051a39Sopenharmony_ci$disabled{asm} = 'no asm_arch' unless (defined $target{asm_arch});
1325e1051a39Sopenharmony_ci
1326e1051a39Sopenharmony_cidisable();                      # Run a cascade now
1327e1051a39Sopenharmony_ci
1328e1051a39Sopenharmony_ci$target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX};
1329e1051a39Sopenharmony_ci$target{cxxflags}//=$target{cflags} if $target{CXX};
1330e1051a39Sopenharmony_ci$target{exe_extension}=".exe" if ($config{target} eq "DJGPP");
1331e1051a39Sopenharmony_ci$target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
1332e1051a39Sopenharmony_ci
1333e1051a39Sopenharmony_ci# Fill %config with values from %user, and in case those are undefined or
1334e1051a39Sopenharmony_ci# empty, use values from %target (acting as a default).
1335e1051a39Sopenharmony_ciforeach (keys %user) {
1336e1051a39Sopenharmony_ci    my $ref_type = ref $user{$_};
1337e1051a39Sopenharmony_ci
1338e1051a39Sopenharmony_ci    # Temporary function.  Takes an intended ref type (empty string or "ARRAY")
1339e1051a39Sopenharmony_ci    # and a value that's to be coerced into that type.
1340e1051a39Sopenharmony_ci    my $mkvalue = sub {
1341e1051a39Sopenharmony_ci        my $type = shift;
1342e1051a39Sopenharmony_ci        my $value = shift;
1343e1051a39Sopenharmony_ci        my $undef_p = shift;
1344e1051a39Sopenharmony_ci
1345e1051a39Sopenharmony_ci        die "Too many arguments for \$mkvalue" if @_;
1346e1051a39Sopenharmony_ci
1347e1051a39Sopenharmony_ci        while (ref $value eq 'CODE') {
1348e1051a39Sopenharmony_ci            $value = $value->();
1349e1051a39Sopenharmony_ci        }
1350e1051a39Sopenharmony_ci
1351e1051a39Sopenharmony_ci        if ($type eq 'ARRAY') {
1352e1051a39Sopenharmony_ci            return undef unless defined $value;
1353e1051a39Sopenharmony_ci            return undef if ref $value ne 'ARRAY' && !$value;
1354e1051a39Sopenharmony_ci            return undef if ref $value eq 'ARRAY' && !@$value;
1355e1051a39Sopenharmony_ci            return [ $value ] unless ref $value eq 'ARRAY';
1356e1051a39Sopenharmony_ci        }
1357e1051a39Sopenharmony_ci        return undef unless $value;
1358e1051a39Sopenharmony_ci        return $value;
1359e1051a39Sopenharmony_ci    };
1360e1051a39Sopenharmony_ci
1361e1051a39Sopenharmony_ci    $config{$_} =
1362e1051a39Sopenharmony_ci        $mkvalue->($ref_type, $user{$_})
1363e1051a39Sopenharmony_ci        || $mkvalue->($ref_type, $target{$_});
1364e1051a39Sopenharmony_ci    delete $config{$_} unless defined $config{$_};
1365e1051a39Sopenharmony_ci}
1366e1051a39Sopenharmony_ci
1367e1051a39Sopenharmony_ci# Finish up %config by appending things the user gave us on the command line
1368e1051a39Sopenharmony_ci# apart from "make variables"
1369e1051a39Sopenharmony_ciforeach (keys %useradd) {
1370e1051a39Sopenharmony_ci    # The must all be lists, so we assert that here
1371e1051a39Sopenharmony_ci    die "internal error: \$useradd{$_} isn't an ARRAY\n"
1372e1051a39Sopenharmony_ci        unless ref $useradd{$_} eq 'ARRAY';
1373e1051a39Sopenharmony_ci
1374e1051a39Sopenharmony_ci    if (defined $config{$_}) {
1375e1051a39Sopenharmony_ci        push @{$config{$_}}, @{$useradd{$_}};
1376e1051a39Sopenharmony_ci    } else {
1377e1051a39Sopenharmony_ci        $config{$_} = [ @{$useradd{$_}} ];
1378e1051a39Sopenharmony_ci    }
1379e1051a39Sopenharmony_ci}
1380e1051a39Sopenharmony_ci# At this point, we can forget everything about %user and %useradd,
1381e1051a39Sopenharmony_ci# because it's now all been merged into the corresponding $config entry
1382e1051a39Sopenharmony_ci
1383e1051a39Sopenharmony_ciif (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) {
1384e1051a39Sopenharmony_ci    disable('static', 'pic', 'threads');
1385e1051a39Sopenharmony_ci}
1386e1051a39Sopenharmony_ci
1387e1051a39Sopenharmony_ci# Allow overriding the build file name
1388e1051a39Sopenharmony_ci$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
1389e1051a39Sopenharmony_ci
1390e1051a39Sopenharmony_ci# Make sure build_scheme is consistent.
1391e1051a39Sopenharmony_ci$target{build_scheme} = [ $target{build_scheme} ]
1392e1051a39Sopenharmony_ci    if ref($target{build_scheme}) ne "ARRAY";
1393e1051a39Sopenharmony_ci
1394e1051a39Sopenharmony_cimy ($builder, $builder_platform, @builder_opts) =
1395e1051a39Sopenharmony_ci    @{$target{build_scheme}};
1396e1051a39Sopenharmony_ci
1397e1051a39Sopenharmony_ciforeach my $checker (($builder_platform."-".$config{build_file}."-checker.pm",
1398e1051a39Sopenharmony_ci                      $builder_platform."-checker.pm")) {
1399e1051a39Sopenharmony_ci    my $checker_path = catfile($srcdir, "Configurations", $checker);
1400e1051a39Sopenharmony_ci    if (-f $checker_path) {
1401e1051a39Sopenharmony_ci        my $fn = $ENV{CONFIGURE_CHECKER_WARN}
1402e1051a39Sopenharmony_ci            ? sub { warn $@; } : sub { die $@; };
1403e1051a39Sopenharmony_ci        if (! do $checker_path) {
1404e1051a39Sopenharmony_ci            if ($@) {
1405e1051a39Sopenharmony_ci                $fn->($@);
1406e1051a39Sopenharmony_ci            } elsif ($!) {
1407e1051a39Sopenharmony_ci                $fn->($!);
1408e1051a39Sopenharmony_ci            } else {
1409e1051a39Sopenharmony_ci                $fn->("The detected tools didn't match the platform\n");
1410e1051a39Sopenharmony_ci            }
1411e1051a39Sopenharmony_ci        }
1412e1051a39Sopenharmony_ci        last;
1413e1051a39Sopenharmony_ci    }
1414e1051a39Sopenharmony_ci}
1415e1051a39Sopenharmony_ci
1416e1051a39Sopenharmony_cipush @{$config{defines}}, "NDEBUG"    if $config{build_type} eq "release";
1417e1051a39Sopenharmony_ci
1418e1051a39Sopenharmony_ciif ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m)
1419e1051a39Sopenharmony_ci        {
1420e1051a39Sopenharmony_ci        push @{$config{cflags}}, "-mno-cygwin";
1421e1051a39Sopenharmony_ci        push @{$config{cxxflags}}, "-mno-cygwin" if $config{CXX};
1422e1051a39Sopenharmony_ci        push @{$config{shared_ldflag}}, "-mno-cygwin";
1423e1051a39Sopenharmony_ci        }
1424e1051a39Sopenharmony_ci
1425e1051a39Sopenharmony_ciif ($target =~ /linux.*-mips/ && !$disabled{asm}
1426e1051a39Sopenharmony_ci        && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) {
1427e1051a39Sopenharmony_ci        # minimally required architecture flags for assembly modules
1428e1051a39Sopenharmony_ci        my $value;
1429e1051a39Sopenharmony_ci        $value = '-mips2' if ($target =~ /mips32/);
1430e1051a39Sopenharmony_ci        $value = '-mips3' if ($target =~ /mips64/);
1431e1051a39Sopenharmony_ci        unshift @{$config{cflags}}, $value;
1432e1051a39Sopenharmony_ci        unshift @{$config{cxxflags}}, $value if $config{CXX};
1433e1051a39Sopenharmony_ci}
1434e1051a39Sopenharmony_ci
1435e1051a39Sopenharmony_ci# If threads aren't disabled, check how possible they are
1436e1051a39Sopenharmony_ciunless ($disabled{threads}) {
1437e1051a39Sopenharmony_ci    if ($auto_threads) {
1438e1051a39Sopenharmony_ci        # Enabled by default, disable it forcibly if unavailable
1439e1051a39Sopenharmony_ci        if ($target{thread_scheme} eq "(unknown)") {
1440e1051a39Sopenharmony_ci            disable("unavailable", 'threads');
1441e1051a39Sopenharmony_ci        }
1442e1051a39Sopenharmony_ci    } else {
1443e1051a39Sopenharmony_ci        # The user chose to enable threads explicitly, let's see
1444e1051a39Sopenharmony_ci        # if there's a chance that's possible
1445e1051a39Sopenharmony_ci        if ($target{thread_scheme} eq "(unknown)") {
1446e1051a39Sopenharmony_ci            # If the user asked for "threads" and we don't have internal
1447e1051a39Sopenharmony_ci            # knowledge how to do it, [s]he is expected to provide any
1448e1051a39Sopenharmony_ci            # system-dependent compiler options that are necessary.  We
1449e1051a39Sopenharmony_ci            # can't truly check that the given options are correct, but
1450e1051a39Sopenharmony_ci            # we expect the user to know what [s]He is doing.
1451e1051a39Sopenharmony_ci            if (!@{$config{CFLAGS}} && !@{$config{CPPDEFINES}}) {
1452e1051a39Sopenharmony_ci                die "You asked for multi-threading support, but didn't\n"
1453e1051a39Sopenharmony_ci                    ,"provide any system-specific compiler options\n";
1454e1051a39Sopenharmony_ci            }
1455e1051a39Sopenharmony_ci        }
1456e1051a39Sopenharmony_ci    }
1457e1051a39Sopenharmony_ci}
1458e1051a39Sopenharmony_ci
1459e1051a39Sopenharmony_ci# Find out if clang's sanitizers have been enabled with -fsanitize
1460e1051a39Sopenharmony_ci# flags and ensure that the corresponding %disabled elements area
1461e1051a39Sopenharmony_ci# removed to reflect that the sanitizers are indeed enabled.
1462e1051a39Sopenharmony_cimy %detected_sanitizers = ();
1463e1051a39Sopenharmony_ciforeach (grep /^-fsanitize=/, @{$config{CFLAGS} || []}) {
1464e1051a39Sopenharmony_ci    (my $checks = $_) =~ s/^-fsanitize=//;
1465e1051a39Sopenharmony_ci    foreach (split /,/, $checks) {
1466e1051a39Sopenharmony_ci        my $d = { address       => 'asan',
1467e1051a39Sopenharmony_ci                  undefined     => 'ubsan',
1468e1051a39Sopenharmony_ci                  memory        => 'msan' } -> {$_};
1469e1051a39Sopenharmony_ci        next unless defined $d;
1470e1051a39Sopenharmony_ci
1471e1051a39Sopenharmony_ci        $detected_sanitizers{$d} = 1;
1472e1051a39Sopenharmony_ci        if (defined $disabled{$d}) {
1473e1051a39Sopenharmony_ci            die "***** Conflict between disabling $d and enabling $_ sanitizer"
1474e1051a39Sopenharmony_ci                if $disabled{$d} ne "default";
1475e1051a39Sopenharmony_ci            delete $disabled{$d};
1476e1051a39Sopenharmony_ci        }
1477e1051a39Sopenharmony_ci    }
1478e1051a39Sopenharmony_ci}
1479e1051a39Sopenharmony_ci
1480e1051a39Sopenharmony_ci# If threads still aren't disabled, add a C macro to ensure the source
1481e1051a39Sopenharmony_ci# code knows about it.  Any other flag is taken care of by the configs.
1482e1051a39Sopenharmony_ciunless($disabled{threads}) {
1483e1051a39Sopenharmony_ci    push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
1484e1051a39Sopenharmony_ci}
1485e1051a39Sopenharmony_ci
1486e1051a39Sopenharmony_cimy $no_shared_warn=0;
1487e1051a39Sopenharmony_ciif (($target{shared_target} // '') eq "")
1488e1051a39Sopenharmony_ci        {
1489e1051a39Sopenharmony_ci        $no_shared_warn = 1
1490e1051a39Sopenharmony_ci            if (!$disabled{shared} || !$disabled{"dynamic-engine"});
1491e1051a39Sopenharmony_ci        disable('no-shared-target', 'pic');
1492e1051a39Sopenharmony_ci        }
1493e1051a39Sopenharmony_ci
1494e1051a39Sopenharmony_ciif ($disabled{"dynamic-engine"}) {
1495e1051a39Sopenharmony_ci        $config{dynamic_engines} = 0;
1496e1051a39Sopenharmony_ci} else {
1497e1051a39Sopenharmony_ci        $config{dynamic_engines} = 1;
1498e1051a39Sopenharmony_ci}
1499e1051a39Sopenharmony_ci
1500e1051a39Sopenharmony_ciunless ($disabled{asan} || defined $detected_sanitizers{asan}) {
1501e1051a39Sopenharmony_ci    push @{$config{cflags}}, "-fsanitize=address";
1502e1051a39Sopenharmony_ci}
1503e1051a39Sopenharmony_ci
1504e1051a39Sopenharmony_ciunless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) {
1505e1051a39Sopenharmony_ci    push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC";
1506e1051a39Sopenharmony_ci}
1507e1051a39Sopenharmony_ci
1508e1051a39Sopenharmony_ciunless ($disabled{msan} || defined $detected_sanitizers{msan}) {
1509e1051a39Sopenharmony_ci  push @{$config{cflags}}, "-fsanitize=memory";
1510e1051a39Sopenharmony_ci}
1511e1051a39Sopenharmony_ci
1512e1051a39Sopenharmony_ciunless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1513e1051a39Sopenharmony_ci        && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1514e1051a39Sopenharmony_ci    push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g";
1515e1051a39Sopenharmony_ci    push @{$config{cxxflags}}, "-fno-omit-frame-pointer", "-g" if $config{CXX};
1516e1051a39Sopenharmony_ci}
1517e1051a39Sopenharmony_ci#
1518e1051a39Sopenharmony_ci# Platform fix-ups
1519e1051a39Sopenharmony_ci#
1520e1051a39Sopenharmony_ci
1521e1051a39Sopenharmony_ci# This saves the build files from having to check
1522e1051a39Sopenharmony_ciif ($disabled{pic})
1523e1051a39Sopenharmony_ci        {
1524e1051a39Sopenharmony_ci        foreach (qw(shared_cflag shared_cxxflag shared_cppflag
1525e1051a39Sopenharmony_ci                    shared_defines shared_includes shared_ldflag
1526e1051a39Sopenharmony_ci                    module_cflags module_cxxflags module_cppflags
1527e1051a39Sopenharmony_ci                    module_defines module_includes module_lflags))
1528e1051a39Sopenharmony_ci                {
1529e1051a39Sopenharmony_ci                delete $config{$_};
1530e1051a39Sopenharmony_ci                $target{$_} = "";
1531e1051a39Sopenharmony_ci                }
1532e1051a39Sopenharmony_ci        }
1533e1051a39Sopenharmony_cielse
1534e1051a39Sopenharmony_ci        {
1535e1051a39Sopenharmony_ci        push @{$config{lib_defines}}, "OPENSSL_PIC";
1536e1051a39Sopenharmony_ci        }
1537e1051a39Sopenharmony_ci
1538e1051a39Sopenharmony_ciif ($target{sys_id} ne "")
1539e1051a39Sopenharmony_ci        {
1540e1051a39Sopenharmony_ci        push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1541e1051a39Sopenharmony_ci        }
1542e1051a39Sopenharmony_ci
1543e1051a39Sopenharmony_cimy %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC});
1544e1051a39Sopenharmony_cimy %predefined_CXX = $config{CXX}
1545e1051a39Sopenharmony_ci    ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX})
1546e1051a39Sopenharmony_ci    : ();
1547e1051a39Sopenharmony_ci
1548e1051a39Sopenharmony_ciunless ($disabled{asm}) {
1549e1051a39Sopenharmony_ci    # big endian systems can use ELFv2 ABI
1550e1051a39Sopenharmony_ci    if ($target eq "linux-ppc64") {
1551e1051a39Sopenharmony_ci        $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2);
1552e1051a39Sopenharmony_ci    }
1553e1051a39Sopenharmony_ci}
1554e1051a39Sopenharmony_ci
1555e1051a39Sopenharmony_ci# Check for makedepend capabilities.
1556e1051a39Sopenharmony_ciif (!$disabled{makedepend}) {
1557e1051a39Sopenharmony_ci    # If the attribute makedep_scheme is defined, then we assume that the
1558e1051a39Sopenharmony_ci    # config target and its associated build file are programmed to deal
1559e1051a39Sopenharmony_ci    # with it.
1560e1051a39Sopenharmony_ci    # If makedep_scheme is undefined, we go looking for GCC compatible
1561e1051a39Sopenharmony_ci    # dependency making, and if that's not available, we try to fall back
1562e1051a39Sopenharmony_ci    # on 'makedepend'.
1563e1051a39Sopenharmony_ci    if ($target{makedep_scheme}) {
1564e1051a39Sopenharmony_ci        $config{makedep_scheme} = $target{makedep_scheme};
1565e1051a39Sopenharmony_ci        # If the makedepcmd attribute is defined, copy it.  If not, the
1566e1051a39Sopenharmony_ci        # build files will have to fend for themselves.
1567e1051a39Sopenharmony_ci        $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd};
1568e1051a39Sopenharmony_ci    } elsif (($predefined_C{__GNUC__} // -1) >= 3
1569e1051a39Sopenharmony_ci             && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) {
1570e1051a39Sopenharmony_ci        # We know that GNU C version 3 and up as well as all clang
1571e1051a39Sopenharmony_ci        # versions support dependency generation, but Xcode did not
1572e1051a39Sopenharmony_ci        # handle $cc -M before clang support (but claims __GNUC__ = 3)
1573e1051a39Sopenharmony_ci        $config{makedep_scheme} = 'gcc';
1574e1051a39Sopenharmony_ci    } else {
1575e1051a39Sopenharmony_ci        # In all other cases, we look for 'makedepend', and set the
1576e1051a39Sopenharmony_ci        # makedep_scheme value if we found it.
1577e1051a39Sopenharmony_ci        $config{makedepcmd} = which('makedepend');
1578e1051a39Sopenharmony_ci        $config{makedep_scheme} = 'makedepend' if $config{makedepcmd};
1579e1051a39Sopenharmony_ci    }
1580e1051a39Sopenharmony_ci
1581e1051a39Sopenharmony_ci    # If no depend scheme is set, we disable makedepend
1582e1051a39Sopenharmony_ci    disable('unavailable', 'makedepend') unless $config{makedep_scheme};
1583e1051a39Sopenharmony_ci}
1584e1051a39Sopenharmony_ci
1585e1051a39Sopenharmony_ciif (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') {
1586e1051a39Sopenharmony_ci    # probe for -Wa,--noexecstack option...
1587e1051a39Sopenharmony_ci    if ($predefined_C{__clang__}) {
1588e1051a39Sopenharmony_ci        # clang has builtin assembler, which doesn't recognize --help,
1589e1051a39Sopenharmony_ci        # but it apparently recognizes the option in question on all
1590e1051a39Sopenharmony_ci        # supported platforms even when it's meaningless. In other words
1591e1051a39Sopenharmony_ci        # probe would fail, but probed option always accepted...
1592e1051a39Sopenharmony_ci        push @{$config{cflags}}, "-Wa,--noexecstack", "-Qunused-arguments";
1593e1051a39Sopenharmony_ci    } else {
1594e1051a39Sopenharmony_ci        my $cc = $config{CROSS_COMPILE}.$config{CC};
1595e1051a39Sopenharmony_ci        open(PIPE, "$cc -Wa,--help -c -o null.$$.o -x assembler /dev/null 2>&1 |");
1596e1051a39Sopenharmony_ci        while(<PIPE>) {
1597e1051a39Sopenharmony_ci            if (m/--noexecstack/) {
1598e1051a39Sopenharmony_ci                push @{$config{cflags}}, "-Wa,--noexecstack";
1599e1051a39Sopenharmony_ci                last;
1600e1051a39Sopenharmony_ci            }
1601e1051a39Sopenharmony_ci        }
1602e1051a39Sopenharmony_ci        close(PIPE);
1603e1051a39Sopenharmony_ci        unlink("null.$$.o");
1604e1051a39Sopenharmony_ci    }
1605e1051a39Sopenharmony_ci}
1606e1051a39Sopenharmony_ci
1607e1051a39Sopenharmony_ci# Deal with bn_ops ###################################################
1608e1051a39Sopenharmony_ci
1609e1051a39Sopenharmony_ci$config{bn_ll}                  =0;
1610e1051a39Sopenharmony_cimy $def_int="unsigned int";
1611e1051a39Sopenharmony_ci$config{rc4_int}                =$def_int;
1612e1051a39Sopenharmony_ci($config{b64l},$config{b64},$config{b32})=(0,0,1);
1613e1051a39Sopenharmony_ci
1614e1051a39Sopenharmony_cimy $count = 0;
1615e1051a39Sopenharmony_ciforeach (sort split(/\s+/,$target{bn_ops})) {
1616e1051a39Sopenharmony_ci    $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1617e1051a39Sopenharmony_ci    $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1618e1051a39Sopenharmony_ci    $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1619e1051a39Sopenharmony_ci    ($config{b64l},$config{b64},$config{b32})
1620e1051a39Sopenharmony_ci        =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1621e1051a39Sopenharmony_ci    ($config{b64l},$config{b64},$config{b32})
1622e1051a39Sopenharmony_ci        =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1623e1051a39Sopenharmony_ci    ($config{b64l},$config{b64},$config{b32})
1624e1051a39Sopenharmony_ci        =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1625e1051a39Sopenharmony_ci}
1626e1051a39Sopenharmony_cidie "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1627e1051a39Sopenharmony_ci    if $count > 1;
1628e1051a39Sopenharmony_ci
1629e1051a39Sopenharmony_ci$config{api} = $config{major} * 10000 + $config{minor} * 100
1630e1051a39Sopenharmony_ci    unless $config{api};
1631e1051a39Sopenharmony_ciforeach (keys %$apitable) {
1632e1051a39Sopenharmony_ci    $disabled{"deprecated-$_"} = "deprecation"
1633e1051a39Sopenharmony_ci        if $disabled{deprecated} && $config{api} >= $apitable->{$_};
1634e1051a39Sopenharmony_ci}
1635e1051a39Sopenharmony_ci
1636e1051a39Sopenharmony_cidisable();                      # Run a cascade now
1637e1051a39Sopenharmony_ci
1638e1051a39Sopenharmony_ci# Hack cflags for better warnings (dev option) #######################
1639e1051a39Sopenharmony_ci
1640e1051a39Sopenharmony_ci# "Stringify" the C and C++ flags string.  This permits it to be made part of
1641e1051a39Sopenharmony_ci# a string and works as well on command lines.
1642e1051a39Sopenharmony_ci$config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1643e1051a39Sopenharmony_ci                        @{$config{cflags}} ];
1644e1051a39Sopenharmony_ci$config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1645e1051a39Sopenharmony_ci                          @{$config{cxxflags}} ] if $config{CXX};
1646e1051a39Sopenharmony_ci
1647e1051a39Sopenharmony_ci$config{openssl_api_defines} = [
1648e1051a39Sopenharmony_ci    "OPENSSL_CONFIGURED_API=".$config{api},
1649e1051a39Sopenharmony_ci];
1650e1051a39Sopenharmony_ci
1651e1051a39Sopenharmony_cimy @strict_warnings_collection=();
1652e1051a39Sopenharmony_ciif ($strict_warnings)
1653e1051a39Sopenharmony_ci        {
1654e1051a39Sopenharmony_ci        my $wopt;
1655e1051a39Sopenharmony_ci        my $gccver = $predefined_C{__GNUC__} // -1;
1656e1051a39Sopenharmony_ci
1657e1051a39Sopenharmony_ci        if ($gccver >= 4)
1658e1051a39Sopenharmony_ci                {
1659e1051a39Sopenharmony_ci                push @strict_warnings_collection, @gcc_devteam_warn;
1660e1051a39Sopenharmony_ci                push @strict_warnings_collection, @clang_devteam_warn
1661e1051a39Sopenharmony_ci                    if (defined($predefined_C{__clang__}));
1662e1051a39Sopenharmony_ci                }
1663e1051a39Sopenharmony_ci        elsif ($config{target} =~ /^VC-/)
1664e1051a39Sopenharmony_ci                {
1665e1051a39Sopenharmony_ci                push @strict_warnings_collection, @cl_devteam_warn;
1666e1051a39Sopenharmony_ci                }
1667e1051a39Sopenharmony_ci        else
1668e1051a39Sopenharmony_ci                {
1669e1051a39Sopenharmony_ci                warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC"
1670e1051a39Sopenharmony_ci                }
1671e1051a39Sopenharmony_ci        }
1672e1051a39Sopenharmony_ci
1673e1051a39Sopenharmony_ci$config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings'
1674e1051a39Sopenharmony_ci                              ? @strict_warnings_collection
1675e1051a39Sopenharmony_ci                              : ( $_ ) }
1676e1051a39Sopenharmony_ci                    @{$config{CFLAGS}} ];
1677e1051a39Sopenharmony_ci
1678e1051a39Sopenharmony_ciunless ($disabled{afalgeng}) {
1679e1051a39Sopenharmony_ci    $config{afalgeng}="";
1680e1051a39Sopenharmony_ci    if (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
1681e1051a39Sopenharmony_ci        my $minver = 4*10000 + 1*100 + 0;
1682e1051a39Sopenharmony_ci        if ($config{CROSS_COMPILE} eq "") {
1683e1051a39Sopenharmony_ci            my $verstr = `uname -r`;
1684e1051a39Sopenharmony_ci            my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1685e1051a39Sopenharmony_ci            ($mi2) = $mi2 =~ /(\d+)/;
1686e1051a39Sopenharmony_ci            my $ver = $ma*10000 + $mi1*100 + $mi2;
1687e1051a39Sopenharmony_ci            if ($ver < $minver) {
1688e1051a39Sopenharmony_ci                disable('too-old-kernel', 'afalgeng');
1689e1051a39Sopenharmony_ci            } else {
1690e1051a39Sopenharmony_ci                push @{$config{engdirs}}, "afalg";
1691e1051a39Sopenharmony_ci            }
1692e1051a39Sopenharmony_ci        } else {
1693e1051a39Sopenharmony_ci            disable('cross-compiling', 'afalgeng');
1694e1051a39Sopenharmony_ci        }
1695e1051a39Sopenharmony_ci    } else {
1696e1051a39Sopenharmony_ci        disable('not-linux', 'afalgeng');
1697e1051a39Sopenharmony_ci    }
1698e1051a39Sopenharmony_ci}
1699e1051a39Sopenharmony_ci
1700e1051a39Sopenharmony_ciunless ($disabled{devcryptoeng}) {
1701e1051a39Sopenharmony_ci    if ($target =~ m/^BSD/) {
1702e1051a39Sopenharmony_ci        my $maxver = 5*100 + 7;
1703e1051a39Sopenharmony_ci        my $sysstr = `uname -s`;
1704e1051a39Sopenharmony_ci        my $verstr = `uname -r`;
1705e1051a39Sopenharmony_ci        $sysstr =~ s|\R$||;
1706e1051a39Sopenharmony_ci        $verstr =~ s|\R$||;
1707e1051a39Sopenharmony_ci        my ($ma, $mi, @rest) = split m|\.|, $verstr;
1708e1051a39Sopenharmony_ci        my $ver = $ma*100 + $mi;
1709e1051a39Sopenharmony_ci        if ($sysstr eq 'OpenBSD' && $ver >= $maxver) {
1710e1051a39Sopenharmony_ci            disable('too-new-kernel', 'devcryptoeng');
1711e1051a39Sopenharmony_ci        }
1712e1051a39Sopenharmony_ci    }
1713e1051a39Sopenharmony_ci}
1714e1051a39Sopenharmony_ci
1715e1051a39Sopenharmony_ciunless ($disabled{ktls}) {
1716e1051a39Sopenharmony_ci    $config{ktls}="";
1717e1051a39Sopenharmony_ci    my $cc = $config{CROSS_COMPILE}.$config{CC};
1718e1051a39Sopenharmony_ci    if ($target =~ m/^linux/) {
1719e1051a39Sopenharmony_ci        system("printf '#include <sys/types.h>\n#include <linux/tls.h>' | $cc -E - >/dev/null 2>&1");
1720e1051a39Sopenharmony_ci        if ($? != 0) {
1721e1051a39Sopenharmony_ci            disable('too-old-kernel', 'ktls');
1722e1051a39Sopenharmony_ci        }
1723e1051a39Sopenharmony_ci    } elsif ($target =~ m/^BSD/) {
1724e1051a39Sopenharmony_ci        system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1");
1725e1051a39Sopenharmony_ci        if ($? != 0) {
1726e1051a39Sopenharmony_ci            disable('too-old-freebsd', 'ktls');
1727e1051a39Sopenharmony_ci        }
1728e1051a39Sopenharmony_ci    } else {
1729e1051a39Sopenharmony_ci        disable('not-linux-or-freebsd', 'ktls');
1730e1051a39Sopenharmony_ci    }
1731e1051a39Sopenharmony_ci}
1732e1051a39Sopenharmony_ci
1733e1051a39Sopenharmony_cipush @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
1734e1051a39Sopenharmony_ci
1735e1051a39Sopenharmony_ci# Get the extra flags used when building shared libraries and modules.  We
1736e1051a39Sopenharmony_ci# do this late because some of them depend on %disabled.
1737e1051a39Sopenharmony_ci
1738e1051a39Sopenharmony_ci# Make the flags to build DSOs the same as for shared libraries unless they
1739e1051a39Sopenharmony_ci# are already defined
1740e1051a39Sopenharmony_ci$target{module_cflags} = $target{shared_cflag} unless defined $target{module_cflags};
1741e1051a39Sopenharmony_ci$target{module_cxxflags} = $target{shared_cxxflag} unless defined $target{module_cxxflags};
1742e1051a39Sopenharmony_ci$target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_ldflags};
1743e1051a39Sopenharmony_ci{
1744e1051a39Sopenharmony_ci    my $shared_info_pl =
1745e1051a39Sopenharmony_ci        catfile(dirname($0), "Configurations", "shared-info.pl");
1746e1051a39Sopenharmony_ci    my %shared_info = read_eval_file($shared_info_pl);
1747e1051a39Sopenharmony_ci    push @{$target{_conf_fname_int}}, $shared_info_pl;
1748e1051a39Sopenharmony_ci    my $si = $target{shared_target};
1749e1051a39Sopenharmony_ci    while (ref $si ne "HASH") {
1750e1051a39Sopenharmony_ci        last if ! defined $si;
1751e1051a39Sopenharmony_ci        if (ref $si eq "CODE") {
1752e1051a39Sopenharmony_ci            $si = $si->();
1753e1051a39Sopenharmony_ci        } else {
1754e1051a39Sopenharmony_ci            $si = $shared_info{$si};
1755e1051a39Sopenharmony_ci        }
1756e1051a39Sopenharmony_ci    }
1757e1051a39Sopenharmony_ci
1758e1051a39Sopenharmony_ci    # Some of the 'shared_target' values don't have any entries in
1759e1051a39Sopenharmony_ci    # %shared_info.  That's perfectly fine, AS LONG AS the build file
1760e1051a39Sopenharmony_ci    # template knows how to handle this.  That is currently the case for
1761e1051a39Sopenharmony_ci    # Windows and VMS.
1762e1051a39Sopenharmony_ci    if (defined $si) {
1763e1051a39Sopenharmony_ci        # Just as above, copy certain shared_* attributes to the corresponding
1764e1051a39Sopenharmony_ci        # module_ attribute unless the latter is already defined
1765e1051a39Sopenharmony_ci        $si->{module_cflags} = $si->{shared_cflag} unless defined $si->{module_cflags};
1766e1051a39Sopenharmony_ci        $si->{module_cxxflags} = $si->{shared_cxxflag} unless defined $si->{module_cxxflags};
1767e1051a39Sopenharmony_ci        $si->{module_ldflags} = $si->{shared_ldflag} unless defined $si->{module_ldflags};
1768e1051a39Sopenharmony_ci        foreach (sort keys %$si) {
1769e1051a39Sopenharmony_ci            $target{$_} = defined $target{$_}
1770e1051a39Sopenharmony_ci                ? add($si->{$_})->($target{$_})
1771e1051a39Sopenharmony_ci                : $si->{$_};
1772e1051a39Sopenharmony_ci        }
1773e1051a39Sopenharmony_ci    }
1774e1051a39Sopenharmony_ci}
1775e1051a39Sopenharmony_ci
1776e1051a39Sopenharmony_ci# ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON
1777e1051a39Sopenharmony_ci
1778e1051a39Sopenharmony_ci######################################################################
1779e1051a39Sopenharmony_ci# Build up information for skipping certain directories depending on disabled
1780e1051a39Sopenharmony_ci# features, as well as setting up macros for disabled features.
1781e1051a39Sopenharmony_ci
1782e1051a39Sopenharmony_ci# This is a tentative database of directories to skip.  Some entries may not
1783e1051a39Sopenharmony_ci# correspond to anything real, but that's ok, they will simply be ignored.
1784e1051a39Sopenharmony_ci# The actual processing of these entries is done in the build.info lookup
1785e1051a39Sopenharmony_ci# loop further down.
1786e1051a39Sopenharmony_ci#
1787e1051a39Sopenharmony_ci# The key is a Unix formatted path in the source tree, the value is an index
1788e1051a39Sopenharmony_ci# into %disabled_info, so any existing path gets added to a corresponding
1789e1051a39Sopenharmony_ci# 'skipped' entry in there with the list of skipped directories.
1790e1051a39Sopenharmony_cimy %skipdir = ();
1791e1051a39Sopenharmony_cimy %disabled_info = ();         # For configdata.pm
1792e1051a39Sopenharmony_ciforeach my $what (sort keys %disabled) {
1793e1051a39Sopenharmony_ci    # There are deprecated disablables that translate to themselves.
1794e1051a39Sopenharmony_ci    # They cause disabling cascades, but should otherwise not regiter.
1795e1051a39Sopenharmony_ci    next if $deprecated_disablables{$what};
1796e1051a39Sopenharmony_ci    # The generated $disabled{"deprecated-x.y"} entries are special
1797e1051a39Sopenharmony_ci    # and treated properly elsewhere
1798e1051a39Sopenharmony_ci    next if $what =~ m|^deprecated-|;
1799e1051a39Sopenharmony_ci
1800e1051a39Sopenharmony_ci    $config{options} .= " no-$what";
1801e1051a39Sopenharmony_ci
1802e1051a39Sopenharmony_ci    if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
1803e1051a39Sopenharmony_ci                                'module', 'pic', 'dynamic-engine', 'makedepend',
1804e1051a39Sopenharmony_ci                                'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) {
1805e1051a39Sopenharmony_ci        (my $WHAT = uc $what) =~ s|-|_|g;
1806e1051a39Sopenharmony_ci        my $skipdir = $what;
1807e1051a39Sopenharmony_ci
1808e1051a39Sopenharmony_ci        # fix-up crypto/directory name(s)
1809e1051a39Sopenharmony_ci        $skipdir = "ripemd" if $what eq "rmd160";
1810e1051a39Sopenharmony_ci        $skipdir = "whrlpool" if $what eq "whirlpool";
1811e1051a39Sopenharmony_ci
1812e1051a39Sopenharmony_ci        my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT";
1813e1051a39Sopenharmony_ci        push @{$config{openssl_feature_defines}}, $macro;
1814e1051a39Sopenharmony_ci
1815e1051a39Sopenharmony_ci        $skipdir{engines} = $what if $what eq 'engine';
1816e1051a39Sopenharmony_ci        $skipdir{"crypto/$skipdir"} = $what
1817e1051a39Sopenharmony_ci            unless $what eq 'async' || $what eq 'err' || $what eq 'dso';
1818e1051a39Sopenharmony_ci    }
1819e1051a39Sopenharmony_ci}
1820e1051a39Sopenharmony_ci
1821e1051a39Sopenharmony_ciif ($disabled{"dynamic-engine"}) {
1822e1051a39Sopenharmony_ci    push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1823e1051a39Sopenharmony_ci} else {
1824e1051a39Sopenharmony_ci    push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE";
1825e1051a39Sopenharmony_ci}
1826e1051a39Sopenharmony_ci
1827e1051a39Sopenharmony_ci# If we use the unified build, collect information from build.info files
1828e1051a39Sopenharmony_cimy %unified_info = ();
1829e1051a39Sopenharmony_ci
1830e1051a39Sopenharmony_cimy $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1831e1051a39Sopenharmony_ciif ($builder eq "unified") {
1832e1051a39Sopenharmony_ci    use Text::Template 1.46;
1833e1051a39Sopenharmony_ci
1834e1051a39Sopenharmony_ci    sub cleandir {
1835e1051a39Sopenharmony_ci        my $base = shift;
1836e1051a39Sopenharmony_ci        my $dir = shift;
1837e1051a39Sopenharmony_ci        my $relativeto = shift || ".";
1838e1051a39Sopenharmony_ci
1839e1051a39Sopenharmony_ci        $dir = catdir($base,$dir) unless isabsolute($dir);
1840e1051a39Sopenharmony_ci
1841e1051a39Sopenharmony_ci        # Make sure the directories we're building in exists
1842e1051a39Sopenharmony_ci        mkpath($dir);
1843e1051a39Sopenharmony_ci
1844e1051a39Sopenharmony_ci        my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1845e1051a39Sopenharmony_ci        #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1846e1051a39Sopenharmony_ci        return $res;
1847e1051a39Sopenharmony_ci    }
1848e1051a39Sopenharmony_ci
1849e1051a39Sopenharmony_ci    sub cleanfile {
1850e1051a39Sopenharmony_ci        my $base = shift;
1851e1051a39Sopenharmony_ci        my $file = shift;
1852e1051a39Sopenharmony_ci        my $relativeto = shift || ".";
1853e1051a39Sopenharmony_ci
1854e1051a39Sopenharmony_ci        $file = catfile($base,$file) unless isabsolute($file);
1855e1051a39Sopenharmony_ci
1856e1051a39Sopenharmony_ci        my $d = dirname($file);
1857e1051a39Sopenharmony_ci        my $f = basename($file);
1858e1051a39Sopenharmony_ci
1859e1051a39Sopenharmony_ci        # Make sure the directories we're building in exists
1860e1051a39Sopenharmony_ci        mkpath($d);
1861e1051a39Sopenharmony_ci
1862e1051a39Sopenharmony_ci        my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1863e1051a39Sopenharmony_ci        #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1864e1051a39Sopenharmony_ci        return $res;
1865e1051a39Sopenharmony_ci    }
1866e1051a39Sopenharmony_ci
1867e1051a39Sopenharmony_ci    # Store the name of the template file we will build the build file from
1868e1051a39Sopenharmony_ci    # in %config.  This may be useful for the build file itself.
1869e1051a39Sopenharmony_ci    my @build_file_template_names =
1870e1051a39Sopenharmony_ci        ( $builder_platform."-".$config{build_file}.".tmpl",
1871e1051a39Sopenharmony_ci          $config{build_file}.".tmpl" );
1872e1051a39Sopenharmony_ci    my @build_file_templates = ();
1873e1051a39Sopenharmony_ci
1874e1051a39Sopenharmony_ci    # First, look in the user provided directory, if given
1875e1051a39Sopenharmony_ci    if (defined env($local_config_envname)) {
1876e1051a39Sopenharmony_ci        @build_file_templates =
1877e1051a39Sopenharmony_ci            map {
1878e1051a39Sopenharmony_ci                if ($^O eq 'VMS') {
1879e1051a39Sopenharmony_ci                    # VMS environment variables are logical names,
1880e1051a39Sopenharmony_ci                    # which can be used as is
1881e1051a39Sopenharmony_ci                    $local_config_envname . ':' . $_;
1882e1051a39Sopenharmony_ci                } else {
1883e1051a39Sopenharmony_ci                    catfile(env($local_config_envname), $_);
1884e1051a39Sopenharmony_ci                }
1885e1051a39Sopenharmony_ci            }
1886e1051a39Sopenharmony_ci            @build_file_template_names;
1887e1051a39Sopenharmony_ci    }
1888e1051a39Sopenharmony_ci    # Then, look in our standard directory
1889e1051a39Sopenharmony_ci    push @build_file_templates,
1890e1051a39Sopenharmony_ci        ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1891e1051a39Sopenharmony_ci          @build_file_template_names );
1892e1051a39Sopenharmony_ci
1893e1051a39Sopenharmony_ci    my $build_file_template;
1894e1051a39Sopenharmony_ci    for $_ (@build_file_templates) {
1895e1051a39Sopenharmony_ci        $build_file_template = $_;
1896e1051a39Sopenharmony_ci        last if -f $build_file_template;
1897e1051a39Sopenharmony_ci
1898e1051a39Sopenharmony_ci        $build_file_template = undef;
1899e1051a39Sopenharmony_ci    }
1900e1051a39Sopenharmony_ci    if (!defined $build_file_template) {
1901e1051a39Sopenharmony_ci        die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1902e1051a39Sopenharmony_ci    }
1903e1051a39Sopenharmony_ci    $config{build_file_templates}
1904e1051a39Sopenharmony_ci      = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"),
1905e1051a39Sopenharmony_ci                    $blddir),
1906e1051a39Sopenharmony_ci           $build_file_template ];
1907e1051a39Sopenharmony_ci
1908e1051a39Sopenharmony_ci    my @build_dirs = ( [ ] );   # current directory
1909e1051a39Sopenharmony_ci
1910e1051a39Sopenharmony_ci    $config{build_infos} = [ ];
1911e1051a39Sopenharmony_ci
1912e1051a39Sopenharmony_ci    # We want to detect configdata.pm in the source tree, so we
1913e1051a39Sopenharmony_ci    # don't use it if the build tree is different.
1914e1051a39Sopenharmony_ci    my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir);
1915e1051a39Sopenharmony_ci
1916e1051a39Sopenharmony_ci    # Any source file that we recognise is placed in this hash table, with
1917e1051a39Sopenharmony_ci    # the list of its intended destinations as value.  When everything has
1918e1051a39Sopenharmony_ci    # been collected, there's a routine that checks that these source files
1919e1051a39Sopenharmony_ci    # exist, or if they are generated, that the generator exists.
1920e1051a39Sopenharmony_ci    my %check_exist = ();
1921e1051a39Sopenharmony_ci    my %check_generate = ();
1922e1051a39Sopenharmony_ci
1923e1051a39Sopenharmony_ci    my %ordinals = ();
1924e1051a39Sopenharmony_ci    while (@build_dirs) {
1925e1051a39Sopenharmony_ci        my @curd = @{shift @build_dirs};
1926e1051a39Sopenharmony_ci        my $sourced = catdir($srcdir, @curd);
1927e1051a39Sopenharmony_ci        my $buildd = catdir($blddir, @curd);
1928e1051a39Sopenharmony_ci
1929e1051a39Sopenharmony_ci        my $unixdir = join('/', @curd);
1930e1051a39Sopenharmony_ci        if (exists $skipdir{$unixdir}) {
1931e1051a39Sopenharmony_ci            my $what = $skipdir{$unixdir};
1932e1051a39Sopenharmony_ci            push @{$disabled_info{$what}->{skipped}}, catdir(@curd);
1933e1051a39Sopenharmony_ci            next;
1934e1051a39Sopenharmony_ci        }
1935e1051a39Sopenharmony_ci
1936e1051a39Sopenharmony_ci        mkpath($buildd);
1937e1051a39Sopenharmony_ci
1938e1051a39Sopenharmony_ci        my $f = 'build.info';
1939e1051a39Sopenharmony_ci        # The basic things we're trying to build
1940e1051a39Sopenharmony_ci        my @programs = ();
1941e1051a39Sopenharmony_ci        my @libraries = ();
1942e1051a39Sopenharmony_ci        my @modules = ();
1943e1051a39Sopenharmony_ci        my @scripts = ();
1944e1051a39Sopenharmony_ci
1945e1051a39Sopenharmony_ci        my %sources = ();
1946e1051a39Sopenharmony_ci        my %shared_sources = ();
1947e1051a39Sopenharmony_ci        my %includes = ();
1948e1051a39Sopenharmony_ci        my %defines = ();
1949e1051a39Sopenharmony_ci        my %depends = ();
1950e1051a39Sopenharmony_ci        my %generate = ();
1951e1051a39Sopenharmony_ci        my %imagedocs = ();
1952e1051a39Sopenharmony_ci        my %htmldocs = ();
1953e1051a39Sopenharmony_ci        my %mandocs = ();
1954e1051a39Sopenharmony_ci
1955e1051a39Sopenharmony_ci        # Support for $variablename in build.info files.
1956e1051a39Sopenharmony_ci        # Embedded perl code is the ultimate master, still.  If its output
1957e1051a39Sopenharmony_ci        # contains a dollar sign, it had better be escaped, or it will be
1958e1051a39Sopenharmony_ci        # taken for a variable name prefix.
1959e1051a39Sopenharmony_ci        my %variables = ();
1960e1051a39Sopenharmony_ci        # Variable name syntax
1961e1051a39Sopenharmony_ci        my $variable_name_re = qr/(?P<VARIABLE>[[:alpha:]][[:alnum:]_]*)/;
1962e1051a39Sopenharmony_ci        # Value modifier syntaxes
1963e1051a39Sopenharmony_ci        my $variable_subst_re = qr/\/(?P<RE>(?:\\\/|.)*?)\/(?P<SUBST>.*?)/;
1964e1051a39Sopenharmony_ci        # Variable reference
1965e1051a39Sopenharmony_ci        my $variable_simple_re = qr/(?<!\\)\$${variable_name_re}/;
1966e1051a39Sopenharmony_ci        my $variable_w_mod_re =
1967e1051a39Sopenharmony_ci            qr/(?<!\\)\$\{${variable_name_re}(?P<MOD>(?:\\\/|.)*?)\}/;
1968e1051a39Sopenharmony_ci        # Tie it all together
1969e1051a39Sopenharmony_ci        my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/;
1970e1051a39Sopenharmony_ci
1971e1051a39Sopenharmony_ci        my $expand_variables = sub {
1972e1051a39Sopenharmony_ci            my $value = '';
1973e1051a39Sopenharmony_ci            my $value_rest = shift;
1974e1051a39Sopenharmony_ci
1975e1051a39Sopenharmony_ci            if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
1976e1051a39Sopenharmony_ci                print STDERR
1977e1051a39Sopenharmony_ci                    "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n"
1978e1051a39Sopenharmony_ci            }
1979e1051a39Sopenharmony_ci
1980e1051a39Sopenharmony_ci            while ($value_rest =~ /${variable_re}/) {
1981e1051a39Sopenharmony_ci                # We must save important regexp values, because the next
1982e1051a39Sopenharmony_ci                # regexp clears them
1983e1051a39Sopenharmony_ci                my $mod = $+{MOD};
1984e1051a39Sopenharmony_ci                my $variable_value = $variables{$+{VARIABLE}};
1985e1051a39Sopenharmony_ci
1986e1051a39Sopenharmony_ci                $value_rest = $';
1987e1051a39Sopenharmony_ci                $value .= $`;
1988e1051a39Sopenharmony_ci
1989e1051a39Sopenharmony_ci                # Process modifier expressions, if present
1990e1051a39Sopenharmony_ci                if (defined $mod) {
1991e1051a39Sopenharmony_ci                    if ($mod =~ /^${variable_subst_re}$/) {
1992e1051a39Sopenharmony_ci                        my $re = $+{RE};
1993e1051a39Sopenharmony_ci                        my $subst = $+{SUBST};
1994e1051a39Sopenharmony_ci
1995e1051a39Sopenharmony_ci                        $variable_value =~ s/\Q$re\E/$subst/g;
1996e1051a39Sopenharmony_ci
1997e1051a39Sopenharmony_ci                        if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
1998e1051a39Sopenharmony_ci                            print STDERR
1999e1051a39Sopenharmony_ci                                "DEBUG[\$expand_variables] ... and substituted ",
2000e1051a39Sopenharmony_ci                                "'$re' with '$subst'\n";
2001e1051a39Sopenharmony_ci                        }
2002e1051a39Sopenharmony_ci                    }
2003e1051a39Sopenharmony_ci                }
2004e1051a39Sopenharmony_ci
2005e1051a39Sopenharmony_ci                $value .= $variable_value;
2006e1051a39Sopenharmony_ci            }
2007e1051a39Sopenharmony_ci            if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2008e1051a39Sopenharmony_ci                print STDERR
2009e1051a39Sopenharmony_ci                    "DEBUG[\$expand_variables] ... into: '$value$value_rest'\n";
2010e1051a39Sopenharmony_ci            }
2011e1051a39Sopenharmony_ci            return $value . $value_rest;
2012e1051a39Sopenharmony_ci        };
2013e1051a39Sopenharmony_ci
2014e1051a39Sopenharmony_ci        # Support for attributes in build.info files
2015e1051a39Sopenharmony_ci        my %attributes = ();
2016e1051a39Sopenharmony_ci        my $handle_attributes = sub {
2017e1051a39Sopenharmony_ci            my $attr_str = shift;
2018e1051a39Sopenharmony_ci            my $ref = shift;
2019e1051a39Sopenharmony_ci            my @goals = @_;
2020e1051a39Sopenharmony_ci
2021e1051a39Sopenharmony_ci            return unless defined $attr_str;
2022e1051a39Sopenharmony_ci
2023e1051a39Sopenharmony_ci            my @a = tokenize($attr_str, qr|\s*,\s*|);
2024e1051a39Sopenharmony_ci            foreach my $a (@a) {
2025e1051a39Sopenharmony_ci                my $ac = 1;
2026e1051a39Sopenharmony_ci                my $ak = $a;
2027e1051a39Sopenharmony_ci                my $av = 1;
2028e1051a39Sopenharmony_ci                if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) {
2029e1051a39Sopenharmony_ci                    $ac = ! $1;
2030e1051a39Sopenharmony_ci                    $ak = $2;
2031e1051a39Sopenharmony_ci                    $av = $3;
2032e1051a39Sopenharmony_ci                }
2033e1051a39Sopenharmony_ci                foreach my $g (@goals) {
2034e1051a39Sopenharmony_ci                    if ($ac) {
2035e1051a39Sopenharmony_ci                        $$ref->{$g}->{$ak} = $av;
2036e1051a39Sopenharmony_ci                    } else {
2037e1051a39Sopenharmony_ci                        delete $$ref->{$g}->{$ak};
2038e1051a39Sopenharmony_ci                    }
2039e1051a39Sopenharmony_ci                }
2040e1051a39Sopenharmony_ci            }
2041e1051a39Sopenharmony_ci        };
2042e1051a39Sopenharmony_ci
2043e1051a39Sopenharmony_ci        # Support for pushing values on multiple indexes of a given hash
2044e1051a39Sopenharmony_ci        # array.
2045e1051a39Sopenharmony_ci        my $push_to = sub {
2046e1051a39Sopenharmony_ci            my $valueref = shift;
2047e1051a39Sopenharmony_ci            my $index_str = shift; # May be undef or empty
2048e1051a39Sopenharmony_ci            my $attrref = shift;   # May be undef
2049e1051a39Sopenharmony_ci            my $attr_str = shift;
2050e1051a39Sopenharmony_ci            my @values = @_;
2051e1051a39Sopenharmony_ci
2052e1051a39Sopenharmony_ci            if (defined $index_str) {
2053e1051a39Sopenharmony_ci                my @indexes = ( '' );
2054e1051a39Sopenharmony_ci                if ($index_str !~ m|^\s*$|) {
2055e1051a39Sopenharmony_ci                    @indexes = tokenize($index_str);
2056e1051a39Sopenharmony_ci                }
2057e1051a39Sopenharmony_ci                foreach (@indexes) {
2058e1051a39Sopenharmony_ci                    push @{$valueref->{$_}}, @values;
2059e1051a39Sopenharmony_ci                    if (defined $attrref) {
2060e1051a39Sopenharmony_ci                        $handle_attributes->($attr_str, \$$attrref->{$_},
2061e1051a39Sopenharmony_ci                                             @values);
2062e1051a39Sopenharmony_ci                    }
2063e1051a39Sopenharmony_ci                }
2064e1051a39Sopenharmony_ci            } else {
2065e1051a39Sopenharmony_ci                push @$valueref, @values;
2066e1051a39Sopenharmony_ci                $handle_attributes->($attr_str, $attrref, @values)
2067e1051a39Sopenharmony_ci                    if defined $attrref;
2068e1051a39Sopenharmony_ci            }
2069e1051a39Sopenharmony_ci        };
2070e1051a39Sopenharmony_ci
2071e1051a39Sopenharmony_ci        if ($buildinfo_debug) {
2072e1051a39Sopenharmony_ci            print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n";
2073e1051a39Sopenharmony_ci        }
2074e1051a39Sopenharmony_ci        push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
2075e1051a39Sopenharmony_ci        my $template =
2076e1051a39Sopenharmony_ci            Text::Template->new(TYPE => 'FILE',
2077e1051a39Sopenharmony_ci                                SOURCE => catfile($sourced, $f),
2078e1051a39Sopenharmony_ci                                PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
2079e1051a39Sopenharmony_ci        die "Something went wrong with $sourced/$f: $!\n" unless $template;
2080e1051a39Sopenharmony_ci        my @text =
2081e1051a39Sopenharmony_ci            split /^/m,
2082e1051a39Sopenharmony_ci            $template->fill_in(HASH => { config => \%config,
2083e1051a39Sopenharmony_ci                                         target => \%target,
2084e1051a39Sopenharmony_ci                                         disabled => \%disabled,
2085e1051a39Sopenharmony_ci                                         withargs => \%withargs,
2086e1051a39Sopenharmony_ci                                         builddir => abs2rel($buildd, $blddir),
2087e1051a39Sopenharmony_ci                                         sourcedir => abs2rel($sourced, $blddir),
2088e1051a39Sopenharmony_ci                                         buildtop => abs2rel($blddir, $blddir),
2089e1051a39Sopenharmony_ci                                         sourcetop => abs2rel($srcdir, $blddir) },
2090e1051a39Sopenharmony_ci                               DELIMITERS => [ "{-", "-}" ]);
2091e1051a39Sopenharmony_ci
2092e1051a39Sopenharmony_ci        # The top item of this stack has the following values
2093e1051a39Sopenharmony_ci        # -2 positive already run and we found ELSE (following ELSIF should fail)
2094e1051a39Sopenharmony_ci        # -1 positive already run (skip until ENDIF)
2095e1051a39Sopenharmony_ci        # 0 negatives so far (if we're at a condition, check it)
2096e1051a39Sopenharmony_ci        # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
2097e1051a39Sopenharmony_ci        # 2 positive ELSE (following ELSIF should fail)
2098e1051a39Sopenharmony_ci        my @skip = ();
2099e1051a39Sopenharmony_ci
2100e1051a39Sopenharmony_ci        # A few useful generic regexps
2101e1051a39Sopenharmony_ci        my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/;
2102e1051a39Sopenharmony_ci        my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/;
2103e1051a39Sopenharmony_ci        my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/;
2104e1051a39Sopenharmony_ci        my $value_re = qr/(?P<VALUE>.*?)/;
2105e1051a39Sopenharmony_ci        collect_information(
2106e1051a39Sopenharmony_ci            collect_from_array([ @text ],
2107e1051a39Sopenharmony_ci                               qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
2108e1051a39Sopenharmony_ci                                                $l1 =~ s/\\$//; $l1.$l2 }),
2109e1051a39Sopenharmony_ci            # Info we're looking for
2110e1051a39Sopenharmony_ci            qr/^\s* IF ${cond_re} \s*$/x
2111e1051a39Sopenharmony_ci            => sub {
2112e1051a39Sopenharmony_ci                if (! @skip || $skip[$#skip] > 0) {
2113e1051a39Sopenharmony_ci                    push @skip, !! $expand_variables->($+{COND});
2114e1051a39Sopenharmony_ci                } else {
2115e1051a39Sopenharmony_ci                    push @skip, -1;
2116e1051a39Sopenharmony_ci                }
2117e1051a39Sopenharmony_ci            },
2118e1051a39Sopenharmony_ci            qr/^\s* ELSIF ${cond_re} \s*$/x
2119e1051a39Sopenharmony_ci            => sub { die "ELSIF out of scope" if ! @skip;
2120e1051a39Sopenharmony_ci                     die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
2121e1051a39Sopenharmony_ci                     $skip[$#skip] = -1 if $skip[$#skip] != 0;
2122e1051a39Sopenharmony_ci                     $skip[$#skip] = !! $expand_variables->($+{COND})
2123e1051a39Sopenharmony_ci                         if $skip[$#skip] == 0; },
2124e1051a39Sopenharmony_ci            qr/^\s* ELSE \s*$/x
2125e1051a39Sopenharmony_ci            => sub { die "ELSE out of scope" if ! @skip;
2126e1051a39Sopenharmony_ci                     $skip[$#skip] = -2 if $skip[$#skip] != 0;
2127e1051a39Sopenharmony_ci                     $skip[$#skip] = 2 if $skip[$#skip] == 0; },
2128e1051a39Sopenharmony_ci            qr/^\s* ENDIF \s*$/x
2129e1051a39Sopenharmony_ci            => sub { die "ENDIF out of scope" if ! @skip;
2130e1051a39Sopenharmony_ci                     pop @skip; },
2131e1051a39Sopenharmony_ci            qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x
2132e1051a39Sopenharmony_ci            => sub {
2133e1051a39Sopenharmony_ci                if (!@skip || $skip[$#skip] > 0) {
2134e1051a39Sopenharmony_ci                    $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE});
2135e1051a39Sopenharmony_ci                }
2136e1051a39Sopenharmony_ci            },
2137e1051a39Sopenharmony_ci            qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x
2138e1051a39Sopenharmony_ci            => sub {
2139e1051a39Sopenharmony_ci                if (!@skip || $skip[$#skip] > 0) {
2140e1051a39Sopenharmony_ci                    foreach (tokenize($expand_variables->($+{VALUE}))) {
2141e1051a39Sopenharmony_ci                        push @build_dirs, [ @curd, splitdir($_, 1) ];
2142e1051a39Sopenharmony_ci                    }
2143e1051a39Sopenharmony_ci                }
2144e1051a39Sopenharmony_ci            },
2145e1051a39Sopenharmony_ci            qr/^\s* PROGRAMS ${attribs_re} \s* =  \s* ${value_re} \s* $/x
2146e1051a39Sopenharmony_ci            => sub { $push_to->(\@programs, undef,
2147e1051a39Sopenharmony_ci                                \$attributes{programs}, $+{ATTRIBS},
2148e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2149e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2150e1051a39Sopenharmony_ci            qr/^\s* LIBS ${attribs_re} \s* =  \s* ${value_re} \s* $/x
2151e1051a39Sopenharmony_ci            => sub { $push_to->(\@libraries, undef,
2152e1051a39Sopenharmony_ci                                \$attributes{libraries}, $+{ATTRIBS},
2153e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2154e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2155e1051a39Sopenharmony_ci            qr/^\s* MODULES ${attribs_re} \s* =  \s* ${value_re} \s* $/x
2156e1051a39Sopenharmony_ci            => sub { $push_to->(\@modules, undef,
2157e1051a39Sopenharmony_ci                                \$attributes{modules}, $+{ATTRIBS},
2158e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2159e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2160e1051a39Sopenharmony_ci            qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x
2161e1051a39Sopenharmony_ci            => sub { $push_to->(\@scripts, undef,
2162e1051a39Sopenharmony_ci                                \$attributes{scripts}, $+{ATTRIBS},
2163e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2164e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2165e1051a39Sopenharmony_ci            qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2166e1051a39Sopenharmony_ci            => sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}),
2167e1051a39Sopenharmony_ci                                undef, undef,
2168e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2169e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2170e1051a39Sopenharmony_ci            qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2171e1051a39Sopenharmony_ci            => sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}),
2172e1051a39Sopenharmony_ci                                undef, undef,
2173e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2174e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2175e1051a39Sopenharmony_ci            qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2176e1051a39Sopenharmony_ci            => sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}),
2177e1051a39Sopenharmony_ci                                undef, undef,
2178e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2179e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2180e1051a39Sopenharmony_ci            qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2181e1051a39Sopenharmony_ci            => sub { $push_to->(\%sources, $expand_variables->($+{INDEX}),
2182e1051a39Sopenharmony_ci                                \$attributes{sources}, $+{ATTRIBS},
2183e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2184e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2185e1051a39Sopenharmony_ci            qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2186e1051a39Sopenharmony_ci            => sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}),
2187e1051a39Sopenharmony_ci                                \$attributes{sources}, $+{ATTRIBS},
2188e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2189e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2190e1051a39Sopenharmony_ci            qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x
2191e1051a39Sopenharmony_ci            => sub { $push_to->(\%includes, $expand_variables->($+{INDEX}),
2192e1051a39Sopenharmony_ci                                undef, undef,
2193e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2194e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2195e1051a39Sopenharmony_ci            qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x
2196e1051a39Sopenharmony_ci            => sub { $push_to->(\%defines, $expand_variables->($+{INDEX}),
2197e1051a39Sopenharmony_ci                                undef, undef,
2198e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2199e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2200e1051a39Sopenharmony_ci            qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2201e1051a39Sopenharmony_ci            => sub { $push_to->(\%depends, $expand_variables->($+{INDEX}),
2202e1051a39Sopenharmony_ci                                \$attributes{depends}, $+{ATTRIBS},
2203e1051a39Sopenharmony_ci                                tokenize($expand_variables->($+{VALUE})))
2204e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2205e1051a39Sopenharmony_ci            qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2206e1051a39Sopenharmony_ci            => sub { $push_to->(\%generate, $expand_variables->($+{INDEX}),
2207e1051a39Sopenharmony_ci                                \$attributes{generate}, $+{ATTRIBS},
2208e1051a39Sopenharmony_ci                                $expand_variables->($+{VALUE}))
2209e1051a39Sopenharmony_ci                         if !@skip || $skip[$#skip] > 0; },
2210e1051a39Sopenharmony_ci            qr/^\s* (?:\#.*)? $/x => sub { },
2211e1051a39Sopenharmony_ci            "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
2212e1051a39Sopenharmony_ci            "BEFORE" => sub {
2213e1051a39Sopenharmony_ci                if ($buildinfo_debug) {
2214e1051a39Sopenharmony_ci                    print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
2215e1051a39Sopenharmony_ci                    print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2216e1051a39Sopenharmony_ci                }
2217e1051a39Sopenharmony_ci            },
2218e1051a39Sopenharmony_ci            "AFTER" => sub {
2219e1051a39Sopenharmony_ci                if ($buildinfo_debug) {
2220e1051a39Sopenharmony_ci                    print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2221e1051a39Sopenharmony_ci                }
2222e1051a39Sopenharmony_ci            },
2223e1051a39Sopenharmony_ci            );
2224e1051a39Sopenharmony_ci        die "runaway IF?" if (@skip);
2225e1051a39Sopenharmony_ci
2226e1051a39Sopenharmony_ci        if (grep { defined $attributes{modules}->{$_}->{engine} } keys %attributes
2227e1051a39Sopenharmony_ci                and !$config{dynamic_engines}) {
2228e1051a39Sopenharmony_ci            die <<"EOF"
2229e1051a39Sopenharmony_ciENGINES can only be used if configured with 'dynamic-engine'.
2230e1051a39Sopenharmony_ciThis is usually a fault in a build.info file.
2231e1051a39Sopenharmony_ciEOF
2232e1051a39Sopenharmony_ci        }
2233e1051a39Sopenharmony_ci
2234e1051a39Sopenharmony_ci        {
2235e1051a39Sopenharmony_ci            my %infos = ( programs  => [ @programs  ],
2236e1051a39Sopenharmony_ci                          libraries => [ @libraries ],
2237e1051a39Sopenharmony_ci                          modules   => [ @modules   ],
2238e1051a39Sopenharmony_ci                          scripts   => [ @scripts   ] );
2239e1051a39Sopenharmony_ci            foreach my $k (keys %infos) {
2240e1051a39Sopenharmony_ci                foreach (@{$infos{$k}}) {
2241e1051a39Sopenharmony_ci                    my $item = cleanfile($buildd, $_, $blddir);
2242e1051a39Sopenharmony_ci                    $unified_info{$k}->{$item} = 1;
2243e1051a39Sopenharmony_ci
2244e1051a39Sopenharmony_ci                    # Fix up associated attributes
2245e1051a39Sopenharmony_ci                    $unified_info{attributes}->{$k}->{$item} =
2246e1051a39Sopenharmony_ci                        $attributes{$k}->{$_}
2247e1051a39Sopenharmony_ci                        if defined $attributes{$k}->{$_};
2248e1051a39Sopenharmony_ci                }
2249e1051a39Sopenharmony_ci            }
2250e1051a39Sopenharmony_ci        }
2251e1051a39Sopenharmony_ci
2252e1051a39Sopenharmony_ci        # Check that we haven't defined any library as both shared and
2253e1051a39Sopenharmony_ci        # explicitly static.  That is forbidden.
2254e1051a39Sopenharmony_ci        my @doubles = ();
2255e1051a39Sopenharmony_ci        foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
2256e1051a39Sopenharmony_ci            (my $l = $_) =~ s/\.a$//;
2257e1051a39Sopenharmony_ci            push @doubles, $l if defined $unified_info{libraries}->{$l};
2258e1051a39Sopenharmony_ci        }
2259e1051a39Sopenharmony_ci        die "these libraries are both explicitly static and shared:\n  ",
2260e1051a39Sopenharmony_ci            join(" ", @doubles), "\n"
2261e1051a39Sopenharmony_ci            if @doubles;
2262e1051a39Sopenharmony_ci
2263e1051a39Sopenharmony_ci        foreach (keys %sources) {
2264e1051a39Sopenharmony_ci            my $dest = $_;
2265e1051a39Sopenharmony_ci            my $ddest = cleanfile($buildd, $_, $blddir);
2266e1051a39Sopenharmony_ci            foreach (@{$sources{$dest}}) {
2267e1051a39Sopenharmony_ci                my $s = cleanfile($sourced, $_, $blddir);
2268e1051a39Sopenharmony_ci
2269e1051a39Sopenharmony_ci                # If it's generated or we simply don't find it in the source
2270e1051a39Sopenharmony_ci                # tree, we assume it's in the build tree.
2271e1051a39Sopenharmony_ci                if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
2272e1051a39Sopenharmony_ci                    $s = cleanfile($buildd, $_, $blddir);
2273e1051a39Sopenharmony_ci                }
2274e1051a39Sopenharmony_ci                my $o = $_;
2275e1051a39Sopenharmony_ci                # We recognise C++, C and asm files
2276e1051a39Sopenharmony_ci                if ($s =~ /\.(cc|cpp|c|s|S)$/) {
2277e1051a39Sopenharmony_ci                    push @{$check_exist{$s}}, $ddest;
2278e1051a39Sopenharmony_ci                    $o =~ s/\.[csS]$/.o/; # C and assembler
2279e1051a39Sopenharmony_ci                    $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2280e1051a39Sopenharmony_ci                    $o = cleanfile($buildd, $o, $blddir);
2281e1051a39Sopenharmony_ci                    $unified_info{sources}->{$ddest}->{$o} = -1;
2282e1051a39Sopenharmony_ci                    $unified_info{sources}->{$o}->{$s} = -1;
2283e1051a39Sopenharmony_ci                } elsif ($s =~ /\.rc$/) {
2284e1051a39Sopenharmony_ci                    # We also recognise resource files
2285e1051a39Sopenharmony_ci                    push @{$check_exist{$s}}, $ddest;
2286e1051a39Sopenharmony_ci                    $o =~ s/\.rc$/.res/; # Resource configuration
2287e1051a39Sopenharmony_ci                    $o = cleanfile($buildd, $o, $blddir);
2288e1051a39Sopenharmony_ci                    $unified_info{sources}->{$ddest}->{$o} = -1;
2289e1051a39Sopenharmony_ci                    $unified_info{sources}->{$o}->{$s} = -1;
2290e1051a39Sopenharmony_ci                } else {
2291e1051a39Sopenharmony_ci                    push @{$check_exist{$s}}, $ddest;
2292e1051a39Sopenharmony_ci                    $unified_info{sources}->{$ddest}->{$s} = 1;
2293e1051a39Sopenharmony_ci                }
2294e1051a39Sopenharmony_ci                # Fix up associated attributes
2295e1051a39Sopenharmony_ci                if ($o ne $_) {
2296e1051a39Sopenharmony_ci                    $unified_info{attributes}->{sources}->{$ddest}->{$o} =
2297e1051a39Sopenharmony_ci                        $unified_info{attributes}->{sources}->{$o}->{$s} =
2298e1051a39Sopenharmony_ci                        $attributes{sources}->{$dest}->{$_}
2299e1051a39Sopenharmony_ci                        if defined $attributes{sources}->{$dest}->{$_};
2300e1051a39Sopenharmony_ci                } else {
2301e1051a39Sopenharmony_ci                    $unified_info{attributes}->{sources}->{$ddest}->{$s} =
2302e1051a39Sopenharmony_ci                        $attributes{sources}->{$dest}->{$_}
2303e1051a39Sopenharmony_ci                        if defined $attributes{sources}->{$dest}->{$_};
2304e1051a39Sopenharmony_ci                }
2305e1051a39Sopenharmony_ci            }
2306e1051a39Sopenharmony_ci        }
2307e1051a39Sopenharmony_ci
2308e1051a39Sopenharmony_ci        foreach (keys %shared_sources) {
2309e1051a39Sopenharmony_ci            my $dest = $_;
2310e1051a39Sopenharmony_ci            my $ddest = cleanfile($buildd, $_, $blddir);
2311e1051a39Sopenharmony_ci            foreach (@{$shared_sources{$dest}}) {
2312e1051a39Sopenharmony_ci                my $s = cleanfile($sourced, $_, $blddir);
2313e1051a39Sopenharmony_ci
2314e1051a39Sopenharmony_ci                # If it's generated or we simply don't find it in the source
2315e1051a39Sopenharmony_ci                # tree, we assume it's in the build tree.
2316e1051a39Sopenharmony_ci                if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
2317e1051a39Sopenharmony_ci                    $s = cleanfile($buildd, $_, $blddir);
2318e1051a39Sopenharmony_ci                }
2319e1051a39Sopenharmony_ci
2320e1051a39Sopenharmony_ci                my $o = $_;
2321e1051a39Sopenharmony_ci                if ($s =~ /\.(cc|cpp|c|s|S)$/) {
2322e1051a39Sopenharmony_ci                    # We recognise C++, C and asm files
2323e1051a39Sopenharmony_ci                    push @{$check_exist{$s}}, $ddest;
2324e1051a39Sopenharmony_ci                    $o =~ s/\.[csS]$/.o/; # C and assembler
2325e1051a39Sopenharmony_ci                    $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2326e1051a39Sopenharmony_ci                    $o = cleanfile($buildd, $o, $blddir);
2327e1051a39Sopenharmony_ci                    $unified_info{shared_sources}->{$ddest}->{$o} = -1;
2328e1051a39Sopenharmony_ci                    $unified_info{sources}->{$o}->{$s} = -1;
2329e1051a39Sopenharmony_ci                } elsif ($s =~ /\.rc$/) {
2330e1051a39Sopenharmony_ci                    # We also recognise resource files
2331e1051a39Sopenharmony_ci                    push @{$check_exist{$s}}, $ddest;
2332e1051a39Sopenharmony_ci                    $o =~ s/\.rc$/.res/; # Resource configuration
2333e1051a39Sopenharmony_ci                    $o = cleanfile($buildd, $o, $blddir);
2334e1051a39Sopenharmony_ci                    $unified_info{shared_sources}->{$ddest}->{$o} = -1;
2335e1051a39Sopenharmony_ci                    $unified_info{sources}->{$o}->{$s} = -1;
2336e1051a39Sopenharmony_ci                } elsif ($s =~ /\.ld$/) {
2337e1051a39Sopenharmony_ci                    # We also recognise linker scripts (or corresponding)
2338e1051a39Sopenharmony_ci                    # We know they are generated files
2339e1051a39Sopenharmony_ci                    push @{$check_exist{$s}}, $ddest;
2340e1051a39Sopenharmony_ci                    $o = cleanfile($buildd, $_, $blddir);
2341e1051a39Sopenharmony_ci                    $unified_info{shared_sources}->{$ddest}->{$o} = 1;
2342e1051a39Sopenharmony_ci                } else {
2343e1051a39Sopenharmony_ci                    die "unrecognised source file type for shared library: $s\n";
2344e1051a39Sopenharmony_ci                }
2345e1051a39Sopenharmony_ci                # Fix up associated attributes
2346e1051a39Sopenharmony_ci                if ($o ne $_) {
2347e1051a39Sopenharmony_ci                    $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
2348e1051a39Sopenharmony_ci                        $unified_info{attributes}->{sources}->{$o}->{$s} =
2349e1051a39Sopenharmony_ci                        $attributes{sources}->{$dest}->{$_}
2350e1051a39Sopenharmony_ci                        if defined $attributes{sources}->{$dest}->{$_};
2351e1051a39Sopenharmony_ci                } else {
2352e1051a39Sopenharmony_ci                    $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
2353e1051a39Sopenharmony_ci                        $attributes{sources}->{$dest}->{$_}
2354e1051a39Sopenharmony_ci                        if defined $attributes{sources}->{$dest}->{$_};
2355e1051a39Sopenharmony_ci                }
2356e1051a39Sopenharmony_ci            }
2357e1051a39Sopenharmony_ci        }
2358e1051a39Sopenharmony_ci
2359e1051a39Sopenharmony_ci        foreach (keys %generate) {
2360e1051a39Sopenharmony_ci            my $dest = $_;
2361e1051a39Sopenharmony_ci            my $ddest = cleanfile($buildd, $_, $blddir);
2362e1051a39Sopenharmony_ci            die "more than one generator for $dest: "
2363e1051a39Sopenharmony_ci                ,join(" ", @{$generate{$_}}),"\n"
2364e1051a39Sopenharmony_ci                if scalar @{$generate{$_}} > 1;
2365e1051a39Sopenharmony_ci            my @generator = split /\s+/, $generate{$dest}->[0];
2366e1051a39Sopenharmony_ci            my $gen = $generator[0];
2367e1051a39Sopenharmony_ci            $generator[0] = cleanfile($sourced, $gen, $blddir);
2368e1051a39Sopenharmony_ci
2369e1051a39Sopenharmony_ci            # If the generator is itself generated, it's in the build tree
2370e1051a39Sopenharmony_ci            if ($generate{$gen} || ! -f $generator[0]) {
2371e1051a39Sopenharmony_ci                $generator[0] = cleanfile($buildd, $gen, $blddir);
2372e1051a39Sopenharmony_ci            }
2373e1051a39Sopenharmony_ci            $check_generate{$ddest}->{$generator[0]}++;
2374e1051a39Sopenharmony_ci
2375e1051a39Sopenharmony_ci            $unified_info{generate}->{$ddest} = [ @generator ];
2376e1051a39Sopenharmony_ci            # Fix up associated attributes
2377e1051a39Sopenharmony_ci            $unified_info{attributes}->{generate}->{$ddest} =
2378e1051a39Sopenharmony_ci                $attributes{generate}->{$dest}->{$gen}
2379e1051a39Sopenharmony_ci                if defined $attributes{generate}->{$dest}->{$gen};
2380e1051a39Sopenharmony_ci        }
2381e1051a39Sopenharmony_ci
2382e1051a39Sopenharmony_ci        foreach (keys %depends) {
2383e1051a39Sopenharmony_ci            my $dest = $_;
2384e1051a39Sopenharmony_ci            my $ddest = $dest;
2385e1051a39Sopenharmony_ci
2386e1051a39Sopenharmony_ci            if ($dest =~ /^\|(.*)\|$/) {
2387e1051a39Sopenharmony_ci                # Collect the raw target
2388e1051a39Sopenharmony_ci                $unified_info{targets}->{$1} = 1;
2389e1051a39Sopenharmony_ci                $ddest = $1;
2390e1051a39Sopenharmony_ci            } elsif ($dest eq '') {
2391e1051a39Sopenharmony_ci                $ddest = '';
2392e1051a39Sopenharmony_ci            } else {
2393e1051a39Sopenharmony_ci                $ddest = cleanfile($sourced, $_, $blddir);
2394e1051a39Sopenharmony_ci
2395e1051a39Sopenharmony_ci                # If the destination doesn't exist in source, it can only be
2396e1051a39Sopenharmony_ci                # a generated file in the build tree.
2397e1051a39Sopenharmony_ci                if ($ddest eq $src_configdata || ! -f $ddest) {
2398e1051a39Sopenharmony_ci                    $ddest = cleanfile($buildd, $_, $blddir);
2399e1051a39Sopenharmony_ci                }
2400e1051a39Sopenharmony_ci            }
2401e1051a39Sopenharmony_ci            foreach (@{$depends{$dest}}) {
2402e1051a39Sopenharmony_ci                my $d = cleanfile($sourced, $_, $blddir);
2403e1051a39Sopenharmony_ci                my $d2 = cleanfile($buildd, $_, $blddir);
2404e1051a39Sopenharmony_ci
2405e1051a39Sopenharmony_ci                # If we know it's generated, or assume it is because we can't
2406e1051a39Sopenharmony_ci                # find it in the source tree, we set file we depend on to be
2407e1051a39Sopenharmony_ci                # in the build tree rather than the source tree.
2408e1051a39Sopenharmony_ci                if ($d eq $src_configdata
2409e1051a39Sopenharmony_ci                    || (grep { $d2 eq $_ }
2410e1051a39Sopenharmony_ci                        keys %{$unified_info{generate}})
2411e1051a39Sopenharmony_ci                    || ! -f $d) {
2412e1051a39Sopenharmony_ci                    $d = $d2;
2413e1051a39Sopenharmony_ci                }
2414e1051a39Sopenharmony_ci                $unified_info{depends}->{$ddest}->{$d} = 1;
2415e1051a39Sopenharmony_ci
2416e1051a39Sopenharmony_ci                # Fix up associated attributes
2417e1051a39Sopenharmony_ci                $unified_info{attributes}->{depends}->{$ddest}->{$d} =
2418e1051a39Sopenharmony_ci                    $attributes{depends}->{$dest}->{$_}
2419e1051a39Sopenharmony_ci                    if defined $attributes{depends}->{$dest}->{$_};
2420e1051a39Sopenharmony_ci            }
2421e1051a39Sopenharmony_ci        }
2422e1051a39Sopenharmony_ci
2423e1051a39Sopenharmony_ci        foreach (keys %includes) {
2424e1051a39Sopenharmony_ci            my $dest = $_;
2425e1051a39Sopenharmony_ci            my $ddest = cleanfile($sourced, $_, $blddir);
2426e1051a39Sopenharmony_ci
2427e1051a39Sopenharmony_ci            # If the destination doesn't exist in source, it can only be
2428e1051a39Sopenharmony_ci            # a generated file in the build tree.
2429e1051a39Sopenharmony_ci            if ($ddest eq $src_configdata || ! -f $ddest) {
2430e1051a39Sopenharmony_ci                $ddest = cleanfile($buildd, $_, $blddir);
2431e1051a39Sopenharmony_ci            }
2432e1051a39Sopenharmony_ci            foreach (@{$includes{$dest}}) {
2433e1051a39Sopenharmony_ci                my $is = cleandir($sourced, $_, $blddir);
2434e1051a39Sopenharmony_ci                my $ib = cleandir($buildd, $_, $blddir);
2435e1051a39Sopenharmony_ci                push @{$unified_info{includes}->{$ddest}->{source}}, $is
2436e1051a39Sopenharmony_ci                    unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
2437e1051a39Sopenharmony_ci                push @{$unified_info{includes}->{$ddest}->{build}}, $ib
2438e1051a39Sopenharmony_ci                    unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
2439e1051a39Sopenharmony_ci            }
2440e1051a39Sopenharmony_ci        }
2441e1051a39Sopenharmony_ci
2442e1051a39Sopenharmony_ci        foreach my $dest (keys %defines) {
2443e1051a39Sopenharmony_ci            my $ddest;
2444e1051a39Sopenharmony_ci
2445e1051a39Sopenharmony_ci            if ($dest ne "") {
2446e1051a39Sopenharmony_ci                $ddest = cleanfile($sourced, $dest, $blddir);
2447e1051a39Sopenharmony_ci
2448e1051a39Sopenharmony_ci                # If the destination doesn't exist in source, it can only
2449e1051a39Sopenharmony_ci                # be a generated file in the build tree.
2450e1051a39Sopenharmony_ci                if (! -f $ddest) {
2451e1051a39Sopenharmony_ci                    $ddest = cleanfile($buildd, $dest, $blddir);
2452e1051a39Sopenharmony_ci                }
2453e1051a39Sopenharmony_ci            }
2454e1051a39Sopenharmony_ci            foreach my $v (@{$defines{$dest}}) {
2455e1051a39Sopenharmony_ci                $v =~ m|^([^=]*)(=.*)?$|;
2456e1051a39Sopenharmony_ci                die "0 length macro name not permitted\n" if $1 eq "";
2457e1051a39Sopenharmony_ci                if ($dest ne "") {
2458e1051a39Sopenharmony_ci                    die "$1 defined more than once\n"
2459e1051a39Sopenharmony_ci                        if defined $unified_info{defines}->{$ddest}->{$1};
2460e1051a39Sopenharmony_ci                    $unified_info{defines}->{$ddest}->{$1} = $2;
2461e1051a39Sopenharmony_ci                } else {
2462e1051a39Sopenharmony_ci                    die "$1 defined more than once\n"
2463e1051a39Sopenharmony_ci                        if grep { $v eq $_ } @{$config{defines}};
2464e1051a39Sopenharmony_ci                    push @{$config{defines}}, $v;
2465e1051a39Sopenharmony_ci                }
2466e1051a39Sopenharmony_ci            }
2467e1051a39Sopenharmony_ci        }
2468e1051a39Sopenharmony_ci
2469e1051a39Sopenharmony_ci        foreach my $section (keys %imagedocs) {
2470e1051a39Sopenharmony_ci            foreach (@{$imagedocs{$section}}) {
2471e1051a39Sopenharmony_ci                my $imagedocs = cleanfile($buildd, $_, $blddir);
2472e1051a39Sopenharmony_ci                $unified_info{imagedocs}->{$section}->{$imagedocs} = 1;
2473e1051a39Sopenharmony_ci            }
2474e1051a39Sopenharmony_ci        }
2475e1051a39Sopenharmony_ci
2476e1051a39Sopenharmony_ci        foreach my $section (keys %htmldocs) {
2477e1051a39Sopenharmony_ci            foreach (@{$htmldocs{$section}}) {
2478e1051a39Sopenharmony_ci                my $htmldocs = cleanfile($buildd, $_, $blddir);
2479e1051a39Sopenharmony_ci                $unified_info{htmldocs}->{$section}->{$htmldocs} = 1;
2480e1051a39Sopenharmony_ci            }
2481e1051a39Sopenharmony_ci        }
2482e1051a39Sopenharmony_ci
2483e1051a39Sopenharmony_ci        foreach my $section (keys %mandocs) {
2484e1051a39Sopenharmony_ci            foreach (@{$mandocs{$section}}) {
2485e1051a39Sopenharmony_ci                my $mandocs = cleanfile($buildd, $_, $blddir);
2486e1051a39Sopenharmony_ci                $unified_info{mandocs}->{$section}->{$mandocs} = 1;
2487e1051a39Sopenharmony_ci            }
2488e1051a39Sopenharmony_ci        }
2489e1051a39Sopenharmony_ci    }
2490e1051a39Sopenharmony_ci
2491e1051a39Sopenharmony_ci    my $ordinals_text = join(', ', sort keys %ordinals);
2492e1051a39Sopenharmony_ci    warn <<"EOF" if $ordinals_text;
2493e1051a39Sopenharmony_ci
2494e1051a39Sopenharmony_ciWARNING: ORDINALS were specified for $ordinals_text
2495e1051a39Sopenharmony_ciThey are ignored and should be replaced with a combination of GENERATE,
2496e1051a39Sopenharmony_ciDEPEND and SHARED_SOURCE.
2497e1051a39Sopenharmony_ciEOF
2498e1051a39Sopenharmony_ci
2499e1051a39Sopenharmony_ci    # Check that each generated file is only generated once
2500e1051a39Sopenharmony_ci    my $ambiguous_generation = 0;
2501e1051a39Sopenharmony_ci    foreach (sort keys %check_generate) {
2502e1051a39Sopenharmony_ci        my @generators = sort keys %{$check_generate{$_}};
2503e1051a39Sopenharmony_ci        my $generators_txt = join(', ', @generators);
2504e1051a39Sopenharmony_ci        if (scalar @generators > 1) {
2505e1051a39Sopenharmony_ci            warn "$_ is GENERATEd by more than one generator ($generators_txt)\n";
2506e1051a39Sopenharmony_ci            $ambiguous_generation++;
2507e1051a39Sopenharmony_ci        }
2508e1051a39Sopenharmony_ci        if ($check_generate{$_}->{$generators[0]} > 1) {
2509e1051a39Sopenharmony_ci            warn "INFO: $_ has more than one GENERATE declaration (same generator)\n"
2510e1051a39Sopenharmony_ci        }
2511e1051a39Sopenharmony_ci    }
2512e1051a39Sopenharmony_ci    die "There are ambiguous source file generations\n"
2513e1051a39Sopenharmony_ci        if $ambiguous_generation > 0;
2514e1051a39Sopenharmony_ci
2515e1051a39Sopenharmony_ci    # All given source files should exist, or if generated, their
2516e1051a39Sopenharmony_ci    # generator should exist.  This loop ensures this is true.
2517e1051a39Sopenharmony_ci    my $missing = 0;
2518e1051a39Sopenharmony_ci    foreach my $orig (sort keys %check_exist) {
2519e1051a39Sopenharmony_ci        foreach my $dest (@{$check_exist{$orig}}) {
2520e1051a39Sopenharmony_ci            if ($orig ne $src_configdata) {
2521e1051a39Sopenharmony_ci                if ($orig =~ /\.a$/) {
2522e1051a39Sopenharmony_ci                    # Static library names may be used as sources, so we
2523e1051a39Sopenharmony_ci                    # need to detect those and give them special treatment.
2524e1051a39Sopenharmony_ci                    unless (grep { $_ eq $orig }
2525e1051a39Sopenharmony_ci                            keys %{$unified_info{libraries}}) {
2526e1051a39Sopenharmony_ci                        warn "$orig is given as source for $dest, but no such library is built\n";
2527e1051a39Sopenharmony_ci                        $missing++;
2528e1051a39Sopenharmony_ci                    }
2529e1051a39Sopenharmony_ci                } else {
2530e1051a39Sopenharmony_ci                    # A source may be generated, and its generator may be
2531e1051a39Sopenharmony_ci                    # generated as well.  We therefore loop to dig out the
2532e1051a39Sopenharmony_ci                    # first generator.
2533e1051a39Sopenharmony_ci                    my $gen = $orig;
2534e1051a39Sopenharmony_ci
2535e1051a39Sopenharmony_ci                    while (my @next = keys %{$check_generate{$gen}}) {
2536e1051a39Sopenharmony_ci                        $gen = $next[0];
2537e1051a39Sopenharmony_ci                    }
2538e1051a39Sopenharmony_ci
2539e1051a39Sopenharmony_ci                    if (! -f $gen) {
2540e1051a39Sopenharmony_ci                        if ($gen ne $orig) {
2541e1051a39Sopenharmony_ci                            $missing++;
2542e1051a39Sopenharmony_ci                            warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n";
2543e1051a39Sopenharmony_ci                        } else {
2544e1051a39Sopenharmony_ci                            $missing++;
2545e1051a39Sopenharmony_ci                            warn "$orig is given as source for $dest, but is missing\n";
2546e1051a39Sopenharmony_ci                        }
2547e1051a39Sopenharmony_ci                    }
2548e1051a39Sopenharmony_ci                }
2549e1051a39Sopenharmony_ci            }
2550e1051a39Sopenharmony_ci        }
2551e1051a39Sopenharmony_ci    }
2552e1051a39Sopenharmony_ci    die "There are files missing\n" if $missing > 0;
2553e1051a39Sopenharmony_ci
2554e1051a39Sopenharmony_ci    # Go through the sources of all libraries and check that the same basename
2555e1051a39Sopenharmony_ci    # doesn't appear more than once.  Some static library archivers depend on
2556e1051a39Sopenharmony_ci    # them being unique.
2557e1051a39Sopenharmony_ci    {
2558e1051a39Sopenharmony_ci        my $err = 0;
2559e1051a39Sopenharmony_ci        foreach my $prod (keys %{$unified_info{libraries}}) {
2560e1051a39Sopenharmony_ci            my @prod_sources =
2561e1051a39Sopenharmony_ci                map { keys %{$unified_info{sources}->{$_}} }
2562e1051a39Sopenharmony_ci                keys %{$unified_info{sources}->{$prod}};
2563e1051a39Sopenharmony_ci            my %srccnt = ();
2564e1051a39Sopenharmony_ci
2565e1051a39Sopenharmony_ci            # Count how many times a given each source basename
2566e1051a39Sopenharmony_ci            # appears for each product.
2567e1051a39Sopenharmony_ci            foreach my $src (@prod_sources) {
2568e1051a39Sopenharmony_ci                $srccnt{basename $src}++;
2569e1051a39Sopenharmony_ci            }
2570e1051a39Sopenharmony_ci
2571e1051a39Sopenharmony_ci            foreach my $src (keys %srccnt) {
2572e1051a39Sopenharmony_ci                if ((my $cnt = $srccnt{$src}) > 1) {
2573e1051a39Sopenharmony_ci                    print STDERR "$src appears $cnt times for the product $prod\n";
2574e1051a39Sopenharmony_ci                    $err++
2575e1051a39Sopenharmony_ci                }
2576e1051a39Sopenharmony_ci            }
2577e1051a39Sopenharmony_ci        }
2578e1051a39Sopenharmony_ci        die if $err > 0;
2579e1051a39Sopenharmony_ci    }
2580e1051a39Sopenharmony_ci
2581e1051a39Sopenharmony_ci    # Massage the result
2582e1051a39Sopenharmony_ci
2583e1051a39Sopenharmony_ci    # If we depend on a header file or a perl module, add an inclusion of
2584e1051a39Sopenharmony_ci    # its directory to allow smoothe inclusion
2585e1051a39Sopenharmony_ci    foreach my $dest (keys %{$unified_info{depends}}) {
2586e1051a39Sopenharmony_ci        next if $dest eq "";
2587e1051a39Sopenharmony_ci        foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
2588e1051a39Sopenharmony_ci            next unless $d =~ /\.(h|pm)$/;
2589e1051a39Sopenharmony_ci            my $i = dirname($d);
2590e1051a39Sopenharmony_ci            my $spot =
2591e1051a39Sopenharmony_ci                $d eq "configdata.pm" || defined($unified_info{generate}->{$d})
2592e1051a39Sopenharmony_ci                ? 'build' : 'source';
2593e1051a39Sopenharmony_ci            push @{$unified_info{includes}->{$dest}->{$spot}}, $i
2594e1051a39Sopenharmony_ci                unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{$spot}};
2595e1051a39Sopenharmony_ci        }
2596e1051a39Sopenharmony_ci    }
2597e1051a39Sopenharmony_ci
2598e1051a39Sopenharmony_ci    # Go through all intermediary files and change their names to something that
2599e1051a39Sopenharmony_ci    # reflects what they will be built for.  Note that for some source files,
2600e1051a39Sopenharmony_ci    # this leads to duplicate object files because they are used multiple times.
2601e1051a39Sopenharmony_ci    # the goal is to rename all object files according to this scheme:
2602e1051a39Sopenharmony_ci    #    {productname}-{midfix}-{origobjname}.[o|res]
2603e1051a39Sopenharmony_ci    # the {midfix} is a keyword indicating the type of product, which is mostly
2604e1051a39Sopenharmony_ci    # valuable for libraries since they come in two forms.
2605e1051a39Sopenharmony_ci    #
2606e1051a39Sopenharmony_ci    # This also reorganises the {sources} and {shared_sources} so that the
2607e1051a39Sopenharmony_ci    # former only contains ALL object files that are supposed to end up in
2608e1051a39Sopenharmony_ci    # static libraries and programs, while the latter contains ALL object files
2609e1051a39Sopenharmony_ci    # that are supposed to end up in shared libraries and DSOs.
2610e1051a39Sopenharmony_ci    # The main reason for having two different source structures is to allow
2611e1051a39Sopenharmony_ci    # the same name to be used for the static and the shared variants of a
2612e1051a39Sopenharmony_ci    # library.
2613e1051a39Sopenharmony_ci    {
2614e1051a39Sopenharmony_ci        # Take copies so we don't get interference from added stuff
2615e1051a39Sopenharmony_ci        my %unified_copy = ();
2616e1051a39Sopenharmony_ci        foreach (('sources', 'shared_sources')) {
2617e1051a39Sopenharmony_ci            $unified_copy{$_} = { %{$unified_info{$_}} }
2618e1051a39Sopenharmony_ci                if defined($unified_info{$_});
2619e1051a39Sopenharmony_ci            delete $unified_info{$_};
2620e1051a39Sopenharmony_ci        }
2621e1051a39Sopenharmony_ci        foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) {
2622e1051a39Sopenharmony_ci            # $intent serves multi purposes:
2623e1051a39Sopenharmony_ci            # - give a prefix for the new object files names
2624e1051a39Sopenharmony_ci            # - in the case of libraries, rearrange the object files so static
2625e1051a39Sopenharmony_ci            #   libraries use the 'sources' structure exclusively, while shared
2626e1051a39Sopenharmony_ci            #   libraries use the 'shared_sources' structure exclusively.
2627e1051a39Sopenharmony_ci            my $intent = {
2628e1051a39Sopenharmony_ci                programs  => { bin    => { src => [ 'sources' ],
2629e1051a39Sopenharmony_ci                                           dst => 'sources' } },
2630e1051a39Sopenharmony_ci                libraries => { lib    => { src => [ 'sources' ],
2631e1051a39Sopenharmony_ci                                           dst => 'sources' },
2632e1051a39Sopenharmony_ci                               shlib  => { prodselect =>
2633e1051a39Sopenharmony_ci                                               sub { grep !/\.a$/, @_ },
2634e1051a39Sopenharmony_ci                                           src => [ 'sources',
2635e1051a39Sopenharmony_ci                                                    'shared_sources' ],
2636e1051a39Sopenharmony_ci                                           dst => 'shared_sources' } },
2637e1051a39Sopenharmony_ci                modules   => { dso    => { src => [ 'sources' ],
2638e1051a39Sopenharmony_ci                                           dst => 'sources' } },
2639e1051a39Sopenharmony_ci                scripts   => { script => { src => [ 'sources' ],
2640e1051a39Sopenharmony_ci                                           dst => 'sources' } }
2641e1051a39Sopenharmony_ci               } -> {$prodtype};
2642e1051a39Sopenharmony_ci            foreach my $kind (keys %$intent) {
2643e1051a39Sopenharmony_ci                next if ($intent->{$kind}->{dst} eq 'shared_sources'
2644e1051a39Sopenharmony_ci                             && $disabled{shared});
2645e1051a39Sopenharmony_ci
2646e1051a39Sopenharmony_ci                my @src = @{$intent->{$kind}->{src}};
2647e1051a39Sopenharmony_ci                my $dst = $intent->{$kind}->{dst};
2648e1051a39Sopenharmony_ci                my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ };
2649e1051a39Sopenharmony_ci                foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) {
2650e1051a39Sopenharmony_ci                    # %prod_sources has all applicable objects as keys, and
2651e1051a39Sopenharmony_ci                    # their corresponding sources as values
2652e1051a39Sopenharmony_ci                    my %prod_sources =
2653e1051a39Sopenharmony_ci                        map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] }
2654e1051a39Sopenharmony_ci                        map { keys %{$unified_copy{$_}->{$prod}} }
2655e1051a39Sopenharmony_ci                        @src;
2656e1051a39Sopenharmony_ci                    foreach (keys %prod_sources) {
2657e1051a39Sopenharmony_ci                        # Only affect object files and resource files,
2658e1051a39Sopenharmony_ci                        # the others simply get a new value
2659e1051a39Sopenharmony_ci                        # (+1 instead of -1)
2660e1051a39Sopenharmony_ci                        if ($_ =~ /\.(o|res)$/) {
2661e1051a39Sopenharmony_ci                            (my $prodname = $prod) =~ s|\.a$||;
2662e1051a39Sopenharmony_ci                            my $newobj =
2663e1051a39Sopenharmony_ci                                catfile(dirname($_),
2664e1051a39Sopenharmony_ci                                        basename($prodname)
2665e1051a39Sopenharmony_ci                                            . '-' . $kind
2666e1051a39Sopenharmony_ci                                            . '-' . basename($_));
2667e1051a39Sopenharmony_ci                            $unified_info{$dst}->{$prod}->{$newobj} = 1;
2668e1051a39Sopenharmony_ci                            foreach my $src (@{$prod_sources{$_}}) {
2669e1051a39Sopenharmony_ci                                $unified_info{sources}->{$newobj}->{$src} = 1;
2670e1051a39Sopenharmony_ci                                # Adjust source attributes
2671e1051a39Sopenharmony_ci                                my $attrs = $unified_info{attributes}->{sources};
2672e1051a39Sopenharmony_ci                                if (defined $attrs->{$prod}
2673e1051a39Sopenharmony_ci                                    && defined $attrs->{$prod}->{$_}) {
2674e1051a39Sopenharmony_ci                                    $attrs->{$prod}->{$newobj} =
2675e1051a39Sopenharmony_ci                                        $attrs->{$prod}->{$_};
2676e1051a39Sopenharmony_ci                                    delete $attrs->{$prod}->{$_};
2677e1051a39Sopenharmony_ci                                }
2678e1051a39Sopenharmony_ci                                foreach my $objsrc (keys %{$attrs->{$_} // {}}) {
2679e1051a39Sopenharmony_ci                                    $attrs->{$newobj}->{$objsrc} =
2680e1051a39Sopenharmony_ci                                        $attrs->{$_}->{$objsrc};
2681e1051a39Sopenharmony_ci                                    delete $attrs->{$_}->{$objsrc};
2682e1051a39Sopenharmony_ci                                }
2683e1051a39Sopenharmony_ci                            }
2684e1051a39Sopenharmony_ci                            # Adjust dependencies
2685e1051a39Sopenharmony_ci                            foreach my $deps (keys %{$unified_info{depends}->{$_}}) {
2686e1051a39Sopenharmony_ci                                $unified_info{depends}->{$_}->{$deps} = -1;
2687e1051a39Sopenharmony_ci                                $unified_info{depends}->{$newobj}->{$deps} = 1;
2688e1051a39Sopenharmony_ci                            }
2689e1051a39Sopenharmony_ci                            # Adjust includes
2690e1051a39Sopenharmony_ci                            foreach my $k (('source', 'build')) {
2691e1051a39Sopenharmony_ci                                next unless
2692e1051a39Sopenharmony_ci                                    defined($unified_info{includes}->{$_}->{$k});
2693e1051a39Sopenharmony_ci                                my @incs = @{$unified_info{includes}->{$_}->{$k}};
2694e1051a39Sopenharmony_ci                                $unified_info{includes}->{$newobj}->{$k} = [ @incs ];
2695e1051a39Sopenharmony_ci                            }
2696e1051a39Sopenharmony_ci                        } else {
2697e1051a39Sopenharmony_ci                            $unified_info{$dst}->{$prod}->{$_} = 1;
2698e1051a39Sopenharmony_ci                        }
2699e1051a39Sopenharmony_ci                    }
2700e1051a39Sopenharmony_ci                }
2701e1051a39Sopenharmony_ci            }
2702e1051a39Sopenharmony_ci        }
2703e1051a39Sopenharmony_ci    }
2704e1051a39Sopenharmony_ci
2705e1051a39Sopenharmony_ci    # At this point, we have a number of sources with the value -1.  They
2706e1051a39Sopenharmony_ci    # aren't part of the local build and are probably meant for a different
2707e1051a39Sopenharmony_ci    # platform, and can therefore be cleaned away.  That happens when making
2708e1051a39Sopenharmony_ci    # %unified_info more efficient below.
2709e1051a39Sopenharmony_ci
2710e1051a39Sopenharmony_ci    ### Make unified_info a bit more efficient
2711e1051a39Sopenharmony_ci    # One level structures
2712e1051a39Sopenharmony_ci    foreach (("programs", "libraries", "modules", "scripts", "targets")) {
2713e1051a39Sopenharmony_ci        $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
2714e1051a39Sopenharmony_ci    }
2715e1051a39Sopenharmony_ci    # Two level structures
2716e1051a39Sopenharmony_ci    foreach my $l1 (("sources", "shared_sources", "ldadd", "depends",
2717e1051a39Sopenharmony_ci                     "imagedocs", "htmldocs", "mandocs")) {
2718e1051a39Sopenharmony_ci        foreach my $l2 (sort keys %{$unified_info{$l1}}) {
2719e1051a39Sopenharmony_ci            my @items =
2720e1051a39Sopenharmony_ci                sort
2721e1051a39Sopenharmony_ci                grep { $unified_info{$l1}->{$l2}->{$_} > 0 }
2722e1051a39Sopenharmony_ci                keys %{$unified_info{$l1}->{$l2}};
2723e1051a39Sopenharmony_ci            if (@items) {
2724e1051a39Sopenharmony_ci                $unified_info{$l1}->{$l2} = [ @items ];
2725e1051a39Sopenharmony_ci            } else {
2726e1051a39Sopenharmony_ci                delete $unified_info{$l1}->{$l2};
2727e1051a39Sopenharmony_ci            }
2728e1051a39Sopenharmony_ci        }
2729e1051a39Sopenharmony_ci    }
2730e1051a39Sopenharmony_ci    # Defines
2731e1051a39Sopenharmony_ci    foreach my $dest (sort keys %{$unified_info{defines}}) {
2732e1051a39Sopenharmony_ci        $unified_info{defines}->{$dest}
2733e1051a39Sopenharmony_ci            = [ map { $_.$unified_info{defines}->{$dest}->{$_} }
2734e1051a39Sopenharmony_ci                sort keys %{$unified_info{defines}->{$dest}} ];
2735e1051a39Sopenharmony_ci    }
2736e1051a39Sopenharmony_ci    # Includes
2737e1051a39Sopenharmony_ci    foreach my $dest (sort keys %{$unified_info{includes}}) {
2738e1051a39Sopenharmony_ci        if (defined($unified_info{includes}->{$dest}->{build})) {
2739e1051a39Sopenharmony_ci            my @source_includes = ();
2740e1051a39Sopenharmony_ci            @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} )
2741e1051a39Sopenharmony_ci                if defined($unified_info{includes}->{$dest}->{source});
2742e1051a39Sopenharmony_ci            $unified_info{includes}->{$dest} =
2743e1051a39Sopenharmony_ci                [ @{$unified_info{includes}->{$dest}->{build}} ];
2744e1051a39Sopenharmony_ci            foreach my $inc (@source_includes) {
2745e1051a39Sopenharmony_ci                push @{$unified_info{includes}->{$dest}}, $inc
2746e1051a39Sopenharmony_ci                    unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
2747e1051a39Sopenharmony_ci            }
2748e1051a39Sopenharmony_ci        } elsif (defined($unified_info{includes}->{$dest}->{source})) {
2749e1051a39Sopenharmony_ci            $unified_info{includes}->{$dest} =
2750e1051a39Sopenharmony_ci                [ @{$unified_info{includes}->{$dest}->{source}} ];
2751e1051a39Sopenharmony_ci        } else {
2752e1051a39Sopenharmony_ci            delete $unified_info{includes}->{$dest};
2753e1051a39Sopenharmony_ci        }
2754e1051a39Sopenharmony_ci    }
2755e1051a39Sopenharmony_ci
2756e1051a39Sopenharmony_ci    # For convenience collect information regarding directories where
2757e1051a39Sopenharmony_ci    # files are generated, those generated files and the end product
2758e1051a39Sopenharmony_ci    # they end up in where applicable.  Then, add build rules for those
2759e1051a39Sopenharmony_ci    # directories
2760e1051a39Sopenharmony_ci    my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ],
2761e1051a39Sopenharmony_ci                     "dso" => [ @{$unified_info{modules}} ],
2762e1051a39Sopenharmony_ci                     "bin" => [ @{$unified_info{programs}} ],
2763e1051a39Sopenharmony_ci                     "script" => [ @{$unified_info{scripts}} ],
2764e1051a39Sopenharmony_ci                     "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} }
2765e1051a39Sopenharmony_ci                                  keys %{$unified_info{imagedocs} // {}}),
2766e1051a39Sopenharmony_ci                                 (map { @{$unified_info{htmldocs}->{$_} // []} }
2767e1051a39Sopenharmony_ci                                  keys %{$unified_info{htmldocs} // {}}),
2768e1051a39Sopenharmony_ci                                 (map { @{$unified_info{mandocs}->{$_} // []} }
2769e1051a39Sopenharmony_ci                                  keys %{$unified_info{mandocs} // {}}) ] );
2770e1051a39Sopenharmony_ci    foreach my $type (sort keys %loopinfo) {
2771e1051a39Sopenharmony_ci        foreach my $product (@{$loopinfo{$type}}) {
2772e1051a39Sopenharmony_ci            my %dirs = ();
2773e1051a39Sopenharmony_ci            my $pd = dirname($product);
2774e1051a39Sopenharmony_ci
2775e1051a39Sopenharmony_ci            foreach (@{$unified_info{sources}->{$product} // []},
2776e1051a39Sopenharmony_ci                     @{$unified_info{shared_sources}->{$product} // []}) {
2777e1051a39Sopenharmony_ci                my $d = dirname($_);
2778e1051a39Sopenharmony_ci
2779e1051a39Sopenharmony_ci                # We don't want to create targets for source directories
2780e1051a39Sopenharmony_ci                # when building out of source
2781e1051a39Sopenharmony_ci                next if ($config{sourcedir} ne $config{builddir}
2782e1051a39Sopenharmony_ci                             && $d =~ m|^\Q$config{sourcedir}\E|);
2783e1051a39Sopenharmony_ci                # We already have a "test" target, and the current directory
2784e1051a39Sopenharmony_ci                # is just silly to make a target for
2785e1051a39Sopenharmony_ci                next if $d eq "test" || $d eq ".";
2786e1051a39Sopenharmony_ci
2787e1051a39Sopenharmony_ci                $dirs{$d} = 1;
2788e1051a39Sopenharmony_ci                push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
2789e1051a39Sopenharmony_ci                    if $d ne $pd;
2790e1051a39Sopenharmony_ci            }
2791e1051a39Sopenharmony_ci            foreach (sort keys %dirs) {
2792e1051a39Sopenharmony_ci                push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
2793e1051a39Sopenharmony_ci                    $product;
2794e1051a39Sopenharmony_ci            }
2795e1051a39Sopenharmony_ci        }
2796e1051a39Sopenharmony_ci    }
2797e1051a39Sopenharmony_ci}
2798e1051a39Sopenharmony_ci
2799e1051a39Sopenharmony_ci# For the schemes that need it, we provide the old *_obj configs
2800e1051a39Sopenharmony_ci# from the *_asm_obj ones
2801e1051a39Sopenharmony_ciforeach (grep /_(asm|aux)_src$/, keys %target) {
2802e1051a39Sopenharmony_ci    my $src = $_;
2803e1051a39Sopenharmony_ci    (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
2804e1051a39Sopenharmony_ci    $target{$obj} = $target{$src};
2805e1051a39Sopenharmony_ci    $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
2806e1051a39Sopenharmony_ci    $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
2807e1051a39Sopenharmony_ci}
2808e1051a39Sopenharmony_ci
2809e1051a39Sopenharmony_ci# Write down our configuration where it fits #########################
2810e1051a39Sopenharmony_ci
2811e1051a39Sopenharmony_cimy %template_vars = (
2812e1051a39Sopenharmony_ci    config => \%config,
2813e1051a39Sopenharmony_ci    target => \%target,
2814e1051a39Sopenharmony_ci    disablables => \@disablables,
2815e1051a39Sopenharmony_ci    disablables_int => \@disablables_int,
2816e1051a39Sopenharmony_ci    disabled => \%disabled,
2817e1051a39Sopenharmony_ci    withargs => \%withargs,
2818e1051a39Sopenharmony_ci    unified_info => \%unified_info,
2819e1051a39Sopenharmony_ci    tls => \@tls,
2820e1051a39Sopenharmony_ci    dtls => \@dtls,
2821e1051a39Sopenharmony_ci    makevars => [ sort keys %user ],
2822e1051a39Sopenharmony_ci    disabled_info => \%disabled_info,
2823e1051a39Sopenharmony_ci    user_crossable => \@user_crossable,
2824e1051a39Sopenharmony_ci);
2825e1051a39Sopenharmony_cimy $configdata_outname = 'configdata.pm';
2826e1051a39Sopenharmony_ciopen CONFIGDATA, ">$configdata_outname.new"
2827e1051a39Sopenharmony_ci    or die "Trying to create $configdata_outname.new: $!";
2828e1051a39Sopenharmony_cimy $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir);
2829e1051a39Sopenharmony_cimy $configdata_tmpl =
2830e1051a39Sopenharmony_ci    OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname);
2831e1051a39Sopenharmony_ci$configdata_tmpl->fill_in(
2832e1051a39Sopenharmony_ci    FILENAME => $configdata_tmplname,
2833e1051a39Sopenharmony_ci    OUTPUT => \*CONFIGDATA,
2834e1051a39Sopenharmony_ci    HASH => { %template_vars,
2835e1051a39Sopenharmony_ci              autowarntext => [
2836e1051a39Sopenharmony_ci                  'WARNING: do not edit!',
2837e1051a39Sopenharmony_ci                  "Generated by Configure from $configdata_tmplname",
2838e1051a39Sopenharmony_ci              ] }
2839e1051a39Sopenharmony_ci) or die $Text::Template::ERROR;
2840e1051a39Sopenharmony_ciclose CONFIGDATA;
2841e1051a39Sopenharmony_ci
2842e1051a39Sopenharmony_cirename "$configdata_outname.new", $configdata_outname;
2843e1051a39Sopenharmony_ciif ($builder_platform eq 'unix') {
2844e1051a39Sopenharmony_ci    my $mode = (0755 & ~umask);
2845e1051a39Sopenharmony_ci    chmod $mode, 'configdata.pm'
2846e1051a39Sopenharmony_ci        or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!);
2847e1051a39Sopenharmony_ci}
2848e1051a39Sopenharmony_ciprint "Created $configdata_outname\n";
2849e1051a39Sopenharmony_ci
2850e1051a39Sopenharmony_ciprint "Running $configdata_outname\n";
2851e1051a39Sopenharmony_cimy $perlcmd = (quotify("maybeshell", $config{PERL}))[0];
2852e1051a39Sopenharmony_cimy $cmd = "$perlcmd $configdata_outname";
2853e1051a39Sopenharmony_ci#print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2854e1051a39Sopenharmony_cisystem($cmd);
2855e1051a39Sopenharmony_ciexit 1 if $? != 0;
2856e1051a39Sopenharmony_ci
2857e1051a39Sopenharmony_ci$SIG{__DIE__} = $orig_death_handler;
2858e1051a39Sopenharmony_ci
2859e1051a39Sopenharmony_ciprint <<"EOF" if ($disabled{threads} eq "unavailable");
2860e1051a39Sopenharmony_ci
2861e1051a39Sopenharmony_ciThe library could not be configured for supporting multi-threaded
2862e1051a39Sopenharmony_ciapplications as the compiler options required on this system are not known.
2863e1051a39Sopenharmony_ciSee file INSTALL.md for details if you need multi-threading.
2864e1051a39Sopenharmony_ciEOF
2865e1051a39Sopenharmony_ci
2866e1051a39Sopenharmony_ciprint <<"EOF" if ($no_shared_warn);
2867e1051a39Sopenharmony_ci
2868e1051a39Sopenharmony_ciThe options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2869e1051a39Sopenharmony_ciplatform, so we will pretend you gave the option 'no-pic', which also disables
2870e1051a39Sopenharmony_ci'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
2871e1051a39Sopenharmony_cior position independent code, please let us know (but please first make sure
2872e1051a39Sopenharmony_ciyou have tried with a current version of OpenSSL).
2873e1051a39Sopenharmony_ciEOF
2874e1051a39Sopenharmony_ci
2875e1051a39Sopenharmony_ciprint $banner;
2876e1051a39Sopenharmony_ci
2877e1051a39Sopenharmony_ciexit(0);
2878e1051a39Sopenharmony_ci
2879e1051a39Sopenharmony_ci######################################################################
2880e1051a39Sopenharmony_ci#
2881e1051a39Sopenharmony_ci# Helpers and utility functions
2882e1051a39Sopenharmony_ci#
2883e1051a39Sopenharmony_ci
2884e1051a39Sopenharmony_ci# Death handler, to print a helpful message in case of failure #######
2885e1051a39Sopenharmony_ci#
2886e1051a39Sopenharmony_cisub death_handler {
2887e1051a39Sopenharmony_ci    die @_ if $^S;              # To prevent the added message in eval blocks
2888e1051a39Sopenharmony_ci    my $build_file = $config{build_file} // "build file";
2889e1051a39Sopenharmony_ci    my @message = ( <<"_____", @_ );
2890e1051a39Sopenharmony_ci
2891e1051a39Sopenharmony_ciFailure!  $build_file wasn't produced.
2892e1051a39Sopenharmony_ciPlease read INSTALL.md and associated NOTES-* files.  You may also have to
2893e1051a39Sopenharmony_cilook over your available compiler tool chain or change your configuration.
2894e1051a39Sopenharmony_ci
2895e1051a39Sopenharmony_ci_____
2896e1051a39Sopenharmony_ci
2897e1051a39Sopenharmony_ci    # Dying is terminal, so it's ok to reset the signal handler here.
2898e1051a39Sopenharmony_ci    $SIG{__DIE__} = $orig_death_handler;
2899e1051a39Sopenharmony_ci    die @message;
2900e1051a39Sopenharmony_ci}
2901e1051a39Sopenharmony_ci
2902e1051a39Sopenharmony_ci# Configuration file reading #########################################
2903e1051a39Sopenharmony_ci
2904e1051a39Sopenharmony_ci# Note: All of the helper functions are for lazy evaluation.  They all
2905e1051a39Sopenharmony_ci# return a CODE ref, which will return the intended value when evaluated.
2906e1051a39Sopenharmony_ci# Thus, whenever there's mention of a returned value, it's about that
2907e1051a39Sopenharmony_ci# intended value.
2908e1051a39Sopenharmony_ci
2909e1051a39Sopenharmony_ci# Helper function to implement conditional value variants, with a default
2910e1051a39Sopenharmony_ci# plus additional values based on the value of $config{build_type}.
2911e1051a39Sopenharmony_ci# Arguments are given in hash table form:
2912e1051a39Sopenharmony_ci#
2913e1051a39Sopenharmony_ci#       picker(default => "Basic string: ",
2914e1051a39Sopenharmony_ci#              debug   => "debug",
2915e1051a39Sopenharmony_ci#              release => "release")
2916e1051a39Sopenharmony_ci#
2917e1051a39Sopenharmony_ci# When configuring with --debug, the resulting string will be
2918e1051a39Sopenharmony_ci# "Basic string: debug", and when not, it will be "Basic string: release"
2919e1051a39Sopenharmony_ci#
2920e1051a39Sopenharmony_ci# This can be used to create variants of sets of flags according to the
2921e1051a39Sopenharmony_ci# build type:
2922e1051a39Sopenharmony_ci#
2923e1051a39Sopenharmony_ci#       cflags => picker(default => "-Wall",
2924e1051a39Sopenharmony_ci#                        debug   => "-g -O0",
2925e1051a39Sopenharmony_ci#                        release => "-O3")
2926e1051a39Sopenharmony_ci#
2927e1051a39Sopenharmony_cisub picker {
2928e1051a39Sopenharmony_ci    my %opts = @_;
2929e1051a39Sopenharmony_ci    return sub { add($opts{default} || (),
2930e1051a39Sopenharmony_ci                     $opts{$config{build_type}} || ())->(); }
2931e1051a39Sopenharmony_ci}
2932e1051a39Sopenharmony_ci
2933e1051a39Sopenharmony_ci# Helper function to combine several values of different types into one.
2934e1051a39Sopenharmony_ci# This is useful if you want to combine a string with the result of a
2935e1051a39Sopenharmony_ci# lazy function, such as:
2936e1051a39Sopenharmony_ci#
2937e1051a39Sopenharmony_ci#       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2938e1051a39Sopenharmony_ci#
2939e1051a39Sopenharmony_cisub combine {
2940e1051a39Sopenharmony_ci    my @stuff = @_;
2941e1051a39Sopenharmony_ci    return sub { add(@stuff)->(); }
2942e1051a39Sopenharmony_ci}
2943e1051a39Sopenharmony_ci
2944e1051a39Sopenharmony_ci# Helper function to implement conditional values depending on the value
2945e1051a39Sopenharmony_ci# of $disabled{threads}.  Can be used as follows:
2946e1051a39Sopenharmony_ci#
2947e1051a39Sopenharmony_ci#       cflags => combine("-Wall", threads("-pthread"))
2948e1051a39Sopenharmony_ci#
2949e1051a39Sopenharmony_cisub threads {
2950e1051a39Sopenharmony_ci    my @flags = @_;
2951e1051a39Sopenharmony_ci    return sub { add($disabled{threads} ? () : @flags)->(); }
2952e1051a39Sopenharmony_ci}
2953e1051a39Sopenharmony_ci
2954e1051a39Sopenharmony_cisub shared {
2955e1051a39Sopenharmony_ci    my @flags = @_;
2956e1051a39Sopenharmony_ci    return sub { add($disabled{shared} ? () : @flags)->(); }
2957e1051a39Sopenharmony_ci}
2958e1051a39Sopenharmony_ci
2959e1051a39Sopenharmony_ciour $add_called = 0;
2960e1051a39Sopenharmony_ci# Helper function to implement adding values to already existing configuration
2961e1051a39Sopenharmony_ci# values.  It handles elements that are ARRAYs, CODEs and scalars
2962e1051a39Sopenharmony_cisub _add {
2963e1051a39Sopenharmony_ci    my $separator = shift;
2964e1051a39Sopenharmony_ci
2965e1051a39Sopenharmony_ci    # If there's any ARRAY in the collection of values OR the separator
2966e1051a39Sopenharmony_ci    # is undef, we will return an ARRAY of combined values, otherwise a
2967e1051a39Sopenharmony_ci    # string of joined values with $separator as the separator.
2968e1051a39Sopenharmony_ci    my $found_array = !defined($separator);
2969e1051a39Sopenharmony_ci
2970e1051a39Sopenharmony_ci    my @values =
2971e1051a39Sopenharmony_ci        map {
2972e1051a39Sopenharmony_ci            my $res = $_;
2973e1051a39Sopenharmony_ci            while (ref($res) eq "CODE") {
2974e1051a39Sopenharmony_ci                $res = $res->();
2975e1051a39Sopenharmony_ci            }
2976e1051a39Sopenharmony_ci            if (defined($res)) {
2977e1051a39Sopenharmony_ci                if (ref($res) eq "ARRAY") {
2978e1051a39Sopenharmony_ci                    $found_array = 1;
2979e1051a39Sopenharmony_ci                    @$res;
2980e1051a39Sopenharmony_ci                } else {
2981e1051a39Sopenharmony_ci                    $res;
2982e1051a39Sopenharmony_ci                }
2983e1051a39Sopenharmony_ci            } else {
2984e1051a39Sopenharmony_ci                ();
2985e1051a39Sopenharmony_ci            }
2986e1051a39Sopenharmony_ci    } (@_);
2987e1051a39Sopenharmony_ci
2988e1051a39Sopenharmony_ci    $add_called = 1;
2989e1051a39Sopenharmony_ci
2990e1051a39Sopenharmony_ci    if ($found_array) {
2991e1051a39Sopenharmony_ci        [ @values ];
2992e1051a39Sopenharmony_ci    } else {
2993e1051a39Sopenharmony_ci        join($separator, grep { defined($_) && $_ ne "" } @values);
2994e1051a39Sopenharmony_ci    }
2995e1051a39Sopenharmony_ci}
2996e1051a39Sopenharmony_cisub add_before {
2997e1051a39Sopenharmony_ci    my $separator = " ";
2998e1051a39Sopenharmony_ci    if (ref($_[$#_]) eq "HASH") {
2999e1051a39Sopenharmony_ci        my $opts = pop;
3000e1051a39Sopenharmony_ci        $separator = $opts->{separator};
3001e1051a39Sopenharmony_ci    }
3002e1051a39Sopenharmony_ci    my @x = @_;
3003e1051a39Sopenharmony_ci    sub { _add($separator, @x, @_) };
3004e1051a39Sopenharmony_ci}
3005e1051a39Sopenharmony_cisub add {
3006e1051a39Sopenharmony_ci    my $separator = " ";
3007e1051a39Sopenharmony_ci    if (ref($_[$#_]) eq "HASH") {
3008e1051a39Sopenharmony_ci        my $opts = pop;
3009e1051a39Sopenharmony_ci        $separator = $opts->{separator};
3010e1051a39Sopenharmony_ci    }
3011e1051a39Sopenharmony_ci    my @x = @_;
3012e1051a39Sopenharmony_ci    sub { _add($separator, @_, @x) };
3013e1051a39Sopenharmony_ci}
3014e1051a39Sopenharmony_ci
3015e1051a39Sopenharmony_cisub read_eval_file {
3016e1051a39Sopenharmony_ci    my $fname = shift;
3017e1051a39Sopenharmony_ci    my $content;
3018e1051a39Sopenharmony_ci    my @result;
3019e1051a39Sopenharmony_ci
3020e1051a39Sopenharmony_ci    open F, "< $fname" or die "Can't open '$fname': $!\n";
3021e1051a39Sopenharmony_ci    {
3022e1051a39Sopenharmony_ci        undef local $/;
3023e1051a39Sopenharmony_ci        $content = <F>;
3024e1051a39Sopenharmony_ci    }
3025e1051a39Sopenharmony_ci    close F;
3026e1051a39Sopenharmony_ci    {
3027e1051a39Sopenharmony_ci        local $@;
3028e1051a39Sopenharmony_ci
3029e1051a39Sopenharmony_ci        @result = ( eval $content );
3030e1051a39Sopenharmony_ci        warn $@ if $@;
3031e1051a39Sopenharmony_ci    }
3032e1051a39Sopenharmony_ci    return wantarray ? @result : $result[0];
3033e1051a39Sopenharmony_ci}
3034e1051a39Sopenharmony_ci
3035e1051a39Sopenharmony_ci# configuration reader, evaluates the input file as a perl script and expects
3036e1051a39Sopenharmony_ci# it to fill %targets with target configurations.  Those are then added to
3037e1051a39Sopenharmony_ci# %table.
3038e1051a39Sopenharmony_cisub read_config {
3039e1051a39Sopenharmony_ci    my $fname = shift;
3040e1051a39Sopenharmony_ci    my %targets;
3041e1051a39Sopenharmony_ci
3042e1051a39Sopenharmony_ci    {
3043e1051a39Sopenharmony_ci        # Protect certain tables from tampering
3044e1051a39Sopenharmony_ci        local %table = ();
3045e1051a39Sopenharmony_ci
3046e1051a39Sopenharmony_ci        %targets = read_eval_file($fname);
3047e1051a39Sopenharmony_ci    }
3048e1051a39Sopenharmony_ci    my %preexisting = ();
3049e1051a39Sopenharmony_ci    foreach (sort keys %targets) {
3050e1051a39Sopenharmony_ci        $preexisting{$_} = 1 if $table{$_};
3051e1051a39Sopenharmony_ci    }
3052e1051a39Sopenharmony_ci    die <<"EOF",
3053e1051a39Sopenharmony_ciThe following config targets from $fname
3054e1051a39Sopenharmony_cishadow pre-existing config targets with the same name:
3055e1051a39Sopenharmony_ciEOF
3056e1051a39Sopenharmony_ci        map { "  $_\n" } sort keys %preexisting
3057e1051a39Sopenharmony_ci        if %preexisting;
3058e1051a39Sopenharmony_ci
3059e1051a39Sopenharmony_ci
3060e1051a39Sopenharmony_ci    # For each target, check that it's configured with a hash table.
3061e1051a39Sopenharmony_ci    foreach (keys %targets) {
3062e1051a39Sopenharmony_ci        if (ref($targets{$_}) ne "HASH") {
3063e1051a39Sopenharmony_ci            if (ref($targets{$_}) eq "") {
3064e1051a39Sopenharmony_ci                warn "Deprecated target configuration for $_, ignoring...\n";
3065e1051a39Sopenharmony_ci            } else {
3066e1051a39Sopenharmony_ci                warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
3067e1051a39Sopenharmony_ci            }
3068e1051a39Sopenharmony_ci            delete $targets{$_};
3069e1051a39Sopenharmony_ci        } else {
3070e1051a39Sopenharmony_ci            $targets{$_}->{_conf_fname_int} = add([ $fname ]);
3071e1051a39Sopenharmony_ci        }
3072e1051a39Sopenharmony_ci    }
3073e1051a39Sopenharmony_ci
3074e1051a39Sopenharmony_ci    %table = (%table, %targets);
3075e1051a39Sopenharmony_ci
3076e1051a39Sopenharmony_ci}
3077e1051a39Sopenharmony_ci
3078e1051a39Sopenharmony_ci# configuration resolver.  Will only resolve all the lazy evaluation
3079e1051a39Sopenharmony_ci# codeblocks for the chosen target and all those it inherits from,
3080e1051a39Sopenharmony_ci# recursively
3081e1051a39Sopenharmony_cisub resolve_config {
3082e1051a39Sopenharmony_ci    my $target = shift;
3083e1051a39Sopenharmony_ci    my @breadcrumbs = @_;
3084e1051a39Sopenharmony_ci
3085e1051a39Sopenharmony_ci#    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
3086e1051a39Sopenharmony_ci
3087e1051a39Sopenharmony_ci    if (grep { $_ eq $target } @breadcrumbs) {
3088e1051a39Sopenharmony_ci        die "inherit_from loop!  target backtrace:\n  "
3089e1051a39Sopenharmony_ci            ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
3090e1051a39Sopenharmony_ci    }
3091e1051a39Sopenharmony_ci
3092e1051a39Sopenharmony_ci    if (!defined($table{$target})) {
3093e1051a39Sopenharmony_ci        warn "Warning! target $target doesn't exist!\n";
3094e1051a39Sopenharmony_ci        return ();
3095e1051a39Sopenharmony_ci    }
3096e1051a39Sopenharmony_ci    # Recurse through all inheritances.  They will be resolved on the
3097e1051a39Sopenharmony_ci    # fly, so when this operation is done, they will all just be a
3098e1051a39Sopenharmony_ci    # bunch of attributes with string values.
3099e1051a39Sopenharmony_ci    # What we get here, though, are keys with references to lists of
3100e1051a39Sopenharmony_ci    # the combined values of them all.  We will deal with lists after
3101e1051a39Sopenharmony_ci    # this stage is done.
3102e1051a39Sopenharmony_ci    my %combined_inheritance = ();
3103e1051a39Sopenharmony_ci    if ($table{$target}->{inherit_from}) {
3104e1051a39Sopenharmony_ci        my @inherit_from =
3105e1051a39Sopenharmony_ci            map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
3106e1051a39Sopenharmony_ci        foreach (@inherit_from) {
3107e1051a39Sopenharmony_ci            my %inherited_config = resolve_config($_, $target, @breadcrumbs);
3108e1051a39Sopenharmony_ci
3109e1051a39Sopenharmony_ci            # 'template' is a marker that's considered private to
3110e1051a39Sopenharmony_ci            # the config that had it.
3111e1051a39Sopenharmony_ci            delete $inherited_config{template};
3112e1051a39Sopenharmony_ci
3113e1051a39Sopenharmony_ci            foreach (keys %inherited_config) {
3114e1051a39Sopenharmony_ci                if (!$combined_inheritance{$_}) {
3115e1051a39Sopenharmony_ci                    $combined_inheritance{$_} = [];
3116e1051a39Sopenharmony_ci                }
3117e1051a39Sopenharmony_ci                push @{$combined_inheritance{$_}}, $inherited_config{$_};
3118e1051a39Sopenharmony_ci            }
3119e1051a39Sopenharmony_ci        }
3120e1051a39Sopenharmony_ci    }
3121e1051a39Sopenharmony_ci
3122e1051a39Sopenharmony_ci    # We won't need inherit_from in this target any more, since we've
3123e1051a39Sopenharmony_ci    # resolved all the inheritances that lead to this
3124e1051a39Sopenharmony_ci    delete $table{$target}->{inherit_from};
3125e1051a39Sopenharmony_ci
3126e1051a39Sopenharmony_ci    # Now is the time to deal with those lists.  Here's the place to
3127e1051a39Sopenharmony_ci    # decide what shall be done with those lists, all based on the
3128e1051a39Sopenharmony_ci    # values of the target we're currently dealing with.
3129e1051a39Sopenharmony_ci    # - If a value is a coderef, it will be executed with the list of
3130e1051a39Sopenharmony_ci    #   inherited values as arguments.
3131e1051a39Sopenharmony_ci    # - If the corresponding key doesn't have a value at all or is the
3132e1051a39Sopenharmony_ci    #   empty string, the inherited value list will be run through the
3133e1051a39Sopenharmony_ci    #   default combiner (below), and the result becomes this target's
3134e1051a39Sopenharmony_ci    #   value.
3135e1051a39Sopenharmony_ci    # - Otherwise, this target's value is assumed to be a string that
3136e1051a39Sopenharmony_ci    #   will simply override the inherited list of values.
3137e1051a39Sopenharmony_ci    my $default_combiner = add();
3138e1051a39Sopenharmony_ci
3139e1051a39Sopenharmony_ci    my %all_keys =
3140e1051a39Sopenharmony_ci        map { $_ => 1 } (keys %combined_inheritance,
3141e1051a39Sopenharmony_ci                         keys %{$table{$target}});
3142e1051a39Sopenharmony_ci
3143e1051a39Sopenharmony_ci    sub process_values {
3144e1051a39Sopenharmony_ci        my $object    = shift;
3145e1051a39Sopenharmony_ci        my $inherited = shift;  # Always a [ list ]
3146e1051a39Sopenharmony_ci        my $target    = shift;
3147e1051a39Sopenharmony_ci        my $entry     = shift;
3148e1051a39Sopenharmony_ci
3149e1051a39Sopenharmony_ci        $add_called = 0;
3150e1051a39Sopenharmony_ci
3151e1051a39Sopenharmony_ci        while(ref($object) eq "CODE") {
3152e1051a39Sopenharmony_ci            $object = $object->(@$inherited);
3153e1051a39Sopenharmony_ci        }
3154e1051a39Sopenharmony_ci        if (!defined($object)) {
3155e1051a39Sopenharmony_ci            return ();
3156e1051a39Sopenharmony_ci        }
3157e1051a39Sopenharmony_ci        elsif (ref($object) eq "ARRAY") {
3158e1051a39Sopenharmony_ci            local $add_called;  # To make sure recursive calls don't affect it
3159e1051a39Sopenharmony_ci            return [ map { process_values($_, $inherited, $target, $entry) }
3160e1051a39Sopenharmony_ci                     @$object ];
3161e1051a39Sopenharmony_ci        } elsif (ref($object) eq "") {
3162e1051a39Sopenharmony_ci            return $object;
3163e1051a39Sopenharmony_ci        } else {
3164e1051a39Sopenharmony_ci            die "cannot handle reference type ",ref($object)
3165e1051a39Sopenharmony_ci                ," found in target ",$target," -> ",$entry,"\n";
3166e1051a39Sopenharmony_ci        }
3167e1051a39Sopenharmony_ci    }
3168e1051a39Sopenharmony_ci
3169e1051a39Sopenharmony_ci    foreach my $key (sort keys %all_keys) {
3170e1051a39Sopenharmony_ci        my $previous = $combined_inheritance{$key};
3171e1051a39Sopenharmony_ci
3172e1051a39Sopenharmony_ci        # Current target doesn't have a value for the current key?
3173e1051a39Sopenharmony_ci        # Assign it the default combiner, the rest of this loop body
3174e1051a39Sopenharmony_ci        # will handle it just like any other coderef.
3175e1051a39Sopenharmony_ci        if (!exists $table{$target}->{$key}) {
3176e1051a39Sopenharmony_ci            $table{$target}->{$key} = $default_combiner;
3177e1051a39Sopenharmony_ci        }
3178e1051a39Sopenharmony_ci
3179e1051a39Sopenharmony_ci        $table{$target}->{$key} = process_values($table{$target}->{$key},
3180e1051a39Sopenharmony_ci                                               $combined_inheritance{$key},
3181e1051a39Sopenharmony_ci                                               $target, $key);
3182e1051a39Sopenharmony_ci        unless(defined($table{$target}->{$key})) {
3183e1051a39Sopenharmony_ci            delete $table{$target}->{$key};
3184e1051a39Sopenharmony_ci        }
3185e1051a39Sopenharmony_ci#        if ($extra_checks &&
3186e1051a39Sopenharmony_ci#            $previous && !($add_called ||  $previous ~~ $table{$target}->{$key})) {
3187e1051a39Sopenharmony_ci#            warn "$key got replaced in $target\n";
3188e1051a39Sopenharmony_ci#        }
3189e1051a39Sopenharmony_ci    }
3190e1051a39Sopenharmony_ci
3191e1051a39Sopenharmony_ci    # Finally done, return the result.
3192e1051a39Sopenharmony_ci    return %{$table{$target}};
3193e1051a39Sopenharmony_ci}
3194e1051a39Sopenharmony_ci
3195e1051a39Sopenharmony_cisub usage
3196e1051a39Sopenharmony_ci        {
3197e1051a39Sopenharmony_ci        print STDERR $usage;
3198e1051a39Sopenharmony_ci        print STDERR "\npick os/compiler from:\n";
3199e1051a39Sopenharmony_ci        my $j=0;
3200e1051a39Sopenharmony_ci        my $i;
3201e1051a39Sopenharmony_ci        my $k=0;
3202e1051a39Sopenharmony_ci        foreach $i (sort keys %table)
3203e1051a39Sopenharmony_ci                {
3204e1051a39Sopenharmony_ci                next if $table{$i}->{template};
3205e1051a39Sopenharmony_ci                next if $i =~ /^debug/;
3206e1051a39Sopenharmony_ci                $k += length($i) + 1;
3207e1051a39Sopenharmony_ci                if ($k > 78)
3208e1051a39Sopenharmony_ci                        {
3209e1051a39Sopenharmony_ci                        print STDERR "\n";
3210e1051a39Sopenharmony_ci                        $k=length($i);
3211e1051a39Sopenharmony_ci                        }
3212e1051a39Sopenharmony_ci                print STDERR $i . " ";
3213e1051a39Sopenharmony_ci                }
3214e1051a39Sopenharmony_ci        foreach $i (sort keys %table)
3215e1051a39Sopenharmony_ci                {
3216e1051a39Sopenharmony_ci                next if $table{$i}->{template};
3217e1051a39Sopenharmony_ci                next if $i !~ /^debug/;
3218e1051a39Sopenharmony_ci                $k += length($i) + 1;
3219e1051a39Sopenharmony_ci                if ($k > 78)
3220e1051a39Sopenharmony_ci                        {
3221e1051a39Sopenharmony_ci                        print STDERR "\n";
3222e1051a39Sopenharmony_ci                        $k=length($i);
3223e1051a39Sopenharmony_ci                        }
3224e1051a39Sopenharmony_ci                print STDERR $i . " ";
3225e1051a39Sopenharmony_ci                }
3226e1051a39Sopenharmony_ci        exit(1);
3227e1051a39Sopenharmony_ci        }
3228e1051a39Sopenharmony_ci
3229e1051a39Sopenharmony_cisub compiler_predefined {
3230e1051a39Sopenharmony_ci    state %predefined;
3231e1051a39Sopenharmony_ci    my $cc = shift;
3232e1051a39Sopenharmony_ci
3233e1051a39Sopenharmony_ci    return () if $^O eq 'VMS';
3234e1051a39Sopenharmony_ci
3235e1051a39Sopenharmony_ci    die 'compiler_predefined called without a compiler command'
3236e1051a39Sopenharmony_ci        unless $cc;
3237e1051a39Sopenharmony_ci
3238e1051a39Sopenharmony_ci    if (! $predefined{$cc}) {
3239e1051a39Sopenharmony_ci
3240e1051a39Sopenharmony_ci        $predefined{$cc} = {};
3241e1051a39Sopenharmony_ci
3242e1051a39Sopenharmony_ci        # collect compiler pre-defines from gcc or gcc-alike...
3243e1051a39Sopenharmony_ci        open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
3244e1051a39Sopenharmony_ci        while (my $l = <PIPE>) {
3245e1051a39Sopenharmony_ci            $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
3246e1051a39Sopenharmony_ci            $predefined{$cc}->{$1} = $2 // '';
3247e1051a39Sopenharmony_ci        }
3248e1051a39Sopenharmony_ci        close(PIPE);
3249e1051a39Sopenharmony_ci    }
3250e1051a39Sopenharmony_ci
3251e1051a39Sopenharmony_ci    return %{$predefined{$cc}};
3252e1051a39Sopenharmony_ci}
3253e1051a39Sopenharmony_ci
3254e1051a39Sopenharmony_cisub which
3255e1051a39Sopenharmony_ci{
3256e1051a39Sopenharmony_ci    my ($name)=@_;
3257e1051a39Sopenharmony_ci
3258e1051a39Sopenharmony_ci    if (eval { require IPC::Cmd; 1; }) {
3259e1051a39Sopenharmony_ci        IPC::Cmd->import();
3260e1051a39Sopenharmony_ci        return scalar IPC::Cmd::can_run($name);
3261e1051a39Sopenharmony_ci    } else {
3262e1051a39Sopenharmony_ci        # if there is $directories component in splitpath,
3263e1051a39Sopenharmony_ci        # then it's not something to test with $PATH...
3264e1051a39Sopenharmony_ci        return $name if (File::Spec->splitpath($name))[1];
3265e1051a39Sopenharmony_ci
3266e1051a39Sopenharmony_ci        foreach (File::Spec->path()) {
3267e1051a39Sopenharmony_ci            my $fullpath = catfile($_, "$name$target{exe_extension}");
3268e1051a39Sopenharmony_ci            if (-f $fullpath and -x $fullpath) {
3269e1051a39Sopenharmony_ci                return $fullpath;
3270e1051a39Sopenharmony_ci            }
3271e1051a39Sopenharmony_ci        }
3272e1051a39Sopenharmony_ci    }
3273e1051a39Sopenharmony_ci}
3274e1051a39Sopenharmony_ci
3275e1051a39Sopenharmony_cisub env
3276e1051a39Sopenharmony_ci{
3277e1051a39Sopenharmony_ci    my $name = shift;
3278e1051a39Sopenharmony_ci    my %opts = @_;
3279e1051a39Sopenharmony_ci
3280e1051a39Sopenharmony_ci    unless ($opts{cacheonly}) {
3281e1051a39Sopenharmony_ci        # Note that if $ENV{$name} doesn't exist or is undefined,
3282e1051a39Sopenharmony_ci        # $config{perlenv}->{$name} will be created with the value
3283e1051a39Sopenharmony_ci        # undef.  This is intentional.
3284e1051a39Sopenharmony_ci
3285e1051a39Sopenharmony_ci        $config{perlenv}->{$name} = $ENV{$name}
3286e1051a39Sopenharmony_ci            if ! exists $config{perlenv}->{$name};
3287e1051a39Sopenharmony_ci    }
3288e1051a39Sopenharmony_ci    return $config{perlenv}->{$name};
3289e1051a39Sopenharmony_ci}
3290e1051a39Sopenharmony_ci
3291e1051a39Sopenharmony_ci# Configuration printer ##############################################
3292e1051a39Sopenharmony_ci
3293e1051a39Sopenharmony_cisub print_table_entry
3294e1051a39Sopenharmony_ci{
3295e1051a39Sopenharmony_ci    local $now_printing = shift;
3296e1051a39Sopenharmony_ci    my %target = resolve_config($now_printing);
3297e1051a39Sopenharmony_ci    my $type = shift;
3298e1051a39Sopenharmony_ci
3299e1051a39Sopenharmony_ci    # Don't print the templates
3300e1051a39Sopenharmony_ci    return if $target{template};
3301e1051a39Sopenharmony_ci
3302e1051a39Sopenharmony_ci    my @sequence = (
3303e1051a39Sopenharmony_ci        "sys_id",
3304e1051a39Sopenharmony_ci        "cpp",
3305e1051a39Sopenharmony_ci        "cppflags",
3306e1051a39Sopenharmony_ci        "defines",
3307e1051a39Sopenharmony_ci        "includes",
3308e1051a39Sopenharmony_ci        "cc",
3309e1051a39Sopenharmony_ci        "cflags",
3310e1051a39Sopenharmony_ci        "ld",
3311e1051a39Sopenharmony_ci        "lflags",
3312e1051a39Sopenharmony_ci        "loutflag",
3313e1051a39Sopenharmony_ci        "ex_libs",
3314e1051a39Sopenharmony_ci        "bn_ops",
3315e1051a39Sopenharmony_ci        "enable",
3316e1051a39Sopenharmony_ci        "disable",
3317e1051a39Sopenharmony_ci        "poly1035_asm_src",
3318e1051a39Sopenharmony_ci        "thread_scheme",
3319e1051a39Sopenharmony_ci        "perlasm_scheme",
3320e1051a39Sopenharmony_ci        "dso_scheme",
3321e1051a39Sopenharmony_ci        "shared_target",
3322e1051a39Sopenharmony_ci        "shared_cflag",
3323e1051a39Sopenharmony_ci        "shared_defines",
3324e1051a39Sopenharmony_ci        "shared_ldflag",
3325e1051a39Sopenharmony_ci        "shared_rcflag",
3326e1051a39Sopenharmony_ci        "shared_extension",
3327e1051a39Sopenharmony_ci        "dso_extension",
3328e1051a39Sopenharmony_ci        "obj_extension",
3329e1051a39Sopenharmony_ci        "exe_extension",
3330e1051a39Sopenharmony_ci        "ranlib",
3331e1051a39Sopenharmony_ci        "ar",
3332e1051a39Sopenharmony_ci        "arflags",
3333e1051a39Sopenharmony_ci        "aroutflag",
3334e1051a39Sopenharmony_ci        "rc",
3335e1051a39Sopenharmony_ci        "rcflags",
3336e1051a39Sopenharmony_ci        "rcoutflag",
3337e1051a39Sopenharmony_ci        "mt",
3338e1051a39Sopenharmony_ci        "mtflags",
3339e1051a39Sopenharmony_ci        "mtinflag",
3340e1051a39Sopenharmony_ci        "mtoutflag",
3341e1051a39Sopenharmony_ci        "multilib",
3342e1051a39Sopenharmony_ci        "build_scheme",
3343e1051a39Sopenharmony_ci        );
3344e1051a39Sopenharmony_ci
3345e1051a39Sopenharmony_ci    if ($type eq "TABLE") {
3346e1051a39Sopenharmony_ci        print "\n";
3347e1051a39Sopenharmony_ci        print "*** $now_printing\n";
3348e1051a39Sopenharmony_ci        foreach (@sequence) {
3349e1051a39Sopenharmony_ci            if (ref($target{$_}) eq "ARRAY") {
3350e1051a39Sopenharmony_ci                printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
3351e1051a39Sopenharmony_ci            } else {
3352e1051a39Sopenharmony_ci                printf "\$%-12s = %s\n", $_, $target{$_};
3353e1051a39Sopenharmony_ci            }
3354e1051a39Sopenharmony_ci        }
3355e1051a39Sopenharmony_ci    } elsif ($type eq "HASH") {
3356e1051a39Sopenharmony_ci        my $largest =
3357e1051a39Sopenharmony_ci            length((sort { length($a) <=> length($b) } @sequence)[-1]);
3358e1051a39Sopenharmony_ci        print "    '$now_printing' => {\n";
3359e1051a39Sopenharmony_ci        foreach (@sequence) {
3360e1051a39Sopenharmony_ci            if ($target{$_}) {
3361e1051a39Sopenharmony_ci                if (ref($target{$_}) eq "ARRAY") {
3362e1051a39Sopenharmony_ci                    print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
3363e1051a39Sopenharmony_ci                } else {
3364e1051a39Sopenharmony_ci                    print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
3365e1051a39Sopenharmony_ci                }
3366e1051a39Sopenharmony_ci            }
3367e1051a39Sopenharmony_ci        }
3368e1051a39Sopenharmony_ci        print "    },\n";
3369e1051a39Sopenharmony_ci    }
3370e1051a39Sopenharmony_ci}
3371e1051a39Sopenharmony_ci
3372e1051a39Sopenharmony_ci# Utility routines ###################################################
3373e1051a39Sopenharmony_ci
3374e1051a39Sopenharmony_ci# On VMS, if the given file is a logical name, File::Spec::Functions
3375e1051a39Sopenharmony_ci# will consider it an absolute path.  There are cases when we want a
3376e1051a39Sopenharmony_ci# purely syntactic check without checking the environment.
3377e1051a39Sopenharmony_cisub isabsolute {
3378e1051a39Sopenharmony_ci    my $file = shift;
3379e1051a39Sopenharmony_ci
3380e1051a39Sopenharmony_ci    # On non-platforms, we just use file_name_is_absolute().
3381e1051a39Sopenharmony_ci    return file_name_is_absolute($file) unless $^O eq "VMS";
3382e1051a39Sopenharmony_ci
3383e1051a39Sopenharmony_ci    # If the file spec includes a device or a directory spec,
3384e1051a39Sopenharmony_ci    # file_name_is_absolute() is perfectly safe.
3385e1051a39Sopenharmony_ci    return file_name_is_absolute($file) if $file =~ m|[:\[]|;
3386e1051a39Sopenharmony_ci
3387e1051a39Sopenharmony_ci    # Here, we know the given file spec isn't absolute
3388e1051a39Sopenharmony_ci    return 0;
3389e1051a39Sopenharmony_ci}
3390e1051a39Sopenharmony_ci
3391e1051a39Sopenharmony_ci# Makes a directory absolute and cleans out /../ in paths like foo/../bar
3392e1051a39Sopenharmony_ci# On some platforms, this uses rel2abs(), while on others, realpath() is used.
3393e1051a39Sopenharmony_ci# realpath() requires that at least all path components except the last is an
3394e1051a39Sopenharmony_ci# existing directory.  On VMS, the last component of the directory spec must
3395e1051a39Sopenharmony_ci# exist.
3396e1051a39Sopenharmony_cisub absolutedir {
3397e1051a39Sopenharmony_ci    my $dir = shift;
3398e1051a39Sopenharmony_ci
3399e1051a39Sopenharmony_ci    # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
3400e1051a39Sopenharmony_ci    # will return the volume name for the device, no matter what.  Also,
3401e1051a39Sopenharmony_ci    # it will return an incorrect directory spec if the argument is a
3402e1051a39Sopenharmony_ci    # directory that doesn't exist.
3403e1051a39Sopenharmony_ci    if ($^O eq "VMS") {
3404e1051a39Sopenharmony_ci        return rel2abs($dir);
3405e1051a39Sopenharmony_ci    }
3406e1051a39Sopenharmony_ci
3407e1051a39Sopenharmony_ci    # We use realpath() on Unix, since no other will properly clean out
3408e1051a39Sopenharmony_ci    # a directory spec.
3409e1051a39Sopenharmony_ci    use Cwd qw/realpath/;
3410e1051a39Sopenharmony_ci
3411e1051a39Sopenharmony_ci    return realpath($dir);
3412e1051a39Sopenharmony_ci}
3413e1051a39Sopenharmony_ci
3414e1051a39Sopenharmony_ci# Check if all paths are one and the same, using stat.  They must both exist
3415e1051a39Sopenharmony_ci# We need this for the cases when File::Spec doesn't detect case insensitivity
3416e1051a39Sopenharmony_ci# (File::Spec::Unix assumes case sensitivity)
3417e1051a39Sopenharmony_cisub samedir {
3418e1051a39Sopenharmony_ci    die "samedir expects two arguments\n" unless scalar @_ == 2;
3419e1051a39Sopenharmony_ci
3420e1051a39Sopenharmony_ci    my @stat0 = stat($_[0]);    # First argument
3421e1051a39Sopenharmony_ci    my @stat1 = stat($_[1]);    # Second argument
3422e1051a39Sopenharmony_ci
3423e1051a39Sopenharmony_ci    die "Couldn't stat $_[0]" unless @stat0;
3424e1051a39Sopenharmony_ci    die "Couldn't stat $_[1]" unless @stat1;
3425e1051a39Sopenharmony_ci
3426e1051a39Sopenharmony_ci    # Compare device number
3427e1051a39Sopenharmony_ci    return 0 unless ($stat0[0] == $stat1[0]);
3428e1051a39Sopenharmony_ci    # Compare "inode".  The perl manual recommends comparing as
3429e1051a39Sopenharmony_ci    # string rather than as number.
3430e1051a39Sopenharmony_ci    return 0 unless ($stat0[1] eq $stat1[1]);
3431e1051a39Sopenharmony_ci
3432e1051a39Sopenharmony_ci    return 1;                   # All the same
3433e1051a39Sopenharmony_ci}
3434e1051a39Sopenharmony_ci
3435e1051a39Sopenharmony_cisub quotify {
3436e1051a39Sopenharmony_ci    my %processors = (
3437e1051a39Sopenharmony_ci        perl    => sub { my $x = shift;
3438e1051a39Sopenharmony_ci                         $x =~ s/([\\\$\@"])/\\$1/g;
3439e1051a39Sopenharmony_ci                         return '"'.$x.'"'; },
3440e1051a39Sopenharmony_ci        maybeshell => sub { my $x = shift;
3441e1051a39Sopenharmony_ci                            (my $y = $x) =~ s/([\\\"])/\\$1/g;
3442e1051a39Sopenharmony_ci                            if ($x ne $y || $x =~ m|\s|) {
3443e1051a39Sopenharmony_ci                                return '"'.$y.'"';
3444e1051a39Sopenharmony_ci                            } else {
3445e1051a39Sopenharmony_ci                                return $x;
3446e1051a39Sopenharmony_ci                            }
3447e1051a39Sopenharmony_ci                        },
3448e1051a39Sopenharmony_ci        );
3449e1051a39Sopenharmony_ci    my $for = shift;
3450e1051a39Sopenharmony_ci    my $processor =
3451e1051a39Sopenharmony_ci        defined($processors{$for}) ? $processors{$for} : sub { shift; };
3452e1051a39Sopenharmony_ci
3453e1051a39Sopenharmony_ci    return map { $processor->($_); } @_;
3454e1051a39Sopenharmony_ci}
3455e1051a39Sopenharmony_ci
3456e1051a39Sopenharmony_ci# collect_from_file($filename, $line_concat_cond_re, $line_concat)
3457e1051a39Sopenharmony_ci# $filename is a file name to read from
3458e1051a39Sopenharmony_ci# $line_concat_cond_re is a regexp detecting a line continuation ending
3459e1051a39Sopenharmony_ci# $line_concat is a CODEref that takes care of concatenating two lines
3460e1051a39Sopenharmony_cisub collect_from_file {
3461e1051a39Sopenharmony_ci    my $filename = shift;
3462e1051a39Sopenharmony_ci    my $line_concat_cond_re = shift;
3463e1051a39Sopenharmony_ci    my $line_concat = shift;
3464e1051a39Sopenharmony_ci
3465e1051a39Sopenharmony_ci    open my $fh, $filename || die "unable to read $filename: $!\n";
3466e1051a39Sopenharmony_ci    return sub {
3467e1051a39Sopenharmony_ci        my $saved_line = "";
3468e1051a39Sopenharmony_ci        $_ = "";
3469e1051a39Sopenharmony_ci        while (<$fh>) {
3470e1051a39Sopenharmony_ci            s|\R$||;
3471e1051a39Sopenharmony_ci            if (defined $line_concat) {
3472e1051a39Sopenharmony_ci                $_ = $line_concat->($saved_line, $_);
3473e1051a39Sopenharmony_ci                $saved_line = "";
3474e1051a39Sopenharmony_ci            }
3475e1051a39Sopenharmony_ci            if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3476e1051a39Sopenharmony_ci                $saved_line = $_;
3477e1051a39Sopenharmony_ci                next;
3478e1051a39Sopenharmony_ci            }
3479e1051a39Sopenharmony_ci            return $_;
3480e1051a39Sopenharmony_ci        }
3481e1051a39Sopenharmony_ci        die "$filename ending with continuation line\n" if $_;
3482e1051a39Sopenharmony_ci        close $fh;
3483e1051a39Sopenharmony_ci        return undef;
3484e1051a39Sopenharmony_ci    }
3485e1051a39Sopenharmony_ci}
3486e1051a39Sopenharmony_ci
3487e1051a39Sopenharmony_ci# collect_from_array($array, $line_concat_cond_re, $line_concat)
3488e1051a39Sopenharmony_ci# $array is an ARRAYref of lines
3489e1051a39Sopenharmony_ci# $line_concat_cond_re is a regexp detecting a line continuation ending
3490e1051a39Sopenharmony_ci# $line_concat is a CODEref that takes care of concatenating two lines
3491e1051a39Sopenharmony_cisub collect_from_array {
3492e1051a39Sopenharmony_ci    my $array = shift;
3493e1051a39Sopenharmony_ci    my $line_concat_cond_re = shift;
3494e1051a39Sopenharmony_ci    my $line_concat = shift;
3495e1051a39Sopenharmony_ci    my @array = (@$array);
3496e1051a39Sopenharmony_ci
3497e1051a39Sopenharmony_ci    return sub {
3498e1051a39Sopenharmony_ci        my $saved_line = "";
3499e1051a39Sopenharmony_ci        $_ = "";
3500e1051a39Sopenharmony_ci        while (defined($_ = shift @array)) {
3501e1051a39Sopenharmony_ci            s|\R$||;
3502e1051a39Sopenharmony_ci            if (defined $line_concat) {
3503e1051a39Sopenharmony_ci                $_ = $line_concat->($saved_line, $_);
3504e1051a39Sopenharmony_ci                $saved_line = "";
3505e1051a39Sopenharmony_ci            }
3506e1051a39Sopenharmony_ci            if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3507e1051a39Sopenharmony_ci                $saved_line = $_;
3508e1051a39Sopenharmony_ci                next;
3509e1051a39Sopenharmony_ci            }
3510e1051a39Sopenharmony_ci            return $_;
3511e1051a39Sopenharmony_ci        }
3512e1051a39Sopenharmony_ci        die "input text ending with continuation line\n" if $_;
3513e1051a39Sopenharmony_ci        return undef;
3514e1051a39Sopenharmony_ci    }
3515e1051a39Sopenharmony_ci}
3516e1051a39Sopenharmony_ci
3517e1051a39Sopenharmony_ci# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
3518e1051a39Sopenharmony_ci# $lineiterator is a CODEref that delivers one line at a time.
3519e1051a39Sopenharmony_ci# All following arguments are regex/CODEref pairs, where the regexp detects a
3520e1051a39Sopenharmony_ci# line and the CODEref does something with the result of the regexp.
3521e1051a39Sopenharmony_cisub collect_information {
3522e1051a39Sopenharmony_ci    my $lineiterator = shift;
3523e1051a39Sopenharmony_ci    my %collectors = @_;
3524e1051a39Sopenharmony_ci
3525e1051a39Sopenharmony_ci    while(defined($_ = $lineiterator->())) {
3526e1051a39Sopenharmony_ci        s|\R$||;
3527e1051a39Sopenharmony_ci        my $found = 0;
3528e1051a39Sopenharmony_ci        if ($collectors{"BEFORE"}) {
3529e1051a39Sopenharmony_ci            $collectors{"BEFORE"}->($_);
3530e1051a39Sopenharmony_ci        }
3531e1051a39Sopenharmony_ci        foreach my $re (keys %collectors) {
3532e1051a39Sopenharmony_ci            if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
3533e1051a39Sopenharmony_ci                $collectors{$re}->($lineiterator);
3534e1051a39Sopenharmony_ci                $found = 1;
3535e1051a39Sopenharmony_ci            };
3536e1051a39Sopenharmony_ci        }
3537e1051a39Sopenharmony_ci        if ($collectors{"OTHERWISE"}) {
3538e1051a39Sopenharmony_ci            $collectors{"OTHERWISE"}->($lineiterator, $_)
3539e1051a39Sopenharmony_ci                unless $found || !defined $collectors{"OTHERWISE"};
3540e1051a39Sopenharmony_ci        }
3541e1051a39Sopenharmony_ci        if ($collectors{"AFTER"}) {
3542e1051a39Sopenharmony_ci            $collectors{"AFTER"}->($_);
3543e1051a39Sopenharmony_ci        }
3544e1051a39Sopenharmony_ci    }
3545e1051a39Sopenharmony_ci}
3546e1051a39Sopenharmony_ci
3547e1051a39Sopenharmony_ci# tokenize($line)
3548e1051a39Sopenharmony_ci# tokenize($line,$separator)
3549e1051a39Sopenharmony_ci# $line is a line of text to split up into tokens
3550e1051a39Sopenharmony_ci# $separator [optional] is a regular expression that separates the tokens,
3551e1051a39Sopenharmony_ci# the default being spaces.  Do not use quotes of any kind as separators,
3552e1051a39Sopenharmony_ci# that will give undefined results.
3553e1051a39Sopenharmony_ci# Returns a list of tokens.
3554e1051a39Sopenharmony_ci#
3555e1051a39Sopenharmony_ci# Tokens are divided by separator (spaces by default).  If the tokens include
3556e1051a39Sopenharmony_ci# the separators, they have to be quoted with single or double quotes.
3557e1051a39Sopenharmony_ci# Double quotes inside a double quoted token must be escaped.  Escaping is done
3558e1051a39Sopenharmony_ci# with backslash.
3559e1051a39Sopenharmony_ci# Basically, the same quoting rules apply for " and ' as in any
3560e1051a39Sopenharmony_ci# Unix shell.
3561e1051a39Sopenharmony_cisub tokenize {
3562e1051a39Sopenharmony_ci    my $line = my $debug_line = shift;
3563e1051a39Sopenharmony_ci    my $separator = shift // qr|\s+|;
3564e1051a39Sopenharmony_ci    my @result = ();
3565e1051a39Sopenharmony_ci
3566e1051a39Sopenharmony_ci    if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3567e1051a39Sopenharmony_ci        print STDERR "DEBUG[tokenize]: \$separator = $separator\n";
3568e1051a39Sopenharmony_ci    }
3569e1051a39Sopenharmony_ci
3570e1051a39Sopenharmony_ci    while ($line =~ s|^${separator}||, $line ne "") {
3571e1051a39Sopenharmony_ci        my $token = "";
3572e1051a39Sopenharmony_ci    again:
3573e1051a39Sopenharmony_ci        $line =~ m/^(.*?)(${separator}|"|'|$)/;
3574e1051a39Sopenharmony_ci        $token .= $1;
3575e1051a39Sopenharmony_ci        $line = $2.$';
3576e1051a39Sopenharmony_ci
3577e1051a39Sopenharmony_ci        if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
3578e1051a39Sopenharmony_ci            $token .= $1;
3579e1051a39Sopenharmony_ci            $line = $';
3580e1051a39Sopenharmony_ci            goto again;
3581e1051a39Sopenharmony_ci        } elsif ($line =~ m/^'([^']*)'/) {
3582e1051a39Sopenharmony_ci            $token .= $1;
3583e1051a39Sopenharmony_ci            $line = $';
3584e1051a39Sopenharmony_ci            goto again;
3585e1051a39Sopenharmony_ci        }
3586e1051a39Sopenharmony_ci        push @result, $token;
3587e1051a39Sopenharmony_ci    }
3588e1051a39Sopenharmony_ci
3589e1051a39Sopenharmony_ci    if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3590e1051a39Sopenharmony_ci        print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
3591e1051a39Sopenharmony_ci        print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
3592e1051a39Sopenharmony_ci    }
3593e1051a39Sopenharmony_ci    return @result;
3594e1051a39Sopenharmony_ci}
3595