15af53050Schristos#! /usr/bin/env perl 25af53050Schristos# -*- mode: perl; -*- 3b46c97feSchristos# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. 45af53050Schristos# 58fbed61eSchristos# Licensed under the Apache License 2.0 (the "License"). You may not use 65af53050Schristos# this file except in compliance with the License. You can obtain a copy 75af53050Schristos# in the file LICENSE in the source distribution or at 85af53050Schristos# https://www.openssl.org/source/license.html 9a89c9211Schristos 105af53050Schristos## Configure -- OpenSSL source tree configuration script 115af53050Schristos 125af53050Schristosuse 5.10.0; 13a89c9211Schristosuse strict; 14e0ea3921Schristosuse Config; 1578327f04Schristosuse FindBin; 1678327f04Schristosuse lib "$FindBin::Bin/util/perl"; 175af53050Schristosuse File::Basename; 188fbed61eSchristosuse File::Spec::Functions qw/:DEFAULT abs2rel rel2abs splitdir/; 195af53050Schristosuse File::Path qw/mkpath/; 208fbed61eSchristosuse OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt"; 2178327f04Schristosuse OpenSSL::Glob; 228fbed61eSchristosuse OpenSSL::Template; 238fbed61eSchristosuse OpenSSL::config; 24a89c9211Schristos 258fbed61eSchristos# see INSTALL.md for instructions. 26a89c9211Schristos 272500041cSchristosmy $orig_death_handler = $SIG{__DIE__}; 282500041cSchristos$SIG{__DIE__} = \&death_handler; 292500041cSchristos 304261787cSchristosmy $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"; 31a89c9211Schristos 328fbed61eSchristosmy $banner = <<"EOF"; 338fbed61eSchristos 348fbed61eSchristos********************************************************************** 358fbed61eSchristos*** *** 368fbed61eSchristos*** OpenSSL has been successfully configured *** 378fbed61eSchristos*** *** 388fbed61eSchristos*** If you encounter a problem while building, please open an *** 398fbed61eSchristos*** issue on GitHub <https://github.com/openssl/openssl/issues> *** 408fbed61eSchristos*** and include the output from the following command: *** 418fbed61eSchristos*** *** 428fbed61eSchristos*** perl configdata.pm --dump *** 438fbed61eSchristos*** *** 448fbed61eSchristos*** (If you are new to OpenSSL, you might want to consult the *** 458fbed61eSchristos*** 'Troubleshooting' section in the INSTALL.md file first) *** 468fbed61eSchristos*** *** 478fbed61eSchristos********************************************************************** 488fbed61eSchristosEOF 498fbed61eSchristos 50a89c9211Schristos# Options: 51a89c9211Schristos# 525af53050Schristos# --config add the given configuration file, which will be read after 535af53050Schristos# any "Configurations*" files that are found in the same 545af53050Schristos# directory as this script. 555af53050Schristos# --prefix prefix for the OpenSSL installation, which includes the 565af53050Schristos# directories bin, lib, include, share/man, share/doc/openssl 575af53050Schristos# This becomes the value of INSTALLTOP in Makefile 585af53050Schristos# (Default: /usr/local) 595af53050Schristos# --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys. 605af53050Schristos# If it's a relative directory, it will be added on the directory 615af53050Schristos# given with --prefix. 625af53050Schristos# This becomes the value of OPENSSLDIR in Makefile and in C. 635af53050Schristos# (Default: PREFIX/ssl) 648fbed61eSchristos# --banner=".." Output specified text instead of default completion banner 658fbed61eSchristos# 668fbed61eSchristos# -w Don't wait after showing a Configure warning 67a89c9211Schristos# 68a89c9211Schristos# --cross-compile-prefix Add specified prefix to binutils components. 69a89c9211Schristos# 708fbed61eSchristos# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0 718fbed61eSchristos# Define the public APIs as they were for that version 728fbed61eSchristos# including patch releases. If 'no-deprecated' is also 738fbed61eSchristos# given, do not compile support for interfaces deprecated 748fbed61eSchristos# up to and including the specified OpenSSL version. 755af53050Schristos# 76a89c9211Schristos# no-hw-xxx do not compile support for specific crypto hardware. 77a89c9211Schristos# Generic OpenSSL-style methods relating to this support 78a89c9211Schristos# are always compiled but return NULL if the hardware 79a89c9211Schristos# support isn't compiled. 80a89c9211Schristos# no-hw do not compile support for any crypto hardware. 81a89c9211Schristos# [no-]threads [don't] try to create a library that is suitable for 82a89c9211Schristos# multithreaded applications (default is "threads" if we 83a89c9211Schristos# know how to do it) 84a89c9211Schristos# [no-]shared [don't] try to create shared libraries when supported. 855af53050Schristos# [no-]pic [don't] try to build position independent code when supported. 865af53050Schristos# If disabled, it also disables shared and dynamic-engine. 87a89c9211Schristos# no-asm do not use assembler 885af53050Schristos# no-egd do not compile support for the entropy-gathering daemon APIs 89a89c9211Schristos# [no-]zlib [don't] compile support for zlib compression. 90a89c9211Schristos# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared 91a89c9211Schristos# library and will be loaded in run-time by the OpenSSL library. 92e3d33c04Schristos# sctp include SCTP support 938fbed61eSchristos# no-uplink Don't build support for UPLINK interface. 94338c2544Schristos# enable-weak-ssl-ciphers 955af53050Schristos# Enable weak ciphers that are disabled by default. 96b367ed38Sspz# 386 generate 80386 code in assembly modules 97b367ed38Sspz# no-sse2 disables IA-32 SSE2 code in assembly modules, the above 98b367ed38Sspz# mentioned '386' option implies this one 998fbed61eSchristos# no-<cipher> build without specified algorithm (dsa, idea, rc5, ...) 10052629741Schristos# -<xxx> +<xxx> All options which are unknown to the 'Configure' script are 10152629741Schristos# /<xxx> passed through to the compiler. Unix-style options beginning 10252629741Schristos# with a '-' or '+' are recognized, as well as Windows-style 10352629741Schristos# options beginning with a '/'. If the option contains arguments 10452629741Schristos# separated by spaces, then the URL-style notation %20 can be 10552629741Schristos# used for the space character in order to avoid having to quote 10652629741Schristos# the option. For example, -opt%20arg gets expanded to -opt arg. 10752629741Schristos# In fact, any ASCII character can be encoded as %xx using its 10852629741Schristos# hexadecimal encoding. 1095af53050Schristos# -static while -static is also a pass-through compiler option (and 1105af53050Schristos# as such is limited to environments where it's actually 1115af53050Schristos# meaningful), it triggers a number configuration options, 1124261787cSchristos# namely no-pic, no-shared and no-threads. It is 1135af53050Schristos# argued that the only reason to produce statically linked 1145af53050Schristos# binaries (and in context it means executables linked with 1155af53050Schristos# -static flag, and not just executables linked with static 1165af53050Schristos# libcrypto.a) is to eliminate dependency on specific run-time, 1175af53050Schristos# a.k.a. libc version. The mentioned config options are meant 1185af53050Schristos# to achieve just that. Unfortunately on Linux it's impossible 1195af53050Schristos# to eliminate the dependency completely for openssl executable 1205af53050Schristos# because of getaddrinfo and gethostbyname calls, which can 1215af53050Schristos# invoke dynamically loadable library facility anyway to meet 1225af53050Schristos# the lookup requests. For this reason on Linux statically 1235af53050Schristos# linked openssl executable has rather debugging value than 1245af53050Schristos# production quality. 125a89c9211Schristos# 126a89c9211Schristos# BN_LLONG use the type 'long long' in crypto/bn/bn.h 127a89c9211Schristos# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h 128a89c9211Schristos# Following are set automatically by this script 129a89c9211Schristos# 1305af53050Schristos# MD5_ASM use some extra md5 assembler, 1315af53050Schristos# SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86 1325af53050Schristos# RMD160_ASM use some extra ripemd160 assembler, 133a89c9211Schristos# SHA256_ASM sha256_block is implemented in assembler 134a89c9211Schristos# SHA512_ASM sha512_block is implemented in assembler 1355af53050Schristos# AES_ASM AES_[en|de]crypt is implemented in assembler 136a89c9211Schristos 1374261787cSchristos# Minimum warning options... any contributions to OpenSSL should at least 1384261787cSchristos# get past these. Note that we only use these with C compilers, not with 1394261787cSchristos# C++ compilers. 140a89c9211Schristos 1415af53050Schristos# -DPEDANTIC complements -pedantic and is meant to mask code that 1425af53050Schristos# is not strictly standard-compliant and/or implementation-specific, 1435af53050Schristos# e.g. inline assembly, disregards to alignment requirements, such 1445af53050Schristos# that -pedantic would complain about. Incidentally -DPEDANTIC has 1455af53050Schristos# to be used even in sanitized builds, because sanitizer too is 1465af53050Schristos# supposed to and does take notice of non-standard behaviour. Then 1475af53050Schristos# -pedantic with pre-C9x compiler would also complain about 'long 1485af53050Schristos# long' not being supported. As 64-bit algorithms are common now, 1495af53050Schristos# it grew impossible to resolve this without sizeable additional 1505af53050Schristos# code, so we just tell compiler to be pedantic about everything 1515af53050Schristos# but 'long long' type. 152e0ea3921Schristos 1534261787cSchristosmy @gcc_devteam_warn = qw( 1548fbed61eSchristos -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG 1554261787cSchristos -Wall 1568fbed61eSchristos -Wmissing-declarations 1574261787cSchristos -Wextra 1584261787cSchristos -Wno-unused-parameter 1594261787cSchristos -Wno-missing-field-initializers 1604261787cSchristos -Wswitch 1614261787cSchristos -Wsign-compare 1624261787cSchristos -Wshadow 1634261787cSchristos -Wformat 1644261787cSchristos -Wtype-limits 1654261787cSchristos -Wundef 1664261787cSchristos -Werror 1674261787cSchristos -Wmissing-prototypes 1684261787cSchristos -Wstrict-prototypes 1694261787cSchristos); 17031b855a0Sspz 17131b855a0Sspz# These are used in addition to $gcc_devteam_warn when the compiler is clang. 17231b855a0Sspz# TODO(openssl-team): fix problems and investigate if (at least) the 1735af53050Schristos# following warnings can also be enabled: 1745af53050Schristos# -Wcast-align 175e0ea3921Schristos# -Wunreachable-code -- no, too ugly/compiler-specific 1765af53050Schristos# -Wlanguage-extension-token -- no, we use asm() 1775af53050Schristos# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc 1785af53050Schristos# -Wextended-offsetof -- no, needed in CMS ASN1 code 1794261787cSchristosmy @clang_devteam_warn = qw( 180403eeac4Schristos -Wno-unknown-warning-option 1814261787cSchristos -Wno-parentheses-equality 1824261787cSchristos -Wno-language-extension-token 1834261787cSchristos -Wno-extended-offsetof 1844261787cSchristos -Wconditional-uninitialized 1854261787cSchristos -Wincompatible-pointer-types-discards-qualifiers 1864261787cSchristos -Wmissing-variable-declarations 1874261787cSchristos); 18831b855a0Sspz 18952629741Schristosmy @cl_devteam_warn = qw( 19052629741Schristos /WX 19152629741Schristos); 19252629741Schristos 193cef2ee70Schristosmy $strict_warnings = 0; 194cef2ee70Schristos 195a89c9211Schristos# As for $BSDthreads. Idea is to maintain "collective" set of flags, 196a89c9211Schristos# which would cover all BSD flavors. -pthread applies to them all, 197a89c9211Schristos# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD 198a89c9211Schristos# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r, 199a89c9211Schristos# which has to be accompanied by explicit -D_THREAD_SAFE and 200a89c9211Schristos# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which 201a89c9211Schristos# seems to be sufficient? 2025af53050Schristosour $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT"; 203a89c9211Schristos 204a89c9211Schristos# 2055af53050Schristos# API compatibility name to version number mapping. 206a89c9211Schristos# 2075af53050Schristosmy $apitable = { 2088fbed61eSchristos # This table expresses when API additions or changes can occur. 2098fbed61eSchristos # The numbering used changes from 3.0 and on because we updated 2108fbed61eSchristos # (solidified) our version numbering scheme at that point. 2118fbed61eSchristos 2128fbed61eSchristos # From 3.0 and on, we internalise the given version number in decimal 2138fbed61eSchristos # as MAJOR * 10000 + MINOR * 100 + 0 2148fbed61eSchristos "3.0.0" => 30000, 2158fbed61eSchristos "3.0" => 30000, 2168fbed61eSchristos 2178fbed61eSchristos # Note that before 3.0, we didn't have the same version number scheme. 2188fbed61eSchristos # Still, the numbering we use here covers what we need. 2198fbed61eSchristos "1.1.1" => 10101, 2208fbed61eSchristos "1.1.0" => 10100, 2218fbed61eSchristos "1.0.2" => 10002, 2228fbed61eSchristos "1.0.1" => 10001, 2238fbed61eSchristos "1.0.0" => 10000, 2248fbed61eSchristos "0.9.8" => 908, 2255af53050Schristos}; 2265af53050Schristos 2278fbed61eSchristos# For OpenSSL::config::get_platform 2288fbed61eSchristosmy %guess_opts = (); 2298fbed61eSchristos 2308fbed61eSchristosmy $dryrun = 0; 2318fbed61eSchristos 2325af53050Schristosour %table = (); 2335af53050Schristosour %config = (); 2345af53050Schristosour %withargs = (); 235e0ea3921Schristosour $now_printing; # set to current entry's name in print_table_entry 236e0ea3921Schristos # (todo: right thing would be to encapsulate name 237e0ea3921Schristos # into %target [class] and make print_table_entry 238e0ea3921Schristos # a method) 2395af53050Schristos 2405af53050Schristos# Forward declarations ############################################### 2415af53050Schristos 2425af53050Schristos# read_config(filename) 243a89c9211Schristos# 2445af53050Schristos# Reads a configuration file and populates %table with the contents 2455af53050Schristos# (which the configuration file places in %targets). 2465af53050Schristossub read_config; 247a89c9211Schristos 2485af53050Schristos# resolve_config(target) 249a89c9211Schristos# 2505af53050Schristos# Resolves all the late evaluations, inheritances and so on for the 2515af53050Schristos# chosen target and any target it inherits from. 2525af53050Schristossub resolve_config; 253a89c9211Schristos 254a89c9211Schristos 2555af53050Schristos# Information collection ############################################# 256a89c9211Schristos 2575af53050Schristos# Unified build supports separate build dir 2585af53050Schristosmy $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax 2595af53050Schristosmy $blddir = catdir(absolutedir(".")); # catdir ensures local syntax 2604a7cf967Schristos 2614a7cf967Schristos# File::Spec::Unix doesn't detect case insensitivity, so we make sure to 2624a7cf967Schristos# check if the source and build directory are really the same, and make 2634a7cf967Schristos# them so. This avoids all kinds of confusion later on. 2644a7cf967Schristos# We must check @File::Spec::ISA rather than using File::Spec->isa() to 2654a7cf967Schristos# know if File::Spec ended up loading File::Spec::Unix. 2664a7cf967Schristos$srcdir = $blddir 2674a7cf967Schristos if (grep(/::Unix$/, @File::Spec::ISA) 2684a7cf967Schristos && samedir($srcdir, $blddir)); 2694a7cf967Schristos 2705af53050Schristosmy $dofile = abs2rel(catfile($srcdir, "util/dofile.pl")); 271a89c9211Schristos 2725af53050Schristosmy $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR'; 273a89c9211Schristos 2744a7cf967Schristos$config{sourcedir} = abs2rel($srcdir, $blddir); 2754a7cf967Schristos$config{builddir} = abs2rel($blddir, $blddir); 2768fbed61eSchristos# echo -n 'holy hand grenade of antioch' | openssl sha256 2778fbed61eSchristos$config{FIPSKEY} = 2788fbed61eSchristos 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813'; 279a89c9211Schristos 2805af53050Schristos# Collect reconfiguration information if needed 2815af53050Schristosmy @argvcopy=@ARGV; 282a89c9211Schristos 2835af53050Schristosif (grep /^reconf(igure)?$/, @argvcopy) { 284e0ea3921Schristos die "reconfiguring with other arguments present isn't supported" 285e0ea3921Schristos if scalar @argvcopy > 1; 2865af53050Schristos if (-f "./configdata.pm") { 2875af53050Schristos my $file = "./configdata.pm"; 2885af53050Schristos unless (my $return = do $file) { 2895af53050Schristos die "couldn't parse $file: $@" if $@; 2905af53050Schristos die "couldn't do $file: $!" unless defined $return; 2915af53050Schristos die "couldn't run $file" unless $return; 292e3d33c04Schristos } 293a89c9211Schristos 2945af53050Schristos @argvcopy = defined($configdata::config{perlargv}) ? 2955af53050Schristos @{$configdata::config{perlargv}} : (); 2965af53050Schristos die "Incorrect data to reconfigure, please do a normal configuration\n" 2975af53050Schristos if (grep(/^reconf/,@argvcopy)); 298e0ea3921Schristos $config{perlenv} = $configdata::config{perlenv} // {}; 2995af53050Schristos } else { 3005af53050Schristos die "Insufficient data to reconfigure, please do a normal configuration\n"; 3015af53050Schristos } 3025af53050Schristos} 3035af53050Schristos 3045af53050Schristos$config{perlargv} = [ @argvcopy ]; 3055af53050Schristos 3068fbed61eSchristos# Historical: if known directories in crypto/ have been removed, it means 3078fbed61eSchristos# that those sub-systems are disabled. 3088fbed61eSchristos# (the other option would be to removed them from the SUBDIRS statement in 3098fbed61eSchristos# crypto/build.info) 3108fbed61eSchristos# We reverse the input list for cosmetic purely reasons, to compensate that 3118fbed61eSchristos# 'unshift' adds at the front of the list (i.e. in reverse input order). 3128fbed61eSchristosforeach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh', 3138fbed61eSchristos 'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2', 3148fbed61eSchristos 'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha', 3158fbed61eSchristos 'sm2', 'sm3', 'sm4') ) { 3168fbed61eSchristos unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_); 3178fbed61eSchristos} 3188fbed61eSchristos 3195af53050Schristos# Collect version numbers 3208fbed61eSchristosmy %version = (); 3215af53050Schristos 3225af53050Schristoscollect_information( 3238fbed61eSchristos collect_from_file(catfile($srcdir,'VERSION.dat')), 3248fbed61eSchristos qr/\s*(\w+)\s*=\s*(.*?)\s*$/ => 3258fbed61eSchristos sub { 3268fbed61eSchristos # Only define it if there is a value at all 3278fbed61eSchristos if ($2 ne '') { 3288fbed61eSchristos my $k = $1; 3298fbed61eSchristos my $v = $2; 3308fbed61eSchristos # Some values are quoted. Trim the quotes 3318fbed61eSchristos $v = $1 if $v =~ /^"(.*)"$/; 3328fbed61eSchristos $version{uc $k} = $v; 3338fbed61eSchristos } 3348fbed61eSchristos }, 3358fbed61eSchristos "OTHERWISE" => 3368fbed61eSchristos sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" }, 3375af53050Schristos ); 3385af53050Schristos 3398fbed61eSchristos$config{major} = $version{MAJOR} // 'unknown'; 3408fbed61eSchristos$config{minor} = $version{MINOR} // 'unknown'; 3418fbed61eSchristos$config{patch} = $version{PATCH} // 'unknown'; 3428fbed61eSchristos$config{prerelease} = 3438fbed61eSchristos defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : ''; 3448fbed61eSchristos$config{build_metadata} = 3458fbed61eSchristos defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : ''; 3468fbed61eSchristos$config{shlib_version} = $version{SHLIB_VERSION} // 'unknown'; 3478fbed61eSchristos$config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx'; 3488fbed61eSchristos 3498fbed61eSchristos$config{version} = "$config{major}.$config{minor}.$config{patch}"; 3508fbed61eSchristos$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}"; 3518fbed61eSchristos 3528fbed61eSchristosdie "erroneous version information in VERSION.dat: ", 3538fbed61eSchristos "$config{version}, $config{shlib_version}\n" 3548fbed61eSchristos unless (defined $version{MAJOR} 3558fbed61eSchristos && defined $version{MINOR} 3568fbed61eSchristos && defined $version{PATCH} 3578fbed61eSchristos && defined $version{SHLIB_VERSION}); 3585af53050Schristos 3595af53050Schristos# Collect target configurations 3605af53050Schristos 3615af53050Schristosmy $pattern = catfile(dirname($0), "Configurations", "*.conf"); 3625af53050Schristosforeach (sort glob($pattern)) { 3635af53050Schristos &read_config($_); 3645af53050Schristos} 3655af53050Schristos 366e0ea3921Schristosif (defined env($local_config_envname)) { 3675af53050Schristos if ($^O eq 'VMS') { 3685af53050Schristos # VMS environment variables are logical names, 3695af53050Schristos # which can be used as is 3705af53050Schristos $pattern = $local_config_envname . ':' . '*.conf'; 3715af53050Schristos } else { 372e0ea3921Schristos $pattern = catfile(env($local_config_envname), '*.conf'); 3735af53050Schristos } 3745af53050Schristos 3755af53050Schristos foreach (sort glob($pattern)) { 3765af53050Schristos &read_config($_); 3775af53050Schristos } 3785af53050Schristos} 3795af53050Schristos 380e0ea3921Schristos# Save away perl command information 381e0ea3921Schristos$config{perl_cmd} = $^X; 382e0ea3921Schristos$config{perl_version} = $Config{version}; 383e0ea3921Schristos$config{perl_archname} = $Config{archname}; 3845af53050Schristos 3855af53050Schristos$config{prefix}=""; 3865af53050Schristos$config{openssldir}=""; 3875af53050Schristos$config{processor}=""; 3885af53050Schristos$config{libdir}=""; 3895af53050Schristosmy $auto_threads=1; # enable threads automatically? true by default 3905af53050Schristosmy $default_ranlib; 3915af53050Schristos 3925af53050Schristos# Known TLS and DTLS protocols 393e0ea3921Schristosmy @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3); 3945af53050Schristosmy @dtls = qw(dtls1 dtls1_2); 3955af53050Schristos 3965af53050Schristos# Explicitly known options that are possible to disable. They can 3975af53050Schristos# be regexps, and will be used like this: /^no-${option}$/ 3985af53050Schristos# For developers: keep it sorted alphabetically 3995af53050Schristos 4005af53050Schristosmy @disablables = ( 4018fbed61eSchristos "acvp-tests", 4025af53050Schristos "afalgeng", 403e0ea3921Schristos "aria", 4045af53050Schristos "asan", 4055af53050Schristos "asm", 4065af53050Schristos "async", 407b46c97feSchristos "atexit", 4085af53050Schristos "autoalginit", 4095af53050Schristos "autoerrinit", 410e0ea3921Schristos "autoload-config", 4115af53050Schristos "bf", 4125af53050Schristos "blake2", 4138fbed61eSchristos "buildtest-c++", 4148fbed61eSchristos "bulk", 4158fbed61eSchristos "cached-fetch", 4165af53050Schristos "camellia", 4175af53050Schristos "capieng", 4185af53050Schristos "cast", 4195af53050Schristos "chacha", 4205af53050Schristos "cmac", 4218fbed61eSchristos "cmp", 4225af53050Schristos "cms", 4235af53050Schristos "comp", 4245af53050Schristos "crypto-mdebug", 4255af53050Schristos "ct", 4265af53050Schristos "deprecated", 4275af53050Schristos "des", 428e0ea3921Schristos "devcryptoeng", 4295af53050Schristos "dgram", 4305af53050Schristos "dh", 4315af53050Schristos "dsa", 43252629741Schristos "dso", 4335af53050Schristos "dtls", 4345af53050Schristos "dynamic-engine", 4355af53050Schristos "ec", 4365af53050Schristos "ec2m", 4378fbed61eSchristos "ec_nistp_64_gcc_128", 4385af53050Schristos "ecdh", 4395af53050Schristos "ecdsa", 4405af53050Schristos "egd", 4415af53050Schristos "engine", 4425af53050Schristos "err", 443e0ea3921Schristos "external-tests", 4445af53050Schristos "filenames", 4458fbed61eSchristos "fips", 4468fbed61eSchristos "fips-securitychecks", 4475af53050Schristos "fuzz-afl", 4488fbed61eSchristos "fuzz-libfuzzer", 4495af53050Schristos "gost", 4505af53050Schristos "idea", 4518fbed61eSchristos "ktls", 4528fbed61eSchristos "legacy", 4538fbed61eSchristos "loadereng", 4545af53050Schristos "makedepend", 4555af53050Schristos "md2", 4565af53050Schristos "md4", 4575af53050Schristos "mdc2", 4588fbed61eSchristos "module", 4595af53050Schristos "msan", 4605af53050Schristos "multiblock", 4615af53050Schristos "nextprotoneg", 4625af53050Schristos "ocb", 4635af53050Schristos "ocsp", 4648fbed61eSchristos "padlockeng", 4655af53050Schristos "pic", 4668fbed61eSchristos "pinshared", 4675af53050Schristos "poly1305", 4685af53050Schristos "posix-io", 4695af53050Schristos "psk", 4705af53050Schristos "rc2", 4715af53050Schristos "rc4", 4725af53050Schristos "rc5", 4735af53050Schristos "rdrand", 4745af53050Schristos "rfc3779", 4755af53050Schristos "rmd160", 4765af53050Schristos "scrypt", 4775af53050Schristos "sctp", 4788fbed61eSchristos "secure-memory", 4795af53050Schristos "seed", 4805af53050Schristos "shared", 481e0ea3921Schristos "siphash", 4828fbed61eSchristos "siv", 483e0ea3921Schristos "sm2", 484e0ea3921Schristos "sm3", 485e0ea3921Schristos "sm4", 4865af53050Schristos "sock", 4875af53050Schristos "srp", 4885af53050Schristos "srtp", 4895af53050Schristos "sse2", 4905af53050Schristos "ssl", 4915af53050Schristos "ssl-trace", 4925af53050Schristos "static-engine", 4935af53050Schristos "stdio", 494e0ea3921Schristos "tests", 4955af53050Schristos "threads", 4965af53050Schristos "tls", 4978fbed61eSchristos "trace", 4985af53050Schristos "ts", 4995af53050Schristos "ubsan", 500e0ea3921Schristos "ui-console", 5015af53050Schristos "unit-test", 5028fbed61eSchristos "uplink", 5035af53050Schristos "weak-ssl-ciphers", 5048fbed61eSchristos "whirlpool", 5055af53050Schristos "zlib", 5065af53050Schristos "zlib-dynamic", 5075af53050Schristos ); 5085af53050Schristosforeach my $proto ((@tls, @dtls)) 5095af53050Schristos { 5105af53050Schristos push(@disablables, $proto); 511e0ea3921Schristos push(@disablables, "$proto-method") unless $proto eq "tls1_3"; 5125af53050Schristos } 5135af53050Schristos 5148fbed61eSchristos# Internal disablables, for aliasing purposes. They serve no special 5158fbed61eSchristos# purpose here, but allow scripts to get to know them through configdata.pm, 5168fbed61eSchristos# where these are merged with @disablables. 5178fbed61eSchristos# The actual aliasing mechanism is done via %disable_cascades 5188fbed61eSchristosmy @disablables_int = qw( 5198fbed61eSchristos crmf 5208fbed61eSchristos ); 5218fbed61eSchristos 5225af53050Schristosmy %deprecated_disablables = ( 5235af53050Schristos "ssl2" => undef, 5245af53050Schristos "buf-freelists" => undef, 5258fbed61eSchristos "crypto-mdebug-backtrace" => undef, 5268fbed61eSchristos "hw" => "hw", # causes cascade, but no macro 5278fbed61eSchristos "hw-padlock" => "padlockeng", 528e0ea3921Schristos "ripemd" => "rmd160", 529e0ea3921Schristos "ui" => "ui-console", 5308fbed61eSchristos "heartbeats" => undef, 5315af53050Schristos ); 5325af53050Schristos 533e0ea3921Schristos# All of the following are disabled by default: 534a89c9211Schristos 5355af53050Schristosour %disabled = ( # "what" => "comment" 5368fbed61eSchristos "fips" => "default", 5375af53050Schristos "asan" => "default", 5384261787cSchristos "buildtest-c++" => "default", 5395af53050Schristos "crypto-mdebug" => "default", 5405af53050Schristos "crypto-mdebug-backtrace" => "default", 541e0ea3921Schristos "devcryptoeng" => "default", 542e3d33c04Schristos "ec_nistp_64_gcc_128" => "default", 5435af53050Schristos "egd" => "default", 544e0ea3921Schristos "external-tests" => "default", 5455af53050Schristos "fuzz-afl" => "default", 5468fbed61eSchristos "fuzz-libfuzzer" => "default", 5478fbed61eSchristos "ktls" => "default", 548a89c9211Schristos "md2" => "default", 5495af53050Schristos "msan" => "default", 550a89c9211Schristos "rc5" => "default", 551e3d33c04Schristos "sctp" => "default", 5525af53050Schristos "ssl3" => "default", 5535af53050Schristos "ssl3-method" => "default", 5548fbed61eSchristos "trace" => "default", 5555af53050Schristos "ubsan" => "default", 5563beda010Sspz "unit-test" => "default", 557338c2544Schristos "weak-ssl-ciphers" => "default", 558a89c9211Schristos "zlib" => "default", 5595af53050Schristos "zlib-dynamic" => "default", 560a89c9211Schristos ); 561a89c9211Schristos 5625af53050Schristos# Note: => pair form used for aesthetics, not to truly make a hash table 5635af53050Schristosmy @disable_cascades = ( 5645af53050Schristos # "what" => [ "cascade", ... ] 5658fbed61eSchristos "bulk" => [ "shared", "dso", 5668fbed61eSchristos "aria", "async", "autoload-config", 5678fbed61eSchristos "blake2", "bf", "camellia", "cast", "chacha", 5688fbed61eSchristos "cmac", "cms", "cmp", "comp", "ct", 5698fbed61eSchristos "des", "dgram", "dh", "dsa", 5708fbed61eSchristos "ec", "engine", 5718fbed61eSchristos "filenames", 5728fbed61eSchristos "idea", "ktls", 5738fbed61eSchristos "md4", "multiblock", "nextprotoneg", 5748fbed61eSchristos "ocsp", "ocb", "poly1305", "psk", 5758fbed61eSchristos "rc2", "rc4", "rmd160", 5768fbed61eSchristos "seed", "siphash", "siv", 5778fbed61eSchristos "sm3", "sm4", "srp", 5788fbed61eSchristos "srtp", "ssl3-method", "ssl-trace", 5798fbed61eSchristos "ts", "ui-console", "whirlpool", 5808fbed61eSchristos "fips-securitychecks" ], 5815af53050Schristos sub { $config{processor} eq "386" } 5825af53050Schristos => [ "sse2" ], 5835af53050Schristos "ssl" => [ "ssl3" ], 5845af53050Schristos "ssl3-method" => [ "ssl3" ], 5855af53050Schristos "zlib" => [ "zlib-dynamic" ], 5865af53050Schristos "des" => [ "mdc2" ], 5878fbed61eSchristos "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ], 5885af53050Schristos "dgram" => [ "dtls", "sctp" ], 5895af53050Schristos "sock" => [ "dgram" ], 5905af53050Schristos "dtls" => [ @dtls ], 5915af53050Schristos sub { 0 == scalar grep { !$disabled{$_} } @dtls } 5925af53050Schristos => [ "dtls" ], 5935af53050Schristos 5945af53050Schristos "tls" => [ @tls ], 5955af53050Schristos sub { 0 == scalar grep { !$disabled{$_} } @tls } 5965af53050Schristos => [ "tls" ], 5975af53050Schristos 5985af53050Schristos "crypto-mdebug" => [ "crypto-mdebug-backtrace" ], 5995af53050Schristos 6008dcce544Schristos "module" => [ "dynamic-engine", "fips" ], 6018fbed61eSchristos 6028fbed61eSchristos # Without shared libraries, dynamic engines aren't possible. 6038fbed61eSchristos # This is due to them having to link with libcrypto and register features 6048fbed61eSchristos # using the ENGINE functionality, and since that relies on global tables, 6058fbed61eSchristos # those *have* to be exacty the same as the ones accessed from the app, 6068fbed61eSchristos # which cannot be guaranteed if shared libraries aren't present. 6078fbed61eSchristos # (note that even with shared libraries, both the app and dynamic engines 6088fbed61eSchristos # must be linked with the same library) 6098fbed61eSchristos "shared" => [ "dynamic-engine", "uplink" ], 6108fbed61eSchristos "dso" => [ "dynamic-engine", "module" ], 6118fbed61eSchristos # Other modules don't necessarily have to link with libcrypto, so shared 6128fbed61eSchristos # libraries do not have to be a condition to produce those. 6138fbed61eSchristos 6148fbed61eSchristos # Without position independent code, there can be no shared libraries 6158fbed61eSchristos # or modules. 6168fbed61eSchristos "pic" => [ "shared", "module" ], 6178fbed61eSchristos 6188fbed61eSchristos "engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ], 6198fbed61eSchristos "dynamic-engine" => [ "loadereng" ], 6208fbed61eSchristos "hw" => [ "padlockeng" ], 6215af53050Schristos 6225af53050Schristos # no-autoalginit is only useful when building non-shared 6238fbed61eSchristos "autoalginit" => [ "shared", "apps", "fips" ], 6245af53050Schristos 6255af53050Schristos "stdio" => [ "apps", "capieng", "egd" ], 6265af53050Schristos "apps" => [ "tests" ], 627e0ea3921Schristos "tests" => [ "external-tests" ], 6285af53050Schristos "comp" => [ "zlib" ], 629e0ea3921Schristos "sm3" => [ "sm2" ], 6305af53050Schristos sub { !$disabled{"unit-test"} } => [ "heartbeats" ], 6315af53050Schristos 6325af53050Schristos sub { !$disabled{"msan"} } => [ "asm" ], 6338fbed61eSchristos 6348fbed61eSchristos "cmac" => [ "siv" ], 6358fbed61eSchristos "legacy" => [ "md2" ], 6368fbed61eSchristos 6378fbed61eSchristos "cmp" => [ "crmf" ], 6388fbed61eSchristos 6398fbed61eSchristos "fips" => [ "fips-securitychecks", "acvp-tests" ], 6408fbed61eSchristos 6418fbed61eSchristos "deprecated-3.0" => [ "engine", "srp" ] 6425af53050Schristos ); 6435af53050Schristos 6445af53050Schristos# Avoid protocol support holes. Also disable all versions below N, if version 6455af53050Schristos# N is disabled while N+1 is enabled. 6465af53050Schristos# 6475af53050Schristosmy @list = (reverse @tls); 6485af53050Schristoswhile ((my $first, my $second) = (shift @list, shift @list)) { 6495af53050Schristos last unless @list; 6505af53050Schristos push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} } 6515af53050Schristos => [ @list ] ); 6525af53050Schristos unshift @list, $second; 6535af53050Schristos} 6545af53050Schristosmy @list = (reverse @dtls); 6555af53050Schristoswhile ((my $first, my $second) = (shift @list, shift @list)) { 6565af53050Schristos last unless @list; 6575af53050Schristos push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} } 6585af53050Schristos => [ @list ] ); 6595af53050Schristos unshift @list, $second; 6605af53050Schristos} 661a89c9211Schristos 662a89c9211Schristos# Explicit "no-..." options will be collected in %disabled along with the defaults. 6635af53050Schristos# To remove something from %disabled, use "enable-foo". 664a89c9211Schristos# For symmetry, "disable-foo" is a synonym for "no-foo". 665a89c9211Schristos 66652629741Schristos# For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with 667e0ea3921Schristos# platform specific list separators. Users from those platforms should 668e0ea3921Schristos# recognise those separators from how you set up the PATH to find executables. 669e0ea3921Schristos# The default is the Unix like separator, :, but as an exception, we also 670e0ea3921Schristos# support the space as separator. 671e0ea3921Schristosmy $list_separator_re = 672e0ea3921Schristos { VMS => qr/(?<!\^),/, 673e0ea3921Schristos MSWin32 => qr/(?<!\\);/ } -> {$^O} // qr/(?<!\\)[:\s]/; 674e0ea3921Schristos# All the "make variables" we support 675e0ea3921Schristos# Some get pre-populated for the sake of backward compatibility 676e0ea3921Schristos# (we supported those before the change to "make variable" support. 677e0ea3921Schristosmy %user = ( 678e0ea3921Schristos AR => env('AR'), 679e0ea3921Schristos ARFLAGS => [], 680e0ea3921Schristos AS => undef, 681e0ea3921Schristos ASFLAGS => [], 682e0ea3921Schristos CC => env('CC'), 6834261787cSchristos CFLAGS => [ env('CFLAGS') || () ], 684e0ea3921Schristos CXX => env('CXX'), 6854261787cSchristos CXXFLAGS => [ env('CXXFLAGS') || () ], 686e0ea3921Schristos CPP => undef, 6874261787cSchristos CPPFLAGS => [ env('CPPFLAGS') || () ], # -D, -I, -Wp, 688e0ea3921Schristos CPPDEFINES => [], # Alternative for -D 689e0ea3921Schristos CPPINCLUDES => [], # Alternative for -I 690e0ea3921Schristos CROSS_COMPILE => env('CROSS_COMPILE'), 691e0ea3921Schristos HASHBANGPERL=> env('HASHBANGPERL') || env('PERL'), 692e0ea3921Schristos LD => undef, 6934261787cSchristos LDFLAGS => [ env('LDFLAGS') || () ], # -L, -Wl, 6944261787cSchristos LDLIBS => [ env('LDLIBS') || () ], # -l 695e0ea3921Schristos MT => undef, 696e0ea3921Schristos MTFLAGS => [], 697e0ea3921Schristos PERL => env('PERL') || ($^O ne "VMS" ? $^X : "perl"), 698e0ea3921Schristos RANLIB => env('RANLIB'), 699e0ea3921Schristos RC => env('RC') || env('WINDRES'), 7004261787cSchristos RCFLAGS => [ env('RCFLAGS') || () ], 701e0ea3921Schristos RM => undef, 702e0ea3921Schristos ); 703e0ea3921Schristos# Info about what "make variables" may be prefixed with the cross compiler 704e0ea3921Schristos# prefix. This should NEVER mention any such variable with a list for value. 705e0ea3921Schristosmy @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC ); 706e0ea3921Schristos# The same but for flags given as Configure options. These are *additional* 707e0ea3921Schristos# input, as opposed to the VAR=string option that override the corresponding 708e0ea3921Schristos# config target attributes 709e0ea3921Schristosmy %useradd = ( 710e0ea3921Schristos CPPDEFINES => [], 711e0ea3921Schristos CPPINCLUDES => [], 712e0ea3921Schristos CPPFLAGS => [], 713e0ea3921Schristos CFLAGS => [], 714e0ea3921Schristos CXXFLAGS => [], 715e0ea3921Schristos LDFLAGS => [], 716e0ea3921Schristos LDLIBS => [], 7174261787cSchristos RCFLAGS => [], 718e0ea3921Schristos ); 719e0ea3921Schristos 720e0ea3921Schristosmy %user_synonyms = ( 721e0ea3921Schristos HASHBANGPERL=> 'PERL', 722e0ea3921Schristos RC => 'WINDRES', 723e0ea3921Schristos ); 724e0ea3921Schristos 725e0ea3921Schristos# Some target attributes have been renamed, this is the translation table 726e0ea3921Schristosmy %target_attr_translate =( 727e0ea3921Schristos ar => 'AR', 728e0ea3921Schristos as => 'AS', 729e0ea3921Schristos cc => 'CC', 730e0ea3921Schristos cxx => 'CXX', 731e0ea3921Schristos cpp => 'CPP', 732e0ea3921Schristos hashbangperl => 'HASHBANGPERL', 733e0ea3921Schristos ld => 'LD', 734e0ea3921Schristos mt => 'MT', 735e0ea3921Schristos ranlib => 'RANLIB', 736e0ea3921Schristos rc => 'RC', 737e0ea3921Schristos rm => 'RM', 738e0ea3921Schristos ); 739e0ea3921Schristos 740e0ea3921Schristos# Initialisers coming from 'config' scripts 741e0ea3921Schristos$config{defines} = [ split(/$list_separator_re/, env('__CNF_CPPDEFINES')) ]; 742e0ea3921Schristos$config{includes} = [ split(/$list_separator_re/, env('__CNF_CPPINCLUDES')) ]; 743e0ea3921Schristos$config{cppflags} = [ env('__CNF_CPPFLAGS') || () ]; 744e0ea3921Schristos$config{cflags} = [ env('__CNF_CFLAGS') || () ]; 745e0ea3921Schristos$config{cxxflags} = [ env('__CNF_CXXFLAGS') || () ]; 746e0ea3921Schristos$config{lflags} = [ env('__CNF_LDFLAGS') || () ]; 747e0ea3921Schristos$config{ex_libs} = [ env('__CNF_LDLIBS') || () ]; 748e0ea3921Schristos 7495af53050Schristos$config{openssl_api_defines}=[]; 7505af53050Schristos$config{openssl_sys_defines}=[]; 7518fbed61eSchristos$config{openssl_feature_defines}=[]; 7525af53050Schristos$config{options}=""; 7535af53050Schristos$config{build_type} = "release"; 754e0ea3921Schristosmy $target=""; 755a89c9211Schristos 756e0ea3921Schristosmy %cmdvars = (); # Stores FOO='blah' type arguments 7575af53050Schristosmy %unsupported_options = (); 7585af53050Schristosmy %deprecated_options = (); 759e0ea3921Schristos# If you change this, update apps/version.c 760e0ea3921Schristosmy @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom); 761e0ea3921Schristosmy @seed_sources = (); 7625af53050Schristoswhile (@argvcopy) 763a89c9211Schristos { 7645af53050Schristos $_ = shift @argvcopy; 765e0ea3921Schristos 766e0ea3921Schristos # Support env variable assignments among the options 767e0ea3921Schristos if (m|^(\w+)=(.+)?$|) 768e0ea3921Schristos { 769e0ea3921Schristos $cmdvars{$1} = $2; 770e0ea3921Schristos # Every time a variable is given as a configuration argument, 771e0ea3921Schristos # it acts as a reset if the variable. 772e0ea3921Schristos if (exists $user{$1}) 773e0ea3921Schristos { 774e0ea3921Schristos $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef; 775e0ea3921Schristos } 776e0ea3921Schristos #if (exists $useradd{$1}) 777e0ea3921Schristos # { 778e0ea3921Schristos # $useradd{$1} = []; 779e0ea3921Schristos # } 780e0ea3921Schristos next; 781e0ea3921Schristos } 782e0ea3921Schristos 7835af53050Schristos # VMS is a case insensitive environment, and depending on settings 7845af53050Schristos # out of our control, we may receive options uppercased. Let's 7855af53050Schristos # downcase at least the part before any equal sign. 7865af53050Schristos if ($^O eq "VMS") 787a89c9211Schristos { 7885af53050Schristos s/^([^=]*)/lc($1)/e; 7895af53050Schristos } 790e0ea3921Schristos 791e0ea3921Schristos # some people just can't read the instructions, clang people have to... 792e0ea3921Schristos s/^-no-(?!integrated-as)/no-/; 793a89c9211Schristos 794a89c9211Schristos # rewrite some options in "enable-..." form 795a89c9211Schristos s /^-?-?shared$/enable-shared/; 796e3d33c04Schristos s /^sctp$/enable-sctp/; 797a89c9211Schristos s /^threads$/enable-threads/; 798a89c9211Schristos s /^zlib$/enable-zlib/; 799a89c9211Schristos s /^zlib-dynamic$/enable-zlib-dynamic/; 8008fbed61eSchristos s /^fips$/enable-fips/; 801a89c9211Schristos 8025af53050Schristos if (/^(no|disable|enable)-(.+)$/) 8035af53050Schristos { 8045af53050Schristos my $word = $2; 8058fbed61eSchristos if ($word !~ m|hw(?:-.+)| # special treatment for hw regexp opt 8068fbed61eSchristos && !exists $deprecated_disablables{$word} 8078fbed61eSchristos && !grep { $word eq $_ } @disablables) 8085af53050Schristos { 8095af53050Schristos $unsupported_options{$_} = 1; 8105af53050Schristos next; 8115af53050Schristos } 8125af53050Schristos } 813a89c9211Schristos if (/^no-(.+)$/ || /^disable-(.+)$/) 814a89c9211Schristos { 8155af53050Schristos foreach my $proto ((@tls, @dtls)) 816a89c9211Schristos { 8175af53050Schristos if ($1 eq "$proto-method") 818a89c9211Schristos { 8195af53050Schristos $disabled{"$proto"} = "option($proto-method)"; 8205af53050Schristos last; 8215af53050Schristos } 8225af53050Schristos } 8235af53050Schristos if ($1 eq "dtls") 8245af53050Schristos { 8255af53050Schristos foreach my $proto (@dtls) 8265af53050Schristos { 8275af53050Schristos $disabled{$proto} = "option(dtls)"; 8285af53050Schristos } 8295af53050Schristos $disabled{"dtls"} = "option(dtls)"; 8305af53050Schristos } 8315af53050Schristos elsif ($1 eq "ssl") 8325af53050Schristos { 8335af53050Schristos # Last one of its kind 834a89c9211Schristos $disabled{"ssl3"} = "option(ssl)"; 835a89c9211Schristos } 836a89c9211Schristos elsif ($1 eq "tls") 837a89c9211Schristos { 8385af53050Schristos # XXX: Tests will fail if all SSL/TLS 8395af53050Schristos # protocols are disabled. 8405af53050Schristos foreach my $proto (@tls) 841805debc4Sspz { 8425af53050Schristos $disabled{$proto} = "option(tls)"; 8435af53050Schristos } 8445af53050Schristos } 8455af53050Schristos elsif ($1 eq "static-engine") 8465af53050Schristos { 8475af53050Schristos delete $disabled{"dynamic-engine"}; 8485af53050Schristos } 8495af53050Schristos elsif ($1 eq "dynamic-engine") 8505af53050Schristos { 8515af53050Schristos $disabled{"dynamic-engine"} = "option"; 8525af53050Schristos } 8535af53050Schristos elsif (exists $deprecated_disablables{$1}) 8545af53050Schristos { 8555af53050Schristos $deprecated_options{$_} = 1; 8565af53050Schristos if (defined $deprecated_disablables{$1}) 8575af53050Schristos { 8585af53050Schristos $disabled{$deprecated_disablables{$1}} = "option"; 8595af53050Schristos } 860805debc4Sspz } 8618fbed61eSchristos elsif ($1 =~ m|hw(?:-.+)|) # deprecate hw options in regexp form 8628fbed61eSchristos { 8638fbed61eSchristos $deprecated_options{$_} = 1; 8644261787cSchristos } 865a89c9211Schristos else 866a89c9211Schristos { 867a89c9211Schristos $disabled{$1} = "option"; 868a89c9211Schristos } 8695af53050Schristos # No longer an automatic choice 8705af53050Schristos $auto_threads = 0 if ($1 eq "threads"); 871a89c9211Schristos } 8725af53050Schristos elsif (/^enable-(.+)$/) 873a89c9211Schristos { 8745af53050Schristos if ($1 eq "static-engine") 8755af53050Schristos { 8765af53050Schristos $disabled{"dynamic-engine"} = "option"; 8775af53050Schristos } 8785af53050Schristos elsif ($1 eq "dynamic-engine") 8795af53050Schristos { 8805af53050Schristos delete $disabled{"dynamic-engine"}; 8815af53050Schristos } 8825af53050Schristos elsif ($1 eq "zlib-dynamic") 8835af53050Schristos { 8845af53050Schristos delete $disabled{"zlib"}; 8855af53050Schristos } 886a89c9211Schristos my $algo = $1; 887a89c9211Schristos delete $disabled{$algo}; 888a89c9211Schristos 8895af53050Schristos # No longer an automatic choice 8905af53050Schristos $auto_threads = 0 if ($1 eq "threads"); 891a89c9211Schristos } 8928fbed61eSchristos elsif (/^-d$/) # From older 'config' 8938fbed61eSchristos { 8948fbed61eSchristos $config{build_type} = "debug"; 8958fbed61eSchristos } 8968fbed61eSchristos elsif (/^-v$/) # From older 'config' 8978fbed61eSchristos { 8988fbed61eSchristos $guess_opts{verbose} = 1; 8998fbed61eSchristos } 9008fbed61eSchristos elsif (/^-w$/) 9018fbed61eSchristos { 9028fbed61eSchristos $guess_opts{nowait} = 1; 9038fbed61eSchristos } 9048fbed61eSchristos elsif (/^-t$/) # From older 'config' 9058fbed61eSchristos { 9068fbed61eSchristos $dryrun = 1; 9078fbed61eSchristos } 9085af53050Schristos elsif (/^--strict-warnings$/) 909cef2ee70Schristos { 9104261787cSchristos # Pretend that our strict flags is a C flag, and replace it 9114261787cSchristos # with the proper flags later on 9124261787cSchristos push @{$useradd{CFLAGS}}, '--ossl-strict-warnings'; 913cef2ee70Schristos $strict_warnings=1; 914cef2ee70Schristos } 9155af53050Schristos elsif (/^--debug$/) 916a89c9211Schristos { 9175af53050Schristos $config{build_type} = "debug"; 918a89c9211Schristos } 9195af53050Schristos elsif (/^--release$/) 9205af53050Schristos { 9215af53050Schristos $config{build_type} = "release"; 922a89c9211Schristos } 923a89c9211Schristos elsif (/^386$/) 9245af53050Schristos { $config{processor}=386; } 925a89c9211Schristos elsif (/^rsaref$/) 926a89c9211Schristos { 927a89c9211Schristos # No RSAref support any more since it's not needed. 928a89c9211Schristos # The check for the option is there so scripts aren't 929a89c9211Schristos # broken 930a89c9211Schristos } 93152629741Schristos elsif (m|^[-+/]|) 932a89c9211Schristos { 93331b855a0Sspz if (/^--prefix=(.*)$/) 934a89c9211Schristos { 9355af53050Schristos $config{prefix}=$1; 9365af53050Schristos } 9375af53050Schristos elsif (/^--api=(.*)$/) 9385af53050Schristos { 9398fbed61eSchristos my $api = $1; 9408fbed61eSchristos die "Unknown API compatibility level $api" 9418fbed61eSchristos unless defined $apitable->{$api}; 9428fbed61eSchristos $config{api}=$apitable->{$api}; 943a89c9211Schristos } 944cef2ee70Schristos elsif (/^--libdir=(.*)$/) 945cef2ee70Schristos { 9465af53050Schristos $config{libdir}=$1; 947cef2ee70Schristos } 948a89c9211Schristos elsif (/^--openssldir=(.*)$/) 949a89c9211Schristos { 9505af53050Schristos $config{openssldir}=$1; 951a89c9211Schristos } 952a89c9211Schristos elsif (/^--with-zlib-lib=(.*)$/) 953a89c9211Schristos { 9545af53050Schristos $withargs{zlib_lib}=$1; 955a89c9211Schristos } 956a89c9211Schristos elsif (/^--with-zlib-include=(.*)$/) 957a89c9211Schristos { 9585af53050Schristos $withargs{zlib_include}=$1; 959a89c9211Schristos } 9605af53050Schristos elsif (/^--with-fuzzer-lib=(.*)$/) 9614e3dcb23Sspz { 9625af53050Schristos $withargs{fuzzer_lib}=$1; 9635af53050Schristos } 9645af53050Schristos elsif (/^--with-fuzzer-include=(.*)$/) 9655af53050Schristos { 9665af53050Schristos $withargs{fuzzer_include}=$1; 9674e3dcb23Sspz } 968e0ea3921Schristos elsif (/^--with-rand-seed=(.*)$/) 9694e3dcb23Sspz { 970e0ea3921Schristos foreach my $x (split(m|,|, $1)) 971e0ea3921Schristos { 972e0ea3921Schristos die "Unknown --with-rand-seed choice $x\n" 973e0ea3921Schristos if ! grep { $x eq $_ } @known_seed_sources; 974e0ea3921Schristos push @seed_sources, $x; 9754e3dcb23Sspz } 9764e3dcb23Sspz } 9778fbed61eSchristos elsif (/^--fips-key=(.*)$/) 9788fbed61eSchristos { 9798fbed61eSchristos $user{FIPSKEY}=lc($1); 9808fbed61eSchristos die "Non-hex character in FIPS key\n" 9818fbed61eSchristos if $user{FIPSKEY} =~ /[^a-f0-9]/; 9828fbed61eSchristos die "FIPS key must have even number of characters\n" 9838fbed61eSchristos if length $1 & 1; 9848fbed61eSchristos die "FIPS key too long (64 bytes max)\n" 9858fbed61eSchristos if length $1 > 64; 9868fbed61eSchristos } 9878fbed61eSchristos elsif (/^--banner=(.*)$/) 9888fbed61eSchristos { 9898fbed61eSchristos $banner = $1 . "\n"; 9908fbed61eSchristos } 991a89c9211Schristos elsif (/^--cross-compile-prefix=(.*)$/) 992a89c9211Schristos { 993e0ea3921Schristos $user{CROSS_COMPILE}=$1; 9945af53050Schristos } 9955af53050Schristos elsif (/^--config=(.*)$/) 9965af53050Schristos { 9975af53050Schristos read_config $1; 998a89c9211Schristos } 999e0ea3921Schristos elsif (/^-l(.*)$/) 1000a89c9211Schristos { 1001e0ea3921Schristos push @{$useradd{LDLIBS}}, $_; 1002e0ea3921Schristos } 1003e0ea3921Schristos elsif (/^-framework$/) 1004e0ea3921Schristos { 1005e0ea3921Schristos push @{$useradd{LDLIBS}}, $_, shift(@argvcopy); 1006e0ea3921Schristos } 1007e0ea3921Schristos elsif (/^-L(.*)$/ or /^-Wl,/) 1008e0ea3921Schristos { 1009e0ea3921Schristos push @{$useradd{LDFLAGS}}, $_; 101031b855a0Sspz } 10115af53050Schristos elsif (/^-rpath$/ or /^-R$/) 10125af53050Schristos # -rpath is the OSF1 rpath flag 10135af53050Schristos # -R is the old Solaris rpath flag 10145af53050Schristos { 10155af53050Schristos my $rpath = shift(@argvcopy) || ""; 10165af53050Schristos $rpath .= " " if $rpath ne ""; 1017e0ea3921Schristos push @{$useradd{LDFLAGS}}, $_, $rpath; 10185af53050Schristos } 10195af53050Schristos elsif (/^-static$/) 10205af53050Schristos { 1021e0ea3921Schristos push @{$useradd{LDFLAGS}}, $_; 10225af53050Schristos } 102352629741Schristos elsif (m|^[-/]D(.*)$|) 10245af53050Schristos { 1025e0ea3921Schristos push @{$useradd{CPPDEFINES}}, $1; 1026e0ea3921Schristos } 102752629741Schristos elsif (m|^[-/]I(.*)$|) 1028e0ea3921Schristos { 1029e0ea3921Schristos push @{$useradd{CPPINCLUDES}}, $1; 1030e0ea3921Schristos } 1031e0ea3921Schristos elsif (/^-Wp,$/) 1032e0ea3921Schristos { 1033e0ea3921Schristos push @{$useradd{CPPFLAGS}}, $1; 10345af53050Schristos } 103531b855a0Sspz else # common if (/^[-+]/), just pass down... 103631b855a0Sspz { 103752629741Schristos # Treat %xx as an ASCII code (e.g. replace %20 by a space character). 103852629741Schristos # This provides a simple way to pass options with arguments separated 103952629741Schristos # by spaces without quoting (e.g. -opt%20arg translates to -opt arg). 104031b855a0Sspz $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei; 1041e0ea3921Schristos push @{$useradd{CFLAGS}}, $_; 1042e0ea3921Schristos push @{$useradd{CXXFLAGS}}, $_; 1043a89c9211Schristos } 1044a89c9211Schristos } 104552629741Schristos elsif (m|^/|) 104652629741Schristos { 104752629741Schristos # Treat %xx as an ASCII code (e.g. replace %20 by a space character). 104852629741Schristos # This provides a simple way to pass options with arguments separated 104952629741Schristos # by spaces without quoting (e.g. /opt%20arg translates to /opt arg). 105052629741Schristos $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei; 105152629741Schristos push @{$useradd{CFLAGS}}, $_; 105252629741Schristos push @{$useradd{CXXFLAGS}}, $_; 105352629741Schristos } 1054a89c9211Schristos else 1055a89c9211Schristos { 1056a89c9211Schristos die "target already defined - $target (offending arg: $_)\n" if ($target ne ""); 1057a89c9211Schristos $target=$_; 1058a89c9211Schristos } 1059a89c9211Schristos unless ($_ eq $target || /^no-/ || /^disable-/) 1060a89c9211Schristos { 1061e0ea3921Schristos # "no-..." follows later after implied deactivations 10625af53050Schristos # have been derived. (Don't take this too seriously, 1063a89c9211Schristos # we really only write OPTIONS to the Makefile out of 1064a89c9211Schristos # nostalgia.) 1065a89c9211Schristos 10665af53050Schristos if ($config{options} eq "") 10675af53050Schristos { $config{options} = $_; } 1068a89c9211Schristos else 10695af53050Schristos { $config{options} .= " ".$_; } 1070a89c9211Schristos } 10712500041cSchristos } 1072a89c9211Schristos 10735af53050Schristosif (keys %deprecated_options) 1074a89c9211Schristos { 10755af53050Schristos warn "***** Deprecated options: ", 10765af53050Schristos join(", ", keys %deprecated_options), "\n"; 10775af53050Schristos } 10785af53050Schristosif (keys %unsupported_options) 10795af53050Schristos { 10805af53050Schristos die "***** Unsupported options: ", 10815af53050Schristos join(", ", keys %unsupported_options), "\n"; 10825af53050Schristos } 1083a89c9211Schristos 1084e0ea3921Schristos# If any %useradd entry has been set, we must check that the "make 1085e0ea3921Schristos# variables" haven't been set. We start by checking of any %useradd entry 1086e0ea3921Schristos# is set. 1087e0ea3921Schristosif (grep { scalar @$_ > 0 } values %useradd) { 1088e0ea3921Schristos # Hash of env / make variables names. The possible values are: 1089e0ea3921Schristos # 1 - "make vars" 1090e0ea3921Schristos # 2 - %useradd entry set 1091e0ea3921Schristos # 3 - both set 1092e0ea3921Schristos my %detected_vars = 1093e0ea3921Schristos map { my $v = 0; 1094e0ea3921Schristos $v += 1 if $cmdvars{$_}; 1095e0ea3921Schristos $v += 2 if @{$useradd{$_}}; 1096e0ea3921Schristos $_ => $v } 1097e0ea3921Schristos keys %useradd; 1098e0ea3921Schristos 1099e0ea3921Schristos # If any of the corresponding "make variables" is set, we error 1100e0ea3921Schristos if (grep { $_ & 1 } values %detected_vars) { 1101e0ea3921Schristos my $names = join(', ', grep { $detected_vars{$_} > 0 } 1102e0ea3921Schristos sort keys %detected_vars); 1103e0ea3921Schristos die <<"_____"; 1104e0ea3921Schristos***** Mixing make variables and additional compiler/linker flags as 1105e0ea3921Schristos***** configure command line option is not permitted. 1106e0ea3921Schristos***** Affected make variables: $names 1107e0ea3921Schristos_____ 1108e0ea3921Schristos } 1109e0ea3921Schristos} 1110e0ea3921Schristos 1111e0ea3921Schristos# Check through all supported command line variables to see if any of them 1112e0ea3921Schristos# were set, and canonicalise the values we got. If no compiler or linker 1113e0ea3921Schristos# flag or anything else that affects %useradd was set, we also check the 1114e0ea3921Schristos# environment for values. 1115e0ea3921Schristosmy $anyuseradd = 1116e0ea3921Schristos grep { defined $_ && (ref $_ ne 'ARRAY' || @$_) } values %useradd; 1117e0ea3921Schristosforeach (keys %user) { 1118e0ea3921Schristos my $value = $cmdvars{$_}; 1119e0ea3921Schristos $value //= env($_) unless $anyuseradd; 1120e0ea3921Schristos $value //= 1121e0ea3921Schristos defined $user_synonyms{$_} ? $cmdvars{$user_synonyms{$_}} : undef; 1122e0ea3921Schristos $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef 1123e0ea3921Schristos unless $anyuseradd; 1124e0ea3921Schristos 1125e0ea3921Schristos if (defined $value) { 1126e0ea3921Schristos if (ref $user{$_} eq 'ARRAY') { 112752629741Schristos if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') { 1128e0ea3921Schristos $user{$_} = [ split /$list_separator_re/, $value ]; 112952629741Schristos } else { 113052629741Schristos $user{$_} = [ $value ]; 113152629741Schristos } 1132e0ea3921Schristos } elsif (!defined $user{$_}) { 1133e0ea3921Schristos $user{$_} = $value; 1134e0ea3921Schristos } 1135e0ea3921Schristos } 1136e0ea3921Schristos} 1137e0ea3921Schristos 1138e0ea3921Schristosif (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ()) 11395af53050Schristos && !$disabled{shared} 11405af53050Schristos && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) { 11415af53050Schristos die "***** Cannot simultaneously use -rpath, shared libraries, and\n", 11425af53050Schristos "***** any of asan, msan or ubsan\n"; 1143a89c9211Schristos} 1144a89c9211Schristos 11458fbed61eSchristos# If no target was given, try guessing. 11468fbed61eSchristosunless ($target) { 11478fbed61eSchristos my %system_config = OpenSSL::config::get_platform(%guess_opts, %user); 11488fbed61eSchristos 11498fbed61eSchristos # The $system_config{disable} is used to populate %disabled with 11508fbed61eSchristos # entries that aren't already there. 11518fbed61eSchristos foreach ( @{$system_config{disable} // []} ) { 11528fbed61eSchristos $disabled{$_} = 'system' unless defined $disabled{$_}; 11538fbed61eSchristos } 11548fbed61eSchristos delete $system_config{disable}; 11558fbed61eSchristos 11568fbed61eSchristos # Override config entries with stuff from the guesser. 11578fbed61eSchristos # It's assumed that this really is nothing new. 11588fbed61eSchristos %config = ( %config, %system_config ); 11598fbed61eSchristos $target = $system_config{target}; 11608fbed61eSchristos} 11618fbed61eSchristos 11624261787cSchristossub disable { 11634261787cSchristos my $disable_type = shift; 11644261787cSchristos 11654261787cSchristos for (@_) { 11664261787cSchristos $disabled{$_} = $disable_type; 11674261787cSchristos } 11684261787cSchristos 11694261787cSchristos my @tocheckfor = (@_ ? @_ : keys %disabled); 11705af53050Schristos while (@tocheckfor) { 11715af53050Schristos my %new_tocheckfor = (); 11725af53050Schristos my @cascade_copy = (@disable_cascades); 11735af53050Schristos while (@cascade_copy) { 11744261787cSchristos my ($test, $descendents) = 11754261787cSchristos (shift @cascade_copy, shift @cascade_copy); 11765af53050Schristos if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) { 11775af53050Schristos foreach (grep { !defined($disabled{$_}) } @$descendents) { 11784261787cSchristos $new_tocheckfor{$_} = 1; $disabled{$_} = "cascade"; 1179a89c9211Schristos } 1180a89c9211Schristos } 11815af53050Schristos } 11825af53050Schristos @tocheckfor = (keys %new_tocheckfor); 1183a89c9211Schristos } 11844261787cSchristos} 11854261787cSchristosdisable(); # First cascade run 1186a89c9211Schristos 11875af53050Schristosour $die = sub { die @_; }; 1188a89c9211Schristosif ($target eq "TABLE") { 11895af53050Schristos local $die = sub { warn @_; }; 11905af53050Schristos foreach (sort keys %table) { 11915af53050Schristos print_table_entry($_, "TABLE"); 1192a89c9211Schristos } 1193a89c9211Schristos exit 0; 1194a89c9211Schristos} 1195a89c9211Schristos 1196a89c9211Schristosif ($target eq "LIST") { 1197a89c9211Schristos foreach (sort keys %table) { 11985af53050Schristos print $_,"\n" unless $table{$_}->{template}; 1199a89c9211Schristos } 1200a89c9211Schristos exit 0; 1201a89c9211Schristos} 1202a89c9211Schristos 12035af53050Schristosif ($target eq "HASH") { 12045af53050Schristos local $die = sub { warn @_; }; 12055af53050Schristos print "%table = (\n"; 12065af53050Schristos foreach (sort keys %table) { 12075af53050Schristos print_table_entry($_, "HASH"); 12085af53050Schristos } 12095af53050Schristos exit 0; 12105af53050Schristos} 12115af53050Schristos 12128fbed61eSchristosprint "Configuring OpenSSL version $config{full_version} "; 12138fbed61eSchristosprint "for target $target\n"; 1214e0ea3921Schristos 1215e0ea3921Schristosif (scalar(@seed_sources) == 0) { 1216e0ea3921Schristos print "Using os-specific seed configuration\n"; 1217e0ea3921Schristos push @seed_sources, 'os'; 1218e0ea3921Schristos} 12194a7cf967Schristosif (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) { 12204a7cf967Schristos delete $disabled{'egd'}; 12214a7cf967Schristos} 1222e0ea3921Schristosif (scalar(grep { $_ eq 'none' } @seed_sources) > 0) { 1223e0ea3921Schristos die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1; 1224e0ea3921Schristos warn <<_____ if scalar(@seed_sources) == 1; 1225e0ea3921Schristos 1226bf8eace1Schristos============================== WARNING =============================== 1227bf8eace1SchristosYou have selected the --with-rand-seed=none option, which effectively 1228bf8eace1Schristosdisables automatic reseeding of the OpenSSL random generator. 1229bf8eace1SchristosAll operations depending on the random generator such as creating keys 1230bf8eace1Schristoswill not work unless the random generator is seeded manually by the 1231bf8eace1Schristosapplication. 1232bf8eace1Schristos 1233bf8eace1SchristosPlease read the 'Note on random number generation' section in the 12348fbed61eSchristosINSTALL.md instructions and the RAND_DRBG(7) manual page for more 12358fbed61eSchristosdetails. 1236bf8eace1Schristos============================== WARNING =============================== 1237bf8eace1Schristos 1238e0ea3921Schristos_____ 1239e0ea3921Schristos} 12408fbed61eSchristospush @{$config{openssl_feature_defines}}, 1241e0ea3921Schristos map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" } 1242e0ea3921Schristos @seed_sources; 1243e0ea3921Schristos 12445af53050Schristos# Backward compatibility? 1245a89c9211Schristosif ($target =~ m/^CygWin32(-.*)$/) { 1246a89c9211Schristos $target = "Cygwin".$1; 1247a89c9211Schristos} 1248a89c9211Schristos 12495af53050Schristos# Support for legacy targets having a name starting with 'debug-' 12505af53050Schristosmy ($d, $t) = $target =~ m/^(debug-)?(.*)$/; 12515af53050Schristosif ($d) { 12525af53050Schristos $config{build_type} = "debug"; 12535af53050Schristos 12545af53050Schristos # If we do not find debug-foo in the table, the target is set to foo. 12555af53050Schristos if (!$table{$target}) { 12565af53050Schristos $target = $t; 12575af53050Schristos } 12585af53050Schristos} 12592500041cSchristos 12608fbed61eSchristosif ($target) { 12618fbed61eSchristos # It's possible that we have different config targets for specific 12628fbed61eSchristos # toolchains, so we try to detect them, and go for the plain config 12638fbed61eSchristos # target if not. 12648fbed61eSchristos my $found; 12658fbed61eSchristos foreach ( ( "$target-$user{CC}", "$target", undef ) ) { 12668fbed61eSchristos $found=$_ if $table{$_} && !$table{$_}->{template}; 12678fbed61eSchristos last if $found; 12688fbed61eSchristos } 12698fbed61eSchristos $target = $found; 12708fbed61eSchristos} else { 12718fbed61eSchristos # If we don't have a config target now, we try the C compiler as we 12728fbed61eSchristos # fallback 12738fbed61eSchristos my $cc = $user{CC} // 'cc'; 12748fbed61eSchristos $target = $cc if $table{$cc} && !$table{$cc}->{template}; 12758fbed61eSchristos} 12768fbed61eSchristos 12778fbed61eSchristos&usage unless $target; 12788fbed61eSchristos 12798fbed61eSchristosexit 0 if $dryrun; # From older 'config' 12802500041cSchristos 12815af53050Schristos$config{target} = $target; 12825af53050Schristosmy %target = resolve_config($target); 12835af53050Schristos 1284e0ea3921Schristosforeach (keys %target_attr_translate) { 1285e0ea3921Schristos $target{$target_attr_translate{$_}} = $target{$_} 1286e0ea3921Schristos if $target{$_}; 1287e0ea3921Schristos delete $target{$_}; 1288e0ea3921Schristos} 1289e0ea3921Schristos 12905af53050Schristos%target = ( %{$table{DEFAULTS}}, %target ); 12915af53050Schristos 1292e0ea3921Schristosmy %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}}); 1293e0ea3921Schristos$config{conf_files} = [ sort keys %conf_files ]; 1294e0ea3921Schristos 12954261787cSchristos# Using sub disable within these loops may prove fragile, so we run 12964261787cSchristos# a cascade afterwards 1297e0ea3921Schristosforeach my $feature (@{$target{disable}}) { 1298e0ea3921Schristos if (exists $deprecated_disablables{$feature}) { 1299e0ea3921Schristos warn "***** config $target disables deprecated feature $feature\n"; 1300e0ea3921Schristos } elsif (!grep { $feature eq $_ } @disablables) { 1301e0ea3921Schristos die "***** config $target disables unknown feature $feature\n"; 1302e0ea3921Schristos } 1303e0ea3921Schristos $disabled{$feature} = 'config'; 1304e0ea3921Schristos} 1305e0ea3921Schristosforeach my $feature (@{$target{enable}}) { 130665b9e620Schristos if ("default" eq ($disabled{$feature} // "")) { 1307e0ea3921Schristos if (exists $deprecated_disablables{$feature}) { 1308e0ea3921Schristos warn "***** config $target enables deprecated feature $feature\n"; 1309e0ea3921Schristos } elsif (!grep { $feature eq $_ } @disablables) { 1310e0ea3921Schristos die "***** config $target enables unknown feature $feature\n"; 1311e0ea3921Schristos } 131265b9e620Schristos delete $disabled{$feature}; 1313e0ea3921Schristos } 1314e0ea3921Schristos} 13158fbed61eSchristos 13168fbed61eSchristos# If uplink_arch isn't defined, disable uplink 13178fbed61eSchristos$disabled{uplink} = 'no uplink_arch' unless (defined $target{uplink_arch}); 13188fbed61eSchristos# If asm_arch isn't defined, disable asm 13198fbed61eSchristos$disabled{asm} = 'no asm_arch' unless (defined $target{asm_arch}); 13208fbed61eSchristos 13214261787cSchristosdisable(); # Run a cascade now 1322e0ea3921Schristos 1323e0ea3921Schristos$target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX}; 1324e0ea3921Schristos$target{cxxflags}//=$target{cflags} if $target{CXX}; 13258fbed61eSchristos$target{exe_extension}=".exe" if ($config{target} eq "DJGPP"); 13265af53050Schristos$target{exe_extension}=".pm" if ($config{target} =~ /vos/); 13275af53050Schristos 1328e0ea3921Schristos# Fill %config with values from %user, and in case those are undefined or 1329e0ea3921Schristos# empty, use values from %target (acting as a default). 1330e0ea3921Schristosforeach (keys %user) { 1331e0ea3921Schristos my $ref_type = ref $user{$_}; 13325af53050Schristos 1333e0ea3921Schristos # Temporary function. Takes an intended ref type (empty string or "ARRAY") 1334e0ea3921Schristos # and a value that's to be coerced into that type. 1335e0ea3921Schristos my $mkvalue = sub { 1336e0ea3921Schristos my $type = shift; 1337e0ea3921Schristos my $value = shift; 1338e0ea3921Schristos my $undef_p = shift; 13395af53050Schristos 1340e0ea3921Schristos die "Too many arguments for \$mkvalue" if @_; 1341e0ea3921Schristos 1342e0ea3921Schristos while (ref $value eq 'CODE') { 1343e0ea3921Schristos $value = $value->(); 1344e0ea3921Schristos } 1345e0ea3921Schristos 1346e0ea3921Schristos if ($type eq 'ARRAY') { 1347e0ea3921Schristos return undef unless defined $value; 1348e0ea3921Schristos return undef if ref $value ne 'ARRAY' && !$value; 1349e0ea3921Schristos return undef if ref $value eq 'ARRAY' && !@$value; 1350e0ea3921Schristos return [ $value ] unless ref $value eq 'ARRAY'; 1351e0ea3921Schristos } 1352e0ea3921Schristos return undef unless $value; 1353e0ea3921Schristos return $value; 1354e0ea3921Schristos }; 1355e0ea3921Schristos 1356e0ea3921Schristos $config{$_} = 1357e0ea3921Schristos $mkvalue->($ref_type, $user{$_}) 1358e0ea3921Schristos || $mkvalue->($ref_type, $target{$_}); 1359e0ea3921Schristos delete $config{$_} unless defined $config{$_}; 1360e0ea3921Schristos} 13615af53050Schristos 13624261787cSchristos# Finish up %config by appending things the user gave us on the command line 13634261787cSchristos# apart from "make variables" 13644261787cSchristosforeach (keys %useradd) { 13654261787cSchristos # The must all be lists, so we assert that here 13664261787cSchristos die "internal error: \$useradd{$_} isn't an ARRAY\n" 13674261787cSchristos unless ref $useradd{$_} eq 'ARRAY'; 13684261787cSchristos 13694261787cSchristos if (defined $config{$_}) { 13704261787cSchristos push @{$config{$_}}, @{$useradd{$_}}; 13714261787cSchristos } else { 13724261787cSchristos $config{$_} = [ @{$useradd{$_}} ]; 13734261787cSchristos } 13744261787cSchristos} 13754261787cSchristos# At this point, we can forget everything about %user and %useradd, 13764261787cSchristos# because it's now all been merged into the corresponding $config entry 13774261787cSchristos 1378b46c97feSchristosif ($config{prefix} && !$config{CROSS_COMPILE}) { 1379b46c97feSchristos die "Directory given with --prefix MUST be absolute\n" 1380b46c97feSchristos unless file_name_is_absolute($config{prefix}); 1381b46c97feSchristos} 1382b46c97feSchristos 13838fbed61eSchristosif (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) { 1384c50ed29dSchristos disable('static', 'pic', 'threads'); 1385c50ed29dSchristos} 1386c50ed29dSchristos 13875af53050Schristos# Allow overriding the build file name 1388e0ea3921Schristos$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile"; 13895af53050Schristos 13905af53050Schristos# Make sure build_scheme is consistent. 13915af53050Schristos$target{build_scheme} = [ $target{build_scheme} ] 13925af53050Schristos if ref($target{build_scheme}) ne "ARRAY"; 13935af53050Schristos 13945af53050Schristosmy ($builder, $builder_platform, @builder_opts) = 13955af53050Schristos @{$target{build_scheme}}; 13965af53050Schristos 1397be43b372Schristosforeach my $checker (($builder_platform."-".$config{build_file}."-checker.pm", 13985af53050Schristos $builder_platform."-checker.pm")) { 13995af53050Schristos my $checker_path = catfile($srcdir, "Configurations", $checker); 14005af53050Schristos if (-f $checker_path) { 14015af53050Schristos my $fn = $ENV{CONFIGURE_CHECKER_WARN} 14025af53050Schristos ? sub { warn $@; } : sub { die $@; }; 14035af53050Schristos if (! do $checker_path) { 14045af53050Schristos if ($@) { 14055af53050Schristos $fn->($@); 14065af53050Schristos } elsif ($!) { 14075af53050Schristos $fn->($!); 14085af53050Schristos } else { 14095af53050Schristos $fn->("The detected tools didn't match the platform\n"); 14105af53050Schristos } 14115af53050Schristos } 14125af53050Schristos last; 14135af53050Schristos } 14145af53050Schristos} 14155af53050Schristos 14165af53050Schristospush @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release"; 14175af53050Schristos 1418e0ea3921Schristosif ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m) 1419a89c9211Schristos { 1420e0ea3921Schristos push @{$config{cflags}}, "-mno-cygwin"; 1421e0ea3921Schristos push @{$config{cxxflags}}, "-mno-cygwin" if $config{CXX}; 1422e0ea3921Schristos push @{$config{shared_ldflag}}, "-mno-cygwin"; 1423a89c9211Schristos } 1424a89c9211Schristos 1425e0ea3921Schristosif ($target =~ /linux.*-mips/ && !$disabled{asm} 1426d6e24a89Schristos && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) { 142731b855a0Sspz # minimally required architecture flags for assembly modules 1428e0ea3921Schristos my $value; 1429e0ea3921Schristos $value = '-mips2' if ($target =~ /mips32/); 1430e0ea3921Schristos $value = '-mips3' if ($target =~ /mips64/); 1431e0ea3921Schristos unshift @{$config{cflags}}, $value; 1432e0ea3921Schristos unshift @{$config{cxxflags}}, $value if $config{CXX}; 1433a89c9211Schristos} 1434a89c9211Schristos 14355af53050Schristos# If threads aren't disabled, check how possible they are 14365af53050Schristosunless ($disabled{threads}) { 14375af53050Schristos if ($auto_threads) { 14385af53050Schristos # Enabled by default, disable it forcibly if unavailable 14395af53050Schristos if ($target{thread_scheme} eq "(unknown)") { 14404261787cSchristos disable("unavailable", 'threads'); 1441a89c9211Schristos } 14425af53050Schristos } else { 14435af53050Schristos # The user chose to enable threads explicitly, let's see 14445af53050Schristos # if there's a chance that's possible 14455af53050Schristos if ($target{thread_scheme} eq "(unknown)") { 14465af53050Schristos # If the user asked for "threads" and we don't have internal 14475af53050Schristos # knowledge how to do it, [s]he is expected to provide any 14485af53050Schristos # system-dependent compiler options that are necessary. We 14495af53050Schristos # can't truly check that the given options are correct, but 14505af53050Schristos # we expect the user to know what [s]He is doing. 14514261787cSchristos if (!@{$config{CFLAGS}} && !@{$config{CPPDEFINES}}) { 14525af53050Schristos die "You asked for multi-threading support, but didn't\n" 14535af53050Schristos ,"provide any system-specific compiler options\n"; 14545af53050Schristos } 14555af53050Schristos } 1456a89c9211Schristos } 1457a89c9211Schristos} 1458a89c9211Schristos 14598fbed61eSchristos# Find out if clang's sanitizers have been enabled with -fsanitize 14608fbed61eSchristos# flags and ensure that the corresponding %disabled elements area 14618fbed61eSchristos# removed to reflect that the sanitizers are indeed enabled. 14628fbed61eSchristosmy %detected_sanitizers = (); 14638fbed61eSchristosforeach (grep /^-fsanitize=/, @{$config{CFLAGS} || []}) { 14648fbed61eSchristos (my $checks = $_) =~ s/^-fsanitize=//; 14658fbed61eSchristos foreach (split /,/, $checks) { 14668fbed61eSchristos my $d = { address => 'asan', 14678fbed61eSchristos undefined => 'ubsan', 14688fbed61eSchristos memory => 'msan' } -> {$_}; 14698fbed61eSchristos next unless defined $d; 14708fbed61eSchristos 14718fbed61eSchristos $detected_sanitizers{$d} = 1; 14728fbed61eSchristos if (defined $disabled{$d}) { 14738fbed61eSchristos die "***** Conflict between disabling $d and enabling $_ sanitizer" 14748fbed61eSchristos if $disabled{$d} ne "default"; 14758fbed61eSchristos delete $disabled{$d}; 14768fbed61eSchristos } 14778fbed61eSchristos } 14788fbed61eSchristos} 14798fbed61eSchristos 14805af53050Schristos# If threads still aren't disabled, add a C macro to ensure the source 14815af53050Schristos# code knows about it. Any other flag is taken care of by the configs. 14825af53050Schristosunless($disabled{threads}) { 14838fbed61eSchristos push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS"; 14845af53050Schristos} 14855af53050Schristos 1486e0ea3921Schristosmy $no_shared_warn=0; 14878fbed61eSchristosif (($target{shared_target} // '') eq "") 14885af53050Schristos { 14895af53050Schristos $no_shared_warn = 1 1490e0ea3921Schristos if (!$disabled{shared} || !$disabled{"dynamic-engine"}); 14914261787cSchristos disable('no-shared-target', 'pic'); 14925af53050Schristos } 14935af53050Schristos 14945af53050Schristosif ($disabled{"dynamic-engine"}) { 14955af53050Schristos $config{dynamic_engines} = 0; 14965af53050Schristos} else { 14975af53050Schristos $config{dynamic_engines} = 1; 14985af53050Schristos} 14995af53050Schristos 15008fbed61eSchristosunless ($disabled{asan} || defined $detected_sanitizers{asan}) { 1501e0ea3921Schristos push @{$config{cflags}}, "-fsanitize=address"; 15025af53050Schristos} 15035af53050Schristos 15048fbed61eSchristosunless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) { 15058fbed61eSchristos push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC"; 15065af53050Schristos} 15075af53050Schristos 15088fbed61eSchristosunless ($disabled{msan} || defined $detected_sanitizers{msan}) { 1509e0ea3921Schristos push @{$config{cflags}}, "-fsanitize=memory"; 15105af53050Schristos} 15115af53050Schristos 15125af53050Schristosunless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} 15135af53050Schristos && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) { 1514e0ea3921Schristos push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g"; 1515e0ea3921Schristos push @{$config{cxxflags}}, "-fno-omit-frame-pointer", "-g" if $config{CXX}; 15165af53050Schristos} 1517a89c9211Schristos# 1518a89c9211Schristos# Platform fix-ups 1519a89c9211Schristos# 1520a89c9211Schristos 15215af53050Schristos# This saves the build files from having to check 15225af53050Schristosif ($disabled{pic}) 1523a89c9211Schristos { 1524e0ea3921Schristos foreach (qw(shared_cflag shared_cxxflag shared_cppflag 1525e0ea3921Schristos shared_defines shared_includes shared_ldflag 1526e0ea3921Schristos module_cflags module_cxxflags module_cppflags 1527e0ea3921Schristos module_defines module_includes module_lflags)) 1528e0ea3921Schristos { 1529e0ea3921Schristos delete $config{$_}; 1530e0ea3921Schristos $target{$_} = ""; 1531e0ea3921Schristos } 153231b855a0Sspz } 153331b855a0Sspzelse 153431b855a0Sspz { 1535e0ea3921Schristos push @{$config{lib_defines}}, "OPENSSL_PIC"; 153631b855a0Sspz } 15375af53050Schristos 15385af53050Schristosif ($target{sys_id} ne "") 1539a89c9211Schristos { 15405af53050Schristos push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}"; 1541a89c9211Schristos } 15425af53050Schristos 15434261787cSchristosmy %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC}); 15444261787cSchristosmy %predefined_CXX = $config{CXX} 15454261787cSchristos ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX}) 15464261787cSchristos : (); 15475af53050Schristos 15488fbed61eSchristosunless ($disabled{asm}) { 15498fbed61eSchristos # big endian systems can use ELFv2 ABI 15508fbed61eSchristos if ($target eq "linux-ppc64") { 15518fbed61eSchristos $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2); 15528fbed61eSchristos } 15538fbed61eSchristos} 15548fbed61eSchristos 1555e0ea3921Schristos# Check for makedepend capabilities. 15565af53050Schristosif (!$disabled{makedepend}) { 15578fbed61eSchristos # If the attribute makedep_scheme is defined, then we assume that the 15588fbed61eSchristos # config target and its associated build file are programmed to deal 15598fbed61eSchristos # with it. 15608fbed61eSchristos # If makedep_scheme is undefined, we go looking for GCC compatible 15618fbed61eSchristos # dependency making, and if that's not available, we try to fall back 15628fbed61eSchristos # on 'makedepend'. 15638fbed61eSchristos if ($target{makedep_scheme}) { 15648fbed61eSchristos $config{makedep_scheme} = $target{makedep_scheme}; 15658fbed61eSchristos # If the makedepcmd attribute is defined, copy it. If not, the 15668fbed61eSchristos # build files will have to fend for themselves. 15678fbed61eSchristos $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd}; 15684261787cSchristos } elsif (($predefined_C{__GNUC__} // -1) >= 3 15694261787cSchristos && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) { 15705af53050Schristos # We know that GNU C version 3 and up as well as all clang 15712500041cSchristos # versions support dependency generation, but Xcode did not 15722500041cSchristos # handle $cc -M before clang support (but claims __GNUC__ = 3) 15738fbed61eSchristos $config{makedep_scheme} = 'gcc'; 15745af53050Schristos } else { 15758fbed61eSchristos # In all other cases, we look for 'makedepend', and set the 15768fbed61eSchristos # makedep_scheme value if we found it. 15778fbed61eSchristos $config{makedepcmd} = which('makedepend'); 15788fbed61eSchristos $config{makedep_scheme} = 'makedepend' if $config{makedepcmd}; 15795af53050Schristos } 15808fbed61eSchristos 15818fbed61eSchristos # If no depend scheme is set, we disable makedepend 15828fbed61eSchristos disable('unavailable', 'makedepend') unless $config{makedep_scheme}; 15835af53050Schristos} 1584e0ea3921Schristos 1585*7d9ffdb3Schristosif (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS' && !$predefined_C{_AIX}) { 1586e0ea3921Schristos # probe for -Wa,--noexecstack option... 15874261787cSchristos if ($predefined_C{__clang__}) { 1588e0ea3921Schristos # clang has builtin assembler, which doesn't recognize --help, 1589e0ea3921Schristos # but it apparently recognizes the option in question on all 1590e0ea3921Schristos # supported platforms even when it's meaningless. In other words 1591e0ea3921Schristos # probe would fail, but probed option always accepted... 1592e0ea3921Schristos push @{$config{cflags}}, "-Wa,--noexecstack", "-Qunused-arguments"; 1593e0ea3921Schristos } else { 1594e0ea3921Schristos my $cc = $config{CROSS_COMPILE}.$config{CC}; 1595e0ea3921Schristos open(PIPE, "$cc -Wa,--help -c -o null.$$.o -x assembler /dev/null 2>&1 |"); 1596e0ea3921Schristos while(<PIPE>) { 1597e0ea3921Schristos if (m/--noexecstack/) { 1598e0ea3921Schristos push @{$config{cflags}}, "-Wa,--noexecstack"; 1599e0ea3921Schristos last; 16005af53050Schristos } 1601e0ea3921Schristos } 1602e0ea3921Schristos close(PIPE); 1603e0ea3921Schristos unlink("null.$$.o"); 1604e0ea3921Schristos } 1605e0ea3921Schristos} 16065af53050Schristos 16075af53050Schristos# Deal with bn_ops ################################################### 16085af53050Schristos 16095af53050Schristos$config{bn_ll} =0; 16105af53050Schristosmy $def_int="unsigned int"; 16115af53050Schristos$config{rc4_int} =$def_int; 16125af53050Schristos($config{b64l},$config{b64},$config{b32})=(0,0,1); 16135af53050Schristos 16145af53050Schristosmy $count = 0; 16155af53050Schristosforeach (sort split(/\s+/,$target{bn_ops})) { 16165af53050Schristos $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/; 16175af53050Schristos $config{bn_ll}=1 if $_ eq 'BN_LLONG'; 16185af53050Schristos $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR'; 16195af53050Schristos ($config{b64l},$config{b64},$config{b32}) 16205af53050Schristos =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT'; 16215af53050Schristos ($config{b64l},$config{b64},$config{b32}) 16225af53050Schristos =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG'; 16235af53050Schristos ($config{b64l},$config{b64},$config{b32}) 16245af53050Schristos =(0,0,1) if $_ eq 'THIRTY_TWO_BIT'; 16255af53050Schristos} 16265af53050Schristosdie "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n" 16275af53050Schristos if $count > 1; 16285af53050Schristos 16298fbed61eSchristos$config{api} = $config{major} * 10000 + $config{minor} * 100 16308fbed61eSchristos unless $config{api}; 16318fbed61eSchristosforeach (keys %$apitable) { 16328fbed61eSchristos $disabled{"deprecated-$_"} = "deprecation" 16338fbed61eSchristos if $disabled{deprecated} && $config{api} >= $apitable->{$_}; 16348fbed61eSchristos} 16358fbed61eSchristos 16368fbed61eSchristosdisable(); # Run a cascade now 16375af53050Schristos 16385af53050Schristos# Hack cflags for better warnings (dev option) ####################### 1639a89c9211Schristos 1640e0ea3921Schristos# "Stringify" the C and C++ flags string. This permits it to be made part of 1641e0ea3921Schristos# a string and works as well on command lines. 1642e0ea3921Schristos$config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } 1643e0ea3921Schristos @{$config{cflags}} ]; 1644e0ea3921Schristos$config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } 1645e0ea3921Schristos @{$config{cxxflags}} ] if $config{CXX}; 1646a89c9211Schristos 16478fbed61eSchristos$config{openssl_api_defines} = [ 16488fbed61eSchristos "OPENSSL_CONFIGURED_API=".$config{api}, 16498fbed61eSchristos]; 165031b855a0Sspz 16514261787cSchristosmy @strict_warnings_collection=(); 165231b855a0Sspzif ($strict_warnings) 165331b855a0Sspz { 1654cef2ee70Schristos my $wopt; 16554261787cSchristos my $gccver = $predefined_C{__GNUC__} // -1; 1656e0ea3921Schristos 165752629741Schristos if ($gccver >= 4) 165852629741Schristos { 16594261787cSchristos push @strict_warnings_collection, @gcc_devteam_warn; 16604261787cSchristos push @strict_warnings_collection, @clang_devteam_warn 16614261787cSchristos if (defined($predefined_C{__clang__})); 1662261bb388Schristos } 166352629741Schristos elsif ($config{target} =~ /^VC-/) 166452629741Schristos { 166552629741Schristos push @strict_warnings_collection, @cl_devteam_warn; 166652629741Schristos } 166752629741Schristos else 166852629741Schristos { 166952629741Schristos warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC" 167052629741Schristos } 167152629741Schristos } 16724261787cSchristos 16734261787cSchristos$config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings' 16744261787cSchristos ? @strict_warnings_collection 16754261787cSchristos : ( $_ ) } 16764261787cSchristos @{$config{CFLAGS}} ]; 1677cef2ee70Schristos 16785af53050Schristosunless ($disabled{afalgeng}) { 16795af53050Schristos $config{afalgeng}=""; 1680e0ea3921Schristos if (grep { $_ eq 'afalgeng' } @{$target{enable}}) { 16815af53050Schristos my $minver = 4*10000 + 1*100 + 0; 1682e0ea3921Schristos if ($config{CROSS_COMPILE} eq "") { 16835af53050Schristos my $verstr = `uname -r`; 16845af53050Schristos my ($ma, $mi1, $mi2) = split("\\.", $verstr); 16855af53050Schristos ($mi2) = $mi2 =~ /(\d+)/; 16865af53050Schristos my $ver = $ma*10000 + $mi1*100 + $mi2; 16875af53050Schristos if ($ver < $minver) { 16884261787cSchristos disable('too-old-kernel', 'afalgeng'); 1689a89c9211Schristos } else { 16905af53050Schristos push @{$config{engdirs}}, "afalg"; 16915af53050Schristos } 1692a89c9211Schristos } else { 16934261787cSchristos disable('cross-compiling', 'afalgeng'); 1694a89c9211Schristos } 16955af53050Schristos } else { 16964261787cSchristos disable('not-linux', 'afalgeng'); 1697a89c9211Schristos } 1698a89c9211Schristos} 1699a89c9211Schristos 170052629741Schristosunless ($disabled{devcryptoeng}) { 170152629741Schristos if ($target =~ m/^BSD/) { 170252629741Schristos my $maxver = 5*100 + 7; 170352629741Schristos my $sysstr = `uname -s`; 170452629741Schristos my $verstr = `uname -r`; 170552629741Schristos $sysstr =~ s|\R$||; 170652629741Schristos $verstr =~ s|\R$||; 170752629741Schristos my ($ma, $mi, @rest) = split m|\.|, $verstr; 170852629741Schristos my $ver = $ma*100 + $mi; 170952629741Schristos if ($sysstr eq 'OpenBSD' && $ver >= $maxver) { 171052629741Schristos disable('too-new-kernel', 'devcryptoeng'); 171152629741Schristos } 171252629741Schristos } 171352629741Schristos} 17145af53050Schristos 17158fbed61eSchristosunless ($disabled{ktls}) { 17168fbed61eSchristos $config{ktls}=""; 17178fbed61eSchristos my $cc = $config{CROSS_COMPILE}.$config{CC}; 17188fbed61eSchristos if ($target =~ m/^linux/) { 17198fbed61eSchristos system("printf '#include <sys/types.h>\n#include <linux/tls.h>' | $cc -E - >/dev/null 2>&1"); 17208fbed61eSchristos if ($? != 0) { 17218fbed61eSchristos disable('too-old-kernel', 'ktls'); 17228fbed61eSchristos } 17238fbed61eSchristos } elsif ($target =~ m/^BSD/) { 17248fbed61eSchristos system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1"); 17258fbed61eSchristos if ($? != 0) { 17268fbed61eSchristos disable('too-old-freebsd', 'ktls'); 17278fbed61eSchristos } 17288fbed61eSchristos } else { 17298fbed61eSchristos disable('not-linux-or-freebsd', 'ktls'); 17308fbed61eSchristos } 17318fbed61eSchristos} 17328fbed61eSchristos 17338fbed61eSchristospush @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls}); 17348fbed61eSchristos 17354261787cSchristos# Get the extra flags used when building shared libraries and modules. We 17364261787cSchristos# do this late because some of them depend on %disabled. 1737e0ea3921Schristos 17384261787cSchristos# Make the flags to build DSOs the same as for shared libraries unless they 17394261787cSchristos# are already defined 17404261787cSchristos$target{module_cflags} = $target{shared_cflag} unless defined $target{module_cflags}; 17414261787cSchristos$target{module_cxxflags} = $target{shared_cxxflag} unless defined $target{module_cxxflags}; 17424261787cSchristos$target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_ldflags}; 17434261787cSchristos{ 17444261787cSchristos my $shared_info_pl = 17454261787cSchristos catfile(dirname($0), "Configurations", "shared-info.pl"); 17464261787cSchristos my %shared_info = read_eval_file($shared_info_pl); 17474261787cSchristos push @{$target{_conf_fname_int}}, $shared_info_pl; 17484261787cSchristos my $si = $target{shared_target}; 17494261787cSchristos while (ref $si ne "HASH") { 17504261787cSchristos last if ! defined $si; 17514261787cSchristos if (ref $si eq "CODE") { 17524261787cSchristos $si = $si->(); 1753e0ea3921Schristos } else { 17544261787cSchristos $si = $shared_info{$si}; 1755e0ea3921Schristos } 1756e0ea3921Schristos } 1757e0ea3921Schristos 17584261787cSchristos # Some of the 'shared_target' values don't have any entries in 17594261787cSchristos # %shared_info. That's perfectly fine, AS LONG AS the build file 17604261787cSchristos # template knows how to handle this. That is currently the case for 17614261787cSchristos # Windows and VMS. 17624261787cSchristos if (defined $si) { 17634261787cSchristos # Just as above, copy certain shared_* attributes to the corresponding 17644261787cSchristos # module_ attribute unless the latter is already defined 17654261787cSchristos $si->{module_cflags} = $si->{shared_cflag} unless defined $si->{module_cflags}; 17664261787cSchristos $si->{module_cxxflags} = $si->{shared_cxxflag} unless defined $si->{module_cxxflags}; 17674261787cSchristos $si->{module_ldflags} = $si->{shared_ldflag} unless defined $si->{module_ldflags}; 17684261787cSchristos foreach (sort keys %$si) { 17694261787cSchristos $target{$_} = defined $target{$_} 17704261787cSchristos ? add($si->{$_})->($target{$_}) 17714261787cSchristos : $si->{$_}; 17724261787cSchristos } 17734261787cSchristos } 17744261787cSchristos} 17754261787cSchristos 17764261787cSchristos# ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON 1777e0ea3921Schristos 17788fbed61eSchristos###################################################################### 17798fbed61eSchristos# Build up information for skipping certain directories depending on disabled 17808fbed61eSchristos# features, as well as setting up macros for disabled features. 17818fbed61eSchristos 17828fbed61eSchristos# This is a tentative database of directories to skip. Some entries may not 17838fbed61eSchristos# correspond to anything real, but that's ok, they will simply be ignored. 17848fbed61eSchristos# The actual processing of these entries is done in the build.info lookup 17858fbed61eSchristos# loop further down. 17868fbed61eSchristos# 17878fbed61eSchristos# The key is a Unix formatted path in the source tree, the value is an index 17888fbed61eSchristos# into %disabled_info, so any existing path gets added to a corresponding 17898fbed61eSchristos# 'skipped' entry in there with the list of skipped directories. 17908fbed61eSchristosmy %skipdir = (); 179152629741Schristosmy %disabled_info = (); # For configdata.pm 179252629741Schristosforeach my $what (sort keys %disabled) { 17938fbed61eSchristos # There are deprecated disablables that translate to themselves. 17948fbed61eSchristos # They cause disabling cascades, but should otherwise not regiter. 17958fbed61eSchristos next if $deprecated_disablables{$what}; 17968fbed61eSchristos # The generated $disabled{"deprecated-x.y"} entries are special 17978fbed61eSchristos # and treated properly elsewhere 17988fbed61eSchristos next if $what =~ m|^deprecated-|; 17998fbed61eSchristos 180052629741Schristos $config{options} .= " no-$what"; 180152629741Schristos 18028fbed61eSchristos if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared', 18038fbed61eSchristos 'module', 'pic', 'dynamic-engine', 'makedepend', 18048fbed61eSchristos 'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) { 180552629741Schristos (my $WHAT = uc $what) =~ s|-|_|g; 18068fbed61eSchristos my $skipdir = $what; 180752629741Schristos 180852629741Schristos # fix-up crypto/directory name(s) 18098fbed61eSchristos $skipdir = "ripemd" if $what eq "rmd160"; 18108fbed61eSchristos $skipdir = "whrlpool" if $what eq "whirlpool"; 181152629741Schristos 181252629741Schristos my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; 18138fbed61eSchristos push @{$config{openssl_feature_defines}}, $macro; 181452629741Schristos 18158fbed61eSchristos $skipdir{engines} = $what if $what eq 'engine'; 18168fbed61eSchristos $skipdir{"crypto/$skipdir"} = $what 18178fbed61eSchristos unless $what eq 'async' || $what eq 'err' || $what eq 'dso'; 181852629741Schristos } 181952629741Schristos} 182052629741Schristos 182152629741Schristosif ($disabled{"dynamic-engine"}) { 18228fbed61eSchristos push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; 182352629741Schristos} else { 18248fbed61eSchristos push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE"; 182552629741Schristos} 182652629741Schristos 18275af53050Schristos# If we use the unified build, collect information from build.info files 18285af53050Schristosmy %unified_info = (); 18295af53050Schristos 18305af53050Schristosmy $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO}); 18315af53050Schristosif ($builder eq "unified") { 18328fbed61eSchristos use Text::Template 1.46; 18335af53050Schristos 18345af53050Schristos sub cleandir { 18355af53050Schristos my $base = shift; 18365af53050Schristos my $dir = shift; 18375af53050Schristos my $relativeto = shift || "."; 1838b46c97feSchristos my $no_mkpath = shift // 0; 18395af53050Schristos 18405af53050Schristos $dir = catdir($base,$dir) unless isabsolute($dir); 18415af53050Schristos 18425af53050Schristos # Make sure the directories we're building in exists 1843b46c97feSchristos mkpath($dir) unless $no_mkpath; 18445af53050Schristos 18455af53050Schristos my $res = abs2rel(absolutedir($dir), rel2abs($relativeto)); 18465af53050Schristos #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n"; 18475af53050Schristos return $res; 1848a89c9211Schristos } 1849a89c9211Schristos 18505af53050Schristos sub cleanfile { 18515af53050Schristos my $base = shift; 18525af53050Schristos my $file = shift; 18535af53050Schristos my $relativeto = shift || "."; 1854b46c97feSchristos my $no_mkpath = shift // 0; 1855a89c9211Schristos 18565af53050Schristos $file = catfile($base,$file) unless isabsolute($file); 18575af53050Schristos 18585af53050Schristos my $d = dirname($file); 18595af53050Schristos my $f = basename($file); 18605af53050Schristos 18615af53050Schristos # Make sure the directories we're building in exists 1862b46c97feSchristos mkpath($d) unless $no_mkpath; 18635af53050Schristos 18645af53050Schristos my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto)); 18655af53050Schristos #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n"; 18665af53050Schristos return $res; 18675af53050Schristos } 18685af53050Schristos 18695af53050Schristos # Store the name of the template file we will build the build file from 18705af53050Schristos # in %config. This may be useful for the build file itself. 18715af53050Schristos my @build_file_template_names = 1872be43b372Schristos ( $builder_platform."-".$config{build_file}.".tmpl", 1873be43b372Schristos $config{build_file}.".tmpl" ); 18745af53050Schristos my @build_file_templates = (); 18755af53050Schristos 18765af53050Schristos # First, look in the user provided directory, if given 1877e0ea3921Schristos if (defined env($local_config_envname)) { 18785af53050Schristos @build_file_templates = 18795af53050Schristos map { 18805af53050Schristos if ($^O eq 'VMS') { 18815af53050Schristos # VMS environment variables are logical names, 18825af53050Schristos # which can be used as is 18835af53050Schristos $local_config_envname . ':' . $_; 18845af53050Schristos } else { 1885e0ea3921Schristos catfile(env($local_config_envname), $_); 18865af53050Schristos } 18875af53050Schristos } 18885af53050Schristos @build_file_template_names; 18895af53050Schristos } 18905af53050Schristos # Then, look in our standard directory 18915af53050Schristos push @build_file_templates, 1892b46c97feSchristos ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir, 1) } 18935af53050Schristos @build_file_template_names ); 18945af53050Schristos 18955af53050Schristos my $build_file_template; 18965af53050Schristos for $_ (@build_file_templates) { 18975af53050Schristos $build_file_template = $_; 18985af53050Schristos last if -f $build_file_template; 18995af53050Schristos 19005af53050Schristos $build_file_template = undef; 19015af53050Schristos } 19025af53050Schristos if (!defined $build_file_template) { 19035af53050Schristos die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n"; 19045af53050Schristos } 19055af53050Schristos $config{build_file_templates} 1906e0ea3921Schristos = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"), 1907b46c97feSchristos $blddir, 1), 19088fbed61eSchristos $build_file_template ]; 19095af53050Schristos 19108fbed61eSchristos my @build_dirs = ( [ ] ); # current directory 19115af53050Schristos 19125af53050Schristos $config{build_infos} = [ ]; 19135af53050Schristos 191478327f04Schristos # We want to detect configdata.pm in the source tree, so we 191578327f04Schristos # don't use it if the build tree is different. 1916b46c97feSchristos my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir, 1); 191778327f04Schristos 19188fbed61eSchristos # Any source file that we recognise is placed in this hash table, with 19198fbed61eSchristos # the list of its intended destinations as value. When everything has 19208fbed61eSchristos # been collected, there's a routine that checks that these source files 19218fbed61eSchristos # exist, or if they are generated, that the generator exists. 19228fbed61eSchristos my %check_exist = (); 19238fbed61eSchristos my %check_generate = (); 19248fbed61eSchristos 19258fbed61eSchristos my %ordinals = (); 19268fbed61eSchristos while (@build_dirs) { 19278fbed61eSchristos my @curd = @{shift @build_dirs}; 19288fbed61eSchristos my $sourced = catdir($srcdir, @curd); 19298fbed61eSchristos my $buildd = catdir($blddir, @curd); 19308fbed61eSchristos 19318fbed61eSchristos my $unixdir = join('/', @curd); 19328fbed61eSchristos if (exists $skipdir{$unixdir}) { 19338fbed61eSchristos my $what = $skipdir{$unixdir}; 19348fbed61eSchristos push @{$disabled_info{$what}->{skipped}}, catdir(@curd); 19358fbed61eSchristos next; 19368fbed61eSchristos } 19378fbed61eSchristos 19388fbed61eSchristos mkpath($buildd); 19398fbed61eSchristos 19408fbed61eSchristos my $f = 'build.info'; 19418fbed61eSchristos # The basic things we're trying to build 19428fbed61eSchristos my @programs = (); 19438fbed61eSchristos my @libraries = (); 19448fbed61eSchristos my @modules = (); 19458fbed61eSchristos my @scripts = (); 19468fbed61eSchristos 19478fbed61eSchristos my %sources = (); 19488fbed61eSchristos my %shared_sources = (); 19498fbed61eSchristos my %includes = (); 19508fbed61eSchristos my %defines = (); 19518fbed61eSchristos my %depends = (); 19528fbed61eSchristos my %generate = (); 19538fbed61eSchristos my %imagedocs = (); 19548fbed61eSchristos my %htmldocs = (); 19558fbed61eSchristos my %mandocs = (); 19568fbed61eSchristos 19578fbed61eSchristos # Support for $variablename in build.info files. 19588fbed61eSchristos # Embedded perl code is the ultimate master, still. If its output 19598fbed61eSchristos # contains a dollar sign, it had better be escaped, or it will be 19608fbed61eSchristos # taken for a variable name prefix. 19618fbed61eSchristos my %variables = (); 19628fbed61eSchristos # Variable name syntax 19638fbed61eSchristos my $variable_name_re = qr/(?P<VARIABLE>[[:alpha:]][[:alnum:]_]*)/; 19648fbed61eSchristos # Value modifier syntaxes 19658fbed61eSchristos my $variable_subst_re = qr/\/(?P<RE>(?:\\\/|.)*?)\/(?P<SUBST>.*?)/; 19668fbed61eSchristos # Variable reference 19678fbed61eSchristos my $variable_simple_re = qr/(?<!\\)\$${variable_name_re}/; 19688fbed61eSchristos my $variable_w_mod_re = 19698fbed61eSchristos qr/(?<!\\)\$\{${variable_name_re}(?P<MOD>(?:\\\/|.)*?)\}/; 19708fbed61eSchristos # Tie it all together 19718fbed61eSchristos my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/; 19728fbed61eSchristos 19738fbed61eSchristos my $expand_variables = sub { 19748fbed61eSchristos my $value = ''; 19758fbed61eSchristos my $value_rest = shift; 19768fbed61eSchristos 19778fbed61eSchristos if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) { 19788fbed61eSchristos print STDERR 19798fbed61eSchristos "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n" 19808fbed61eSchristos } 19818fbed61eSchristos 19828fbed61eSchristos while ($value_rest =~ /${variable_re}/) { 19838fbed61eSchristos # We must save important regexp values, because the next 19848fbed61eSchristos # regexp clears them 19858fbed61eSchristos my $mod = $+{MOD}; 19868fbed61eSchristos my $variable_value = $variables{$+{VARIABLE}}; 19878fbed61eSchristos 19888fbed61eSchristos $value_rest = $'; 19898fbed61eSchristos $value .= $`; 19908fbed61eSchristos 19918fbed61eSchristos # Process modifier expressions, if present 19928fbed61eSchristos if (defined $mod) { 19938fbed61eSchristos if ($mod =~ /^${variable_subst_re}$/) { 19948fbed61eSchristos my $re = $+{RE}; 19958fbed61eSchristos my $subst = $+{SUBST}; 19968fbed61eSchristos 19978fbed61eSchristos $variable_value =~ s/\Q$re\E/$subst/g; 19988fbed61eSchristos 19998fbed61eSchristos if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) { 20008fbed61eSchristos print STDERR 20018fbed61eSchristos "DEBUG[\$expand_variables] ... and substituted ", 20028fbed61eSchristos "'$re' with '$subst'\n"; 20038fbed61eSchristos } 20048fbed61eSchristos } 20058fbed61eSchristos } 20068fbed61eSchristos 20078fbed61eSchristos $value .= $variable_value; 20088fbed61eSchristos } 20098fbed61eSchristos if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) { 20108fbed61eSchristos print STDERR 20118fbed61eSchristos "DEBUG[\$expand_variables] ... into: '$value$value_rest'\n"; 20128fbed61eSchristos } 20138fbed61eSchristos return $value . $value_rest; 20148fbed61eSchristos }; 20158fbed61eSchristos 20168fbed61eSchristos # Support for attributes in build.info files 20178fbed61eSchristos my %attributes = (); 20188fbed61eSchristos my $handle_attributes = sub { 20198fbed61eSchristos my $attr_str = shift; 20208fbed61eSchristos my $ref = shift; 20218fbed61eSchristos my @goals = @_; 20228fbed61eSchristos 20238fbed61eSchristos return unless defined $attr_str; 20248fbed61eSchristos 20258fbed61eSchristos my @a = tokenize($attr_str, qr|\s*,\s*|); 20268fbed61eSchristos foreach my $a (@a) { 20278fbed61eSchristos my $ac = 1; 20288fbed61eSchristos my $ak = $a; 20298fbed61eSchristos my $av = 1; 20308fbed61eSchristos if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) { 20318fbed61eSchristos $ac = ! $1; 20328fbed61eSchristos $ak = $2; 20338fbed61eSchristos $av = $3; 20348fbed61eSchristos } 20358fbed61eSchristos foreach my $g (@goals) { 20368fbed61eSchristos if ($ac) { 20378fbed61eSchristos $$ref->{$g}->{$ak} = $av; 20388fbed61eSchristos } else { 20398fbed61eSchristos delete $$ref->{$g}->{$ak}; 20408fbed61eSchristos } 20418fbed61eSchristos } 20428fbed61eSchristos } 20438fbed61eSchristos }; 20448fbed61eSchristos 20458fbed61eSchristos # Support for pushing values on multiple indexes of a given hash 20468fbed61eSchristos # array. 20478fbed61eSchristos my $push_to = sub { 20488fbed61eSchristos my $valueref = shift; 20498fbed61eSchristos my $index_str = shift; # May be undef or empty 20508fbed61eSchristos my $attrref = shift; # May be undef 20518fbed61eSchristos my $attr_str = shift; 20528fbed61eSchristos my @values = @_; 20538fbed61eSchristos 20548fbed61eSchristos if (defined $index_str) { 20558fbed61eSchristos my @indexes = ( '' ); 20568fbed61eSchristos if ($index_str !~ m|^\s*$|) { 20578fbed61eSchristos @indexes = tokenize($index_str); 20588fbed61eSchristos } 20598fbed61eSchristos foreach (@indexes) { 20608fbed61eSchristos push @{$valueref->{$_}}, @values; 20618fbed61eSchristos if (defined $attrref) { 20628fbed61eSchristos $handle_attributes->($attr_str, \$$attrref->{$_}, 20638fbed61eSchristos @values); 20648fbed61eSchristos } 20658fbed61eSchristos } 20668fbed61eSchristos } else { 20678fbed61eSchristos push @$valueref, @values; 20688fbed61eSchristos $handle_attributes->($attr_str, $attrref, @values) 20698fbed61eSchristos if defined $attrref; 20708fbed61eSchristos } 20718fbed61eSchristos }; 20728fbed61eSchristos 20738fbed61eSchristos if ($buildinfo_debug) { 20748fbed61eSchristos print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n"; 20758fbed61eSchristos } 20765af53050Schristos push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f); 207778327f04Schristos my $template = 207878327f04Schristos Text::Template->new(TYPE => 'FILE', 207978327f04Schristos SOURCE => catfile($sourced, $f), 208078327f04Schristos PREPEND => qq{use lib "$FindBin::Bin/util/perl";}); 20815af53050Schristos die "Something went wrong with $sourced/$f: $!\n" unless $template; 20825af53050Schristos my @text = 20835af53050Schristos split /^/m, 20845af53050Schristos $template->fill_in(HASH => { config => \%config, 20855af53050Schristos target => \%target, 20865af53050Schristos disabled => \%disabled, 20875af53050Schristos withargs => \%withargs, 20885af53050Schristos builddir => abs2rel($buildd, $blddir), 20895af53050Schristos sourcedir => abs2rel($sourced, $blddir), 20905af53050Schristos buildtop => abs2rel($blddir, $blddir), 20915af53050Schristos sourcetop => abs2rel($srcdir, $blddir) }, 20925af53050Schristos DELIMITERS => [ "{-", "-}" ]); 20935af53050Schristos 20945af53050Schristos # The top item of this stack has the following values 20955af53050Schristos # -2 positive already run and we found ELSE (following ELSIF should fail) 20965af53050Schristos # -1 positive already run (skip until ENDIF) 20975af53050Schristos # 0 negatives so far (if we're at a condition, check it) 20985af53050Schristos # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF) 20995af53050Schristos # 2 positive ELSE (following ELSIF should fail) 21005af53050Schristos my @skip = (); 21018fbed61eSchristos 21028fbed61eSchristos # A few useful generic regexps 21038fbed61eSchristos my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/; 21048fbed61eSchristos my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/; 21058fbed61eSchristos my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/; 21068fbed61eSchristos my $value_re = qr/(?P<VALUE>.*?)/; 21075af53050Schristos collect_information( 21085af53050Schristos collect_from_array([ @text ], 21095af53050Schristos qr/\\$/ => sub { my $l1 = shift; my $l2 = shift; 21105af53050Schristos $l1 =~ s/\\$//; $l1.$l2 }), 21115af53050Schristos # Info we're looking for 21128fbed61eSchristos qr/^\s* IF ${cond_re} \s*$/x 21135af53050Schristos => sub { 21145af53050Schristos if (! @skip || $skip[$#skip] > 0) { 21158fbed61eSchristos push @skip, !! $expand_variables->($+{COND}); 21165af53050Schristos } else { 21175af53050Schristos push @skip, -1; 21185af53050Schristos } 21195af53050Schristos }, 21208fbed61eSchristos qr/^\s* ELSIF ${cond_re} \s*$/x 21215af53050Schristos => sub { die "ELSIF out of scope" if ! @skip; 21225af53050Schristos die "ELSIF following ELSE" if abs($skip[$#skip]) == 2; 21235af53050Schristos $skip[$#skip] = -1 if $skip[$#skip] != 0; 21248fbed61eSchristos $skip[$#skip] = !! $expand_variables->($+{COND}) 21255af53050Schristos if $skip[$#skip] == 0; }, 21268fbed61eSchristos qr/^\s* ELSE \s*$/x 21275af53050Schristos => sub { die "ELSE out of scope" if ! @skip; 21285af53050Schristos $skip[$#skip] = -2 if $skip[$#skip] != 0; 21295af53050Schristos $skip[$#skip] = 2 if $skip[$#skip] == 0; }, 21308fbed61eSchristos qr/^\s* ENDIF \s*$/x 21315af53050Schristos => sub { die "ENDIF out of scope" if ! @skip; 21325af53050Schristos pop @skip; }, 21338fbed61eSchristos qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x 21345af53050Schristos => sub { 21355af53050Schristos if (!@skip || $skip[$#skip] > 0) { 21368fbed61eSchristos $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE}); 21375af53050Schristos } 21385af53050Schristos }, 21398fbed61eSchristos qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x 21405af53050Schristos => sub { 21415af53050Schristos if (!@skip || $skip[$#skip] > 0) { 21428fbed61eSchristos foreach (tokenize($expand_variables->($+{VALUE}))) { 21438fbed61eSchristos push @build_dirs, [ @curd, splitdir($_, 1) ]; 21448fbed61eSchristos } 21455af53050Schristos } 21465af53050Schristos }, 21478fbed61eSchristos qr/^\s* PROGRAMS ${attribs_re} \s* = \s* ${value_re} \s* $/x 21488fbed61eSchristos => sub { $push_to->(\@programs, undef, 21498fbed61eSchristos \$attributes{programs}, $+{ATTRIBS}, 21508fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21518fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21528fbed61eSchristos qr/^\s* LIBS ${attribs_re} \s* = \s* ${value_re} \s* $/x 21538fbed61eSchristos => sub { $push_to->(\@libraries, undef, 21548fbed61eSchristos \$attributes{libraries}, $+{ATTRIBS}, 21558fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21568fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21578fbed61eSchristos qr/^\s* MODULES ${attribs_re} \s* = \s* ${value_re} \s* $/x 21588fbed61eSchristos => sub { $push_to->(\@modules, undef, 21598fbed61eSchristos \$attributes{modules}, $+{ATTRIBS}, 21608fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21618fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21628fbed61eSchristos qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x 21638fbed61eSchristos => sub { $push_to->(\@scripts, undef, 21648fbed61eSchristos \$attributes{scripts}, $+{ATTRIBS}, 21658fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21668fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21678fbed61eSchristos qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x 21688fbed61eSchristos => sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}), 21698fbed61eSchristos undef, undef, 21708fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21718fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21728fbed61eSchristos qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x 21738fbed61eSchristos => sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}), 21748fbed61eSchristos undef, undef, 21758fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21768fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21778fbed61eSchristos qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x 21788fbed61eSchristos => sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}), 21798fbed61eSchristos undef, undef, 21808fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21818fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21828fbed61eSchristos qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x 21838fbed61eSchristos => sub { $push_to->(\%sources, $expand_variables->($+{INDEX}), 21848fbed61eSchristos \$attributes{sources}, $+{ATTRIBS}, 21858fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21868fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21878fbed61eSchristos qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x 21888fbed61eSchristos => sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}), 21898fbed61eSchristos \$attributes{sources}, $+{ATTRIBS}, 21908fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21918fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21928fbed61eSchristos qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x 21938fbed61eSchristos => sub { $push_to->(\%includes, $expand_variables->($+{INDEX}), 21948fbed61eSchristos undef, undef, 21958fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 21968fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 21978fbed61eSchristos qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x 21988fbed61eSchristos => sub { $push_to->(\%defines, $expand_variables->($+{INDEX}), 21998fbed61eSchristos undef, undef, 22008fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 22018fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 22028fbed61eSchristos qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x 22038fbed61eSchristos => sub { $push_to->(\%depends, $expand_variables->($+{INDEX}), 22048fbed61eSchristos \$attributes{depends}, $+{ATTRIBS}, 22058fbed61eSchristos tokenize($expand_variables->($+{VALUE}))) 22068fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 22078fbed61eSchristos qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x 22088fbed61eSchristos => sub { $push_to->(\%generate, $expand_variables->($+{INDEX}), 22098fbed61eSchristos \$attributes{generate}, $+{ATTRIBS}, 22108fbed61eSchristos $expand_variables->($+{VALUE})) 22118fbed61eSchristos if !@skip || $skip[$#skip] > 0; }, 22128fbed61eSchristos qr/^\s* (?:\#.*)? $/x => sub { }, 22135af53050Schristos "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }, 22145af53050Schristos "BEFORE" => sub { 22155af53050Schristos if ($buildinfo_debug) { 22165af53050Schristos print STDERR "DEBUG: Parsing ",join(" ", @_),"\n"; 22175af53050Schristos print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n"; 22185af53050Schristos } 22195af53050Schristos }, 22205af53050Schristos "AFTER" => sub { 22215af53050Schristos if ($buildinfo_debug) { 22225af53050Schristos print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n"; 22235af53050Schristos } 22245af53050Schristos }, 22255af53050Schristos ); 22265af53050Schristos die "runaway IF?" if (@skip); 22275af53050Schristos 22288fbed61eSchristos if (grep { defined $attributes{modules}->{$_}->{engine} } keys %attributes 22298fbed61eSchristos and !$config{dynamic_engines}) { 22308fbed61eSchristos die <<"EOF" 22315af53050SchristosENGINES can only be used if configured with 'dynamic-engine'. 22325af53050SchristosThis is usually a fault in a build.info file. 2233a89c9211SchristosEOF 2234a89c9211Schristos } 2235a89c9211Schristos 22368fbed61eSchristos { 22378fbed61eSchristos my %infos = ( programs => [ @programs ], 22388fbed61eSchristos libraries => [ @libraries ], 22398fbed61eSchristos modules => [ @modules ], 22408fbed61eSchristos scripts => [ @scripts ] ); 22418fbed61eSchristos foreach my $k (keys %infos) { 22428fbed61eSchristos foreach (@{$infos{$k}}) { 22438fbed61eSchristos my $item = cleanfile($buildd, $_, $blddir); 22448fbed61eSchristos $unified_info{$k}->{$item} = 1; 22455af53050Schristos 22468fbed61eSchristos # Fix up associated attributes 22478fbed61eSchristos $unified_info{attributes}->{$k}->{$item} = 22488fbed61eSchristos $attributes{$k}->{$_} 22498fbed61eSchristos if defined $attributes{$k}->{$_}; 22505af53050Schristos } 22515af53050Schristos } 22525af53050Schristos } 22535af53050Schristos 2254e0ea3921Schristos # Check that we haven't defined any library as both shared and 2255e0ea3921Schristos # explicitly static. That is forbidden. 2256e0ea3921Schristos my @doubles = (); 2257e0ea3921Schristos foreach (grep /\.a$/, keys %{$unified_info{libraries}}) { 2258e0ea3921Schristos (my $l = $_) =~ s/\.a$//; 22598fbed61eSchristos push @doubles, $l if defined $unified_info{libraries}->{$l}; 22605af53050Schristos } 2261e0ea3921Schristos die "these libraries are both explicitly static and shared:\n ", 2262e0ea3921Schristos join(" ", @doubles), "\n" 2263e0ea3921Schristos if @doubles; 22645af53050Schristos 22655af53050Schristos foreach (keys %sources) { 22665af53050Schristos my $dest = $_; 22675af53050Schristos my $ddest = cleanfile($buildd, $_, $blddir); 22685af53050Schristos foreach (@{$sources{$dest}}) { 2269b46c97feSchristos my $s = cleanfile($sourced, $_, $blddir, 1); 22705af53050Schristos 22718fbed61eSchristos # If it's generated or we simply don't find it in the source 22728fbed61eSchristos # tree, we assume it's in the build tree. 22738fbed61eSchristos if ($s eq $src_configdata || $generate{$_} || ! -f $s) { 22745af53050Schristos $s = cleanfile($buildd, $_, $blddir); 22755af53050Schristos } 22768fbed61eSchristos my $o = $_; 2277e0ea3921Schristos # We recognise C++, C and asm files 2278e0ea3921Schristos if ($s =~ /\.(cc|cpp|c|s|S)$/) { 22798fbed61eSchristos push @{$check_exist{$s}}, $ddest; 2280e0ea3921Schristos $o =~ s/\.[csS]$/.o/; # C and assembler 2281e0ea3921Schristos $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ 22825af53050Schristos $o = cleanfile($buildd, $o, $blddir); 22838fbed61eSchristos $unified_info{sources}->{$ddest}->{$o} = -1; 22848fbed61eSchristos $unified_info{sources}->{$o}->{$s} = -1; 2285e0ea3921Schristos } elsif ($s =~ /\.rc$/) { 2286e0ea3921Schristos # We also recognise resource files 22878fbed61eSchristos push @{$check_exist{$s}}, $ddest; 2288e0ea3921Schristos $o =~ s/\.rc$/.res/; # Resource configuration 22898fbed61eSchristos $o = cleanfile($buildd, $o, $blddir); 22908fbed61eSchristos $unified_info{sources}->{$ddest}->{$o} = -1; 22918fbed61eSchristos $unified_info{sources}->{$o}->{$s} = -1; 22925af53050Schristos } else { 22938fbed61eSchristos push @{$check_exist{$s}}, $ddest; 22945af53050Schristos $unified_info{sources}->{$ddest}->{$s} = 1; 22955af53050Schristos } 22968fbed61eSchristos # Fix up associated attributes 22978fbed61eSchristos if ($o ne $_) { 22988fbed61eSchristos $unified_info{attributes}->{sources}->{$ddest}->{$o} = 22998fbed61eSchristos $unified_info{attributes}->{sources}->{$o}->{$s} = 23008fbed61eSchristos $attributes{sources}->{$dest}->{$_} 23018fbed61eSchristos if defined $attributes{sources}->{$dest}->{$_}; 23028fbed61eSchristos } else { 23038fbed61eSchristos $unified_info{attributes}->{sources}->{$ddest}->{$s} = 23048fbed61eSchristos $attributes{sources}->{$dest}->{$_} 23058fbed61eSchristos if defined $attributes{sources}->{$dest}->{$_}; 23068fbed61eSchristos } 23075af53050Schristos } 23085af53050Schristos } 23095af53050Schristos 23105af53050Schristos foreach (keys %shared_sources) { 23115af53050Schristos my $dest = $_; 23125af53050Schristos my $ddest = cleanfile($buildd, $_, $blddir); 23135af53050Schristos foreach (@{$shared_sources{$dest}}) { 2314b46c97feSchristos my $s = cleanfile($sourced, $_, $blddir, 1); 23155af53050Schristos 23168fbed61eSchristos # If it's generated or we simply don't find it in the source 23178fbed61eSchristos # tree, we assume it's in the build tree. 23188fbed61eSchristos if ($s eq $src_configdata || $generate{$_} || ! -f $s) { 23195af53050Schristos $s = cleanfile($buildd, $_, $blddir); 23205af53050Schristos } 2321e0ea3921Schristos 23228fbed61eSchristos my $o = $_; 2323e0ea3921Schristos if ($s =~ /\.(cc|cpp|c|s|S)$/) { 2324e0ea3921Schristos # We recognise C++, C and asm files 23258fbed61eSchristos push @{$check_exist{$s}}, $ddest; 2326e0ea3921Schristos $o =~ s/\.[csS]$/.o/; # C and assembler 2327e0ea3921Schristos $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ 23285af53050Schristos $o = cleanfile($buildd, $o, $blddir); 23298fbed61eSchristos $unified_info{shared_sources}->{$ddest}->{$o} = -1; 23308fbed61eSchristos $unified_info{sources}->{$o}->{$s} = -1; 2331e0ea3921Schristos } elsif ($s =~ /\.rc$/) { 2332e0ea3921Schristos # We also recognise resource files 23338fbed61eSchristos push @{$check_exist{$s}}, $ddest; 2334e0ea3921Schristos $o =~ s/\.rc$/.res/; # Resource configuration 23358fbed61eSchristos $o = cleanfile($buildd, $o, $blddir); 23368fbed61eSchristos $unified_info{shared_sources}->{$ddest}->{$o} = -1; 23378fbed61eSchristos $unified_info{sources}->{$o}->{$s} = -1; 23388fbed61eSchristos } elsif ($s =~ /\.ld$/) { 23398fbed61eSchristos # We also recognise linker scripts (or corresponding) 2340e0ea3921Schristos # We know they are generated files 23418fbed61eSchristos push @{$check_exist{$s}}, $ddest; 23428fbed61eSchristos $o = cleanfile($buildd, $_, $blddir); 23438fbed61eSchristos $unified_info{shared_sources}->{$ddest}->{$o} = 1; 23445af53050Schristos } else { 23455af53050Schristos die "unrecognised source file type for shared library: $s\n"; 23465af53050Schristos } 23478fbed61eSchristos # Fix up associated attributes 23488fbed61eSchristos if ($o ne $_) { 23498fbed61eSchristos $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} = 23508fbed61eSchristos $unified_info{attributes}->{sources}->{$o}->{$s} = 23518fbed61eSchristos $attributes{sources}->{$dest}->{$_} 23528fbed61eSchristos if defined $attributes{sources}->{$dest}->{$_}; 23538fbed61eSchristos } else { 23548fbed61eSchristos $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} = 23558fbed61eSchristos $attributes{sources}->{$dest}->{$_} 23568fbed61eSchristos if defined $attributes{sources}->{$dest}->{$_}; 23578fbed61eSchristos } 23585af53050Schristos } 23595af53050Schristos } 23605af53050Schristos 23615af53050Schristos foreach (keys %generate) { 23625af53050Schristos my $dest = $_; 23635af53050Schristos my $ddest = cleanfile($buildd, $_, $blddir); 23645af53050Schristos die "more than one generator for $dest: " 23655af53050Schristos ,join(" ", @{$generate{$_}}),"\n" 23665af53050Schristos if scalar @{$generate{$_}} > 1; 23675af53050Schristos my @generator = split /\s+/, $generate{$dest}->[0]; 23688fbed61eSchristos my $gen = $generator[0]; 2369b46c97feSchristos $generator[0] = cleanfile($sourced, $gen, $blddir, 1); 23708fbed61eSchristos 23718fbed61eSchristos # If the generator is itself generated, it's in the build tree 23728fbed61eSchristos if ($generate{$gen} || ! -f $generator[0]) { 23738fbed61eSchristos $generator[0] = cleanfile($buildd, $gen, $blddir); 23748fbed61eSchristos } 23758fbed61eSchristos $check_generate{$ddest}->{$generator[0]}++; 23768fbed61eSchristos 23775af53050Schristos $unified_info{generate}->{$ddest} = [ @generator ]; 23788fbed61eSchristos # Fix up associated attributes 23798fbed61eSchristos $unified_info{attributes}->{generate}->{$ddest} = 23808fbed61eSchristos $attributes{generate}->{$dest}->{$gen} 23818fbed61eSchristos if defined $attributes{generate}->{$dest}->{$gen}; 23825af53050Schristos } 23835af53050Schristos 23845af53050Schristos foreach (keys %depends) { 23855af53050Schristos my $dest = $_; 23868fbed61eSchristos my $ddest = $dest; 23878fbed61eSchristos 23888fbed61eSchristos if ($dest =~ /^\|(.*)\|$/) { 23898fbed61eSchristos # Collect the raw target 23908fbed61eSchristos $unified_info{targets}->{$1} = 1; 23918fbed61eSchristos $ddest = $1; 23928fbed61eSchristos } elsif ($dest eq '') { 23938fbed61eSchristos $ddest = ''; 23948fbed61eSchristos } else { 2395b46c97feSchristos $ddest = cleanfile($sourced, $_, $blddir, 1); 23965af53050Schristos 23975af53050Schristos # If the destination doesn't exist in source, it can only be 23985af53050Schristos # a generated file in the build tree. 23998fbed61eSchristos if ($ddest eq $src_configdata || ! -f $ddest) { 24005af53050Schristos $ddest = cleanfile($buildd, $_, $blddir); 24015af53050Schristos } 24025af53050Schristos } 24035af53050Schristos foreach (@{$depends{$dest}}) { 2404b46c97feSchristos my $d = cleanfile($sourced, $_, $blddir, 1); 24058fbed61eSchristos my $d2 = cleanfile($buildd, $_, $blddir); 24065af53050Schristos 24075af53050Schristos # If we know it's generated, or assume it is because we can't 24085af53050Schristos # find it in the source tree, we set file we depend on to be 24098fbed61eSchristos # in the build tree rather than the source tree. 241078327f04Schristos if ($d eq $src_configdata 24118fbed61eSchristos || (grep { $d2 eq $_ } 24128fbed61eSchristos keys %{$unified_info{generate}}) 24138fbed61eSchristos || ! -f $d) { 24148fbed61eSchristos $d = $d2; 24155af53050Schristos } 24165af53050Schristos $unified_info{depends}->{$ddest}->{$d} = 1; 24178fbed61eSchristos 24188fbed61eSchristos # Fix up associated attributes 24198fbed61eSchristos $unified_info{attributes}->{depends}->{$ddest}->{$d} = 24208fbed61eSchristos $attributes{depends}->{$dest}->{$_} 24218fbed61eSchristos if defined $attributes{depends}->{$dest}->{$_}; 24225af53050Schristos } 24235af53050Schristos } 24245af53050Schristos 24255af53050Schristos foreach (keys %includes) { 24265af53050Schristos my $dest = $_; 2427b46c97feSchristos my $ddest = cleanfile($sourced, $_, $blddir, 1); 24285af53050Schristos 24295af53050Schristos # If the destination doesn't exist in source, it can only be 24305af53050Schristos # a generated file in the build tree. 243178327f04Schristos if ($ddest eq $src_configdata || ! -f $ddest) { 24325af53050Schristos $ddest = cleanfile($buildd, $_, $blddir); 24335af53050Schristos } 24345af53050Schristos foreach (@{$includes{$dest}}) { 2435b46c97feSchristos my $is = cleandir($sourced, $_, $blddir, 1); 24365af53050Schristos my $ib = cleandir($buildd, $_, $blddir); 24375af53050Schristos push @{$unified_info{includes}->{$ddest}->{source}}, $is 24385af53050Schristos unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}}; 24395af53050Schristos push @{$unified_info{includes}->{$ddest}->{build}}, $ib 24405af53050Schristos unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}}; 24415af53050Schristos } 24425af53050Schristos } 24438fbed61eSchristos 24448fbed61eSchristos foreach my $dest (keys %defines) { 24458fbed61eSchristos my $ddest; 24468fbed61eSchristos 24478fbed61eSchristos if ($dest ne "") { 2448b46c97feSchristos $ddest = cleanfile($sourced, $dest, $blddir, 1); 24498fbed61eSchristos 24508fbed61eSchristos # If the destination doesn't exist in source, it can only 24518fbed61eSchristos # be a generated file in the build tree. 24528fbed61eSchristos if (! -f $ddest) { 24538fbed61eSchristos $ddest = cleanfile($buildd, $dest, $blddir); 24548fbed61eSchristos } 24558fbed61eSchristos } 24568fbed61eSchristos foreach my $v (@{$defines{$dest}}) { 24578fbed61eSchristos $v =~ m|^([^=]*)(=.*)?$|; 24588fbed61eSchristos die "0 length macro name not permitted\n" if $1 eq ""; 24598fbed61eSchristos if ($dest ne "") { 24608fbed61eSchristos die "$1 defined more than once\n" 24618fbed61eSchristos if defined $unified_info{defines}->{$ddest}->{$1}; 24628fbed61eSchristos $unified_info{defines}->{$ddest}->{$1} = $2; 24638fbed61eSchristos } else { 24648fbed61eSchristos die "$1 defined more than once\n" 24658fbed61eSchristos if grep { $v eq $_ } @{$config{defines}}; 24668fbed61eSchristos push @{$config{defines}}, $v; 24678fbed61eSchristos } 24688fbed61eSchristos } 24698fbed61eSchristos } 24708fbed61eSchristos 24718fbed61eSchristos foreach my $section (keys %imagedocs) { 24728fbed61eSchristos foreach (@{$imagedocs{$section}}) { 24738fbed61eSchristos my $imagedocs = cleanfile($buildd, $_, $blddir); 24748fbed61eSchristos $unified_info{imagedocs}->{$section}->{$imagedocs} = 1; 24758fbed61eSchristos } 24768fbed61eSchristos } 24778fbed61eSchristos 24788fbed61eSchristos foreach my $section (keys %htmldocs) { 24798fbed61eSchristos foreach (@{$htmldocs{$section}}) { 24808fbed61eSchristos my $htmldocs = cleanfile($buildd, $_, $blddir); 24818fbed61eSchristos $unified_info{htmldocs}->{$section}->{$htmldocs} = 1; 24828fbed61eSchristos } 24838fbed61eSchristos } 24848fbed61eSchristos 24858fbed61eSchristos foreach my $section (keys %mandocs) { 24868fbed61eSchristos foreach (@{$mandocs{$section}}) { 24878fbed61eSchristos my $mandocs = cleanfile($buildd, $_, $blddir); 24888fbed61eSchristos $unified_info{mandocs}->{$section}->{$mandocs} = 1; 24898fbed61eSchristos } 24908fbed61eSchristos } 24915af53050Schristos } 24925af53050Schristos 2493e0ea3921Schristos my $ordinals_text = join(', ', sort keys %ordinals); 2494e0ea3921Schristos warn <<"EOF" if $ordinals_text; 2495e0ea3921Schristos 2496e0ea3921SchristosWARNING: ORDINALS were specified for $ordinals_text 2497e0ea3921SchristosThey are ignored and should be replaced with a combination of GENERATE, 2498e0ea3921SchristosDEPEND and SHARED_SOURCE. 2499e0ea3921SchristosEOF 2500e0ea3921Schristos 25018fbed61eSchristos # Check that each generated file is only generated once 25028fbed61eSchristos my $ambiguous_generation = 0; 25038fbed61eSchristos foreach (sort keys %check_generate) { 25048fbed61eSchristos my @generators = sort keys %{$check_generate{$_}}; 25058fbed61eSchristos my $generators_txt = join(', ', @generators); 25068fbed61eSchristos if (scalar @generators > 1) { 25078fbed61eSchristos warn "$_ is GENERATEd by more than one generator ($generators_txt)\n"; 25088fbed61eSchristos $ambiguous_generation++; 25098fbed61eSchristos } 25108fbed61eSchristos if ($check_generate{$_}->{$generators[0]} > 1) { 25118fbed61eSchristos warn "INFO: $_ has more than one GENERATE declaration (same generator)\n" 25128fbed61eSchristos } 25138fbed61eSchristos } 25148fbed61eSchristos die "There are ambiguous source file generations\n" 25158fbed61eSchristos if $ambiguous_generation > 0; 251678327f04Schristos 25178fbed61eSchristos # All given source files should exist, or if generated, their 25188fbed61eSchristos # generator should exist. This loop ensures this is true. 25198fbed61eSchristos my $missing = 0; 25208fbed61eSchristos foreach my $orig (sort keys %check_exist) { 25218fbed61eSchristos foreach my $dest (@{$check_exist{$orig}}) { 25228fbed61eSchristos if ($orig ne $src_configdata) { 25238fbed61eSchristos if ($orig =~ /\.a$/) { 25248fbed61eSchristos # Static library names may be used as sources, so we 25258fbed61eSchristos # need to detect those and give them special treatment. 25268fbed61eSchristos unless (grep { $_ eq $orig } 25278fbed61eSchristos keys %{$unified_info{libraries}}) { 25288fbed61eSchristos warn "$orig is given as source for $dest, but no such library is built\n"; 25298fbed61eSchristos $missing++; 25308fbed61eSchristos } 25318fbed61eSchristos } else { 25328fbed61eSchristos # A source may be generated, and its generator may be 25338fbed61eSchristos # generated as well. We therefore loop to dig out the 25348fbed61eSchristos # first generator. 25358fbed61eSchristos my $gen = $orig; 25368fbed61eSchristos 25378fbed61eSchristos while (my @next = keys %{$check_generate{$gen}}) { 25388fbed61eSchristos $gen = $next[0]; 25398fbed61eSchristos } 25408fbed61eSchristos 25418fbed61eSchristos if (! -f $gen) { 25428fbed61eSchristos if ($gen ne $orig) { 25438fbed61eSchristos $missing++; 25448fbed61eSchristos warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n"; 25458fbed61eSchristos } else { 25468fbed61eSchristos $missing++; 25478fbed61eSchristos warn "$orig is given as source for $dest, but is missing\n"; 2548bf8eace1Schristos } 2549bf8eace1Schristos } 2550bf8eace1Schristos } 25518fbed61eSchristos } 25528fbed61eSchristos } 25538fbed61eSchristos } 25548fbed61eSchristos die "There are files missing\n" if $missing > 0; 25558fbed61eSchristos 25568fbed61eSchristos # Go through the sources of all libraries and check that the same basename 25578fbed61eSchristos # doesn't appear more than once. Some static library archivers depend on 25588fbed61eSchristos # them being unique. 25598fbed61eSchristos { 25608fbed61eSchristos my $err = 0; 25618fbed61eSchristos foreach my $prod (keys %{$unified_info{libraries}}) { 25628fbed61eSchristos my @prod_sources = 25638fbed61eSchristos map { keys %{$unified_info{sources}->{$_}} } 25648fbed61eSchristos keys %{$unified_info{sources}->{$prod}}; 25658fbed61eSchristos my %srccnt = (); 25668fbed61eSchristos 25678fbed61eSchristos # Count how many times a given each source basename 25688fbed61eSchristos # appears for each product. 25698fbed61eSchristos foreach my $src (@prod_sources) { 25708fbed61eSchristos $srccnt{basename $src}++; 25718fbed61eSchristos } 25728fbed61eSchristos 25738fbed61eSchristos foreach my $src (keys %srccnt) { 25748fbed61eSchristos if ((my $cnt = $srccnt{$src}) > 1) { 25758fbed61eSchristos print STDERR "$src appears $cnt times for the product $prod\n"; 25768fbed61eSchristos $err++ 25778fbed61eSchristos } 25788fbed61eSchristos } 25798fbed61eSchristos } 25808fbed61eSchristos die if $err > 0; 25818fbed61eSchristos } 25828fbed61eSchristos 25838fbed61eSchristos # Massage the result 2584bf8eace1Schristos 258578327f04Schristos # If we depend on a header file or a perl module, add an inclusion of 258678327f04Schristos # its directory to allow smoothe inclusion 258778327f04Schristos foreach my $dest (keys %{$unified_info{depends}}) { 258878327f04Schristos next if $dest eq ""; 258978327f04Schristos foreach my $d (keys %{$unified_info{depends}->{$dest}}) { 259078327f04Schristos next unless $d =~ /\.(h|pm)$/; 259178327f04Schristos my $i = dirname($d); 259278327f04Schristos my $spot = 259378327f04Schristos $d eq "configdata.pm" || defined($unified_info{generate}->{$d}) 259478327f04Schristos ? 'build' : 'source'; 259578327f04Schristos push @{$unified_info{includes}->{$dest}->{$spot}}, $i 259678327f04Schristos unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{$spot}}; 259778327f04Schristos } 259878327f04Schristos } 259978327f04Schristos 26008fbed61eSchristos # Go through all intermediary files and change their names to something that 26018fbed61eSchristos # reflects what they will be built for. Note that for some source files, 26028fbed61eSchristos # this leads to duplicate object files because they are used multiple times. 26038fbed61eSchristos # the goal is to rename all object files according to this scheme: 26048fbed61eSchristos # {productname}-{midfix}-{origobjname}.[o|res] 26058fbed61eSchristos # the {midfix} is a keyword indicating the type of product, which is mostly 26068fbed61eSchristos # valuable for libraries since they come in two forms. 26078fbed61eSchristos # 26088fbed61eSchristos # This also reorganises the {sources} and {shared_sources} so that the 26098fbed61eSchristos # former only contains ALL object files that are supposed to end up in 26108fbed61eSchristos # static libraries and programs, while the latter contains ALL object files 26118fbed61eSchristos # that are supposed to end up in shared libraries and DSOs. 26128fbed61eSchristos # The main reason for having two different source structures is to allow 26138fbed61eSchristos # the same name to be used for the static and the shared variants of a 26148fbed61eSchristos # library. 26158fbed61eSchristos { 26168fbed61eSchristos # Take copies so we don't get interference from added stuff 26178fbed61eSchristos my %unified_copy = (); 26188fbed61eSchristos foreach (('sources', 'shared_sources')) { 26198fbed61eSchristos $unified_copy{$_} = { %{$unified_info{$_}} } 26208fbed61eSchristos if defined($unified_info{$_}); 26218fbed61eSchristos delete $unified_info{$_}; 26228fbed61eSchristos } 26238fbed61eSchristos foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) { 26248fbed61eSchristos # $intent serves multi purposes: 26258fbed61eSchristos # - give a prefix for the new object files names 26268fbed61eSchristos # - in the case of libraries, rearrange the object files so static 26278fbed61eSchristos # libraries use the 'sources' structure exclusively, while shared 26288fbed61eSchristos # libraries use the 'shared_sources' structure exclusively. 26298fbed61eSchristos my $intent = { 26308fbed61eSchristos programs => { bin => { src => [ 'sources' ], 26318fbed61eSchristos dst => 'sources' } }, 26328fbed61eSchristos libraries => { lib => { src => [ 'sources' ], 26338fbed61eSchristos dst => 'sources' }, 26348fbed61eSchristos shlib => { prodselect => 26358fbed61eSchristos sub { grep !/\.a$/, @_ }, 26368fbed61eSchristos src => [ 'sources', 26378fbed61eSchristos 'shared_sources' ], 26388fbed61eSchristos dst => 'shared_sources' } }, 26398fbed61eSchristos modules => { dso => { src => [ 'sources' ], 26408fbed61eSchristos dst => 'sources' } }, 26418fbed61eSchristos scripts => { script => { src => [ 'sources' ], 26428fbed61eSchristos dst => 'sources' } } 26438fbed61eSchristos } -> {$prodtype}; 26448fbed61eSchristos foreach my $kind (keys %$intent) { 26458fbed61eSchristos next if ($intent->{$kind}->{dst} eq 'shared_sources' 26468fbed61eSchristos && $disabled{shared}); 26478fbed61eSchristos 26488fbed61eSchristos my @src = @{$intent->{$kind}->{src}}; 26498fbed61eSchristos my $dst = $intent->{$kind}->{dst}; 26508fbed61eSchristos my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ }; 26518fbed61eSchristos foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) { 26528fbed61eSchristos # %prod_sources has all applicable objects as keys, and 26538fbed61eSchristos # their corresponding sources as values 26548fbed61eSchristos my %prod_sources = 26558fbed61eSchristos map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] } 26568fbed61eSchristos map { keys %{$unified_copy{$_}->{$prod}} } 26578fbed61eSchristos @src; 26588fbed61eSchristos foreach (keys %prod_sources) { 26598fbed61eSchristos # Only affect object files and resource files, 26608fbed61eSchristos # the others simply get a new value 26618fbed61eSchristos # (+1 instead of -1) 26628fbed61eSchristos if ($_ =~ /\.(o|res)$/) { 26638fbed61eSchristos (my $prodname = $prod) =~ s|\.a$||; 26648fbed61eSchristos my $newobj = 26658fbed61eSchristos catfile(dirname($_), 26668fbed61eSchristos basename($prodname) 26678fbed61eSchristos . '-' . $kind 26688fbed61eSchristos . '-' . basename($_)); 26698fbed61eSchristos $unified_info{$dst}->{$prod}->{$newobj} = 1; 26708fbed61eSchristos foreach my $src (@{$prod_sources{$_}}) { 26718fbed61eSchristos $unified_info{sources}->{$newobj}->{$src} = 1; 26728fbed61eSchristos # Adjust source attributes 26738fbed61eSchristos my $attrs = $unified_info{attributes}->{sources}; 26748fbed61eSchristos if (defined $attrs->{$prod} 26758fbed61eSchristos && defined $attrs->{$prod}->{$_}) { 26768fbed61eSchristos $attrs->{$prod}->{$newobj} = 26778fbed61eSchristos $attrs->{$prod}->{$_}; 26788fbed61eSchristos delete $attrs->{$prod}->{$_}; 26798fbed61eSchristos } 26808fbed61eSchristos foreach my $objsrc (keys %{$attrs->{$_} // {}}) { 26818fbed61eSchristos $attrs->{$newobj}->{$objsrc} = 26828fbed61eSchristos $attrs->{$_}->{$objsrc}; 26838fbed61eSchristos delete $attrs->{$_}->{$objsrc}; 26848fbed61eSchristos } 26858fbed61eSchristos } 26868fbed61eSchristos # Adjust dependencies 26878fbed61eSchristos foreach my $deps (keys %{$unified_info{depends}->{$_}}) { 26888fbed61eSchristos $unified_info{depends}->{$_}->{$deps} = -1; 26898fbed61eSchristos $unified_info{depends}->{$newobj}->{$deps} = 1; 26908fbed61eSchristos } 26918fbed61eSchristos # Adjust includes 26928fbed61eSchristos foreach my $k (('source', 'build')) { 26938fbed61eSchristos next unless 26948fbed61eSchristos defined($unified_info{includes}->{$_}->{$k}); 26958fbed61eSchristos my @incs = @{$unified_info{includes}->{$_}->{$k}}; 26968fbed61eSchristos $unified_info{includes}->{$newobj}->{$k} = [ @incs ]; 26978fbed61eSchristos } 26988fbed61eSchristos } else { 26998fbed61eSchristos $unified_info{$dst}->{$prod}->{$_} = 1; 270078327f04Schristos } 270178327f04Schristos } 270278327f04Schristos } 270378327f04Schristos } 27048fbed61eSchristos } 27058fbed61eSchristos } 27068fbed61eSchristos 27078fbed61eSchristos # At this point, we have a number of sources with the value -1. They 27088fbed61eSchristos # aren't part of the local build and are probably meant for a different 27098fbed61eSchristos # platform, and can therefore be cleaned away. That happens when making 27108fbed61eSchristos # %unified_info more efficient below. 271178327f04Schristos 27125af53050Schristos ### Make unified_info a bit more efficient 27135af53050Schristos # One level structures 27148fbed61eSchristos foreach (("programs", "libraries", "modules", "scripts", "targets")) { 27155af53050Schristos $unified_info{$_} = [ sort keys %{$unified_info{$_}} ]; 27165af53050Schristos } 27175af53050Schristos # Two level structures 27188fbed61eSchristos foreach my $l1 (("sources", "shared_sources", "ldadd", "depends", 27198fbed61eSchristos "imagedocs", "htmldocs", "mandocs")) { 27205af53050Schristos foreach my $l2 (sort keys %{$unified_info{$l1}}) { 27218fbed61eSchristos my @items = 27228fbed61eSchristos sort 27238fbed61eSchristos grep { $unified_info{$l1}->{$l2}->{$_} > 0 } 27248fbed61eSchristos keys %{$unified_info{$l1}->{$l2}}; 27258fbed61eSchristos if (@items) { 27268fbed61eSchristos $unified_info{$l1}->{$l2} = [ @items ]; 27278fbed61eSchristos } else { 27288fbed61eSchristos delete $unified_info{$l1}->{$l2}; 27295af53050Schristos } 27305af53050Schristos } 27318fbed61eSchristos } 27328fbed61eSchristos # Defines 27338fbed61eSchristos foreach my $dest (sort keys %{$unified_info{defines}}) { 27348fbed61eSchristos $unified_info{defines}->{$dest} 27358fbed61eSchristos = [ map { $_.$unified_info{defines}->{$dest}->{$_} } 27368fbed61eSchristos sort keys %{$unified_info{defines}->{$dest}} ]; 27378fbed61eSchristos } 27385af53050Schristos # Includes 27395af53050Schristos foreach my $dest (sort keys %{$unified_info{includes}}) { 27405af53050Schristos if (defined($unified_info{includes}->{$dest}->{build})) { 274178327f04Schristos my @source_includes = (); 274278327f04Schristos @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} ) 274378327f04Schristos if defined($unified_info{includes}->{$dest}->{source}); 27445af53050Schristos $unified_info{includes}->{$dest} = 27455af53050Schristos [ @{$unified_info{includes}->{$dest}->{build}} ]; 27465af53050Schristos foreach my $inc (@source_includes) { 27475af53050Schristos push @{$unified_info{includes}->{$dest}}, $inc 27485af53050Schristos unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}}; 27495af53050Schristos } 27508fbed61eSchristos } elsif (defined($unified_info{includes}->{$dest}->{source})) { 27515af53050Schristos $unified_info{includes}->{$dest} = 27525af53050Schristos [ @{$unified_info{includes}->{$dest}->{source}} ]; 27538fbed61eSchristos } else { 27548fbed61eSchristos delete $unified_info{includes}->{$dest}; 27555af53050Schristos } 27565af53050Schristos } 2757bf8eace1Schristos 2758bf8eace1Schristos # For convenience collect information regarding directories where 2759bf8eace1Schristos # files are generated, those generated files and the end product 2760bf8eace1Schristos # they end up in where applicable. Then, add build rules for those 2761bf8eace1Schristos # directories 2762bf8eace1Schristos my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ], 27638fbed61eSchristos "dso" => [ @{$unified_info{modules}} ], 2764bf8eace1Schristos "bin" => [ @{$unified_info{programs}} ], 27658fbed61eSchristos "script" => [ @{$unified_info{scripts}} ], 27668fbed61eSchristos "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} } 27678fbed61eSchristos keys %{$unified_info{imagedocs} // {}}), 27688fbed61eSchristos (map { @{$unified_info{htmldocs}->{$_} // []} } 27698fbed61eSchristos keys %{$unified_info{htmldocs} // {}}), 27708fbed61eSchristos (map { @{$unified_info{mandocs}->{$_} // []} } 27718fbed61eSchristos keys %{$unified_info{mandocs} // {}}) ] ); 27728fbed61eSchristos foreach my $type (sort keys %loopinfo) { 2773bf8eace1Schristos foreach my $product (@{$loopinfo{$type}}) { 2774bf8eace1Schristos my %dirs = (); 2775bf8eace1Schristos my $pd = dirname($product); 2776bf8eace1Schristos 2777bf8eace1Schristos foreach (@{$unified_info{sources}->{$product} // []}, 2778bf8eace1Schristos @{$unified_info{shared_sources}->{$product} // []}) { 2779bf8eace1Schristos my $d = dirname($_); 2780bf8eace1Schristos 2781bf8eace1Schristos # We don't want to create targets for source directories 2782bf8eace1Schristos # when building out of source 2783bf8eace1Schristos next if ($config{sourcedir} ne $config{builddir} 2784bf8eace1Schristos && $d =~ m|^\Q$config{sourcedir}\E|); 2785bf8eace1Schristos # We already have a "test" target, and the current directory 2786bf8eace1Schristos # is just silly to make a target for 2787bf8eace1Schristos next if $d eq "test" || $d eq "."; 2788bf8eace1Schristos 2789bf8eace1Schristos $dirs{$d} = 1; 2790bf8eace1Schristos push @{$unified_info{dirinfo}->{$d}->{deps}}, $_ 2791bf8eace1Schristos if $d ne $pd; 2792bf8eace1Schristos } 27938fbed61eSchristos foreach (sort keys %dirs) { 2794bf8eace1Schristos push @{$unified_info{dirinfo}->{$_}->{products}->{$type}}, 2795bf8eace1Schristos $product; 2796bf8eace1Schristos } 2797bf8eace1Schristos } 2798bf8eace1Schristos } 27995af53050Schristos} 28005af53050Schristos 28015af53050Schristos# For the schemes that need it, we provide the old *_obj configs 28025af53050Schristos# from the *_asm_obj ones 28035af53050Schristosforeach (grep /_(asm|aux)_src$/, keys %target) { 28045af53050Schristos my $src = $_; 28055af53050Schristos (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/; 2806e0ea3921Schristos $target{$obj} = $target{$src}; 2807e0ea3921Schristos $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler 2808e0ea3921Schristos $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++ 28095af53050Schristos} 28105af53050Schristos 28115af53050Schristos# Write down our configuration where it fits ######################### 28125af53050Schristos 28138fbed61eSchristosmy %template_vars = ( 28148fbed61eSchristos config => \%config, 28158fbed61eSchristos target => \%target, 28168fbed61eSchristos disablables => \@disablables, 28178fbed61eSchristos disablables_int => \@disablables_int, 28188fbed61eSchristos disabled => \%disabled, 28198fbed61eSchristos withargs => \%withargs, 28208fbed61eSchristos unified_info => \%unified_info, 28218fbed61eSchristos tls => \@tls, 28228fbed61eSchristos dtls => \@dtls, 28238fbed61eSchristos makevars => [ sort keys %user ], 28248fbed61eSchristos disabled_info => \%disabled_info, 28258fbed61eSchristos user_crossable => \@user_crossable, 28265af53050Schristos); 28278fbed61eSchristosmy $configdata_outname = 'configdata.pm'; 28288fbed61eSchristosopen CONFIGDATA, ">$configdata_outname.new" 28298fbed61eSchristos or die "Trying to create $configdata_outname.new: $!"; 2830b46c97feSchristosmy $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir, 1); 28318fbed61eSchristosmy $configdata_tmpl = 28328fbed61eSchristos OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname); 28338fbed61eSchristos$configdata_tmpl->fill_in( 28348fbed61eSchristos FILENAME => $configdata_tmplname, 28358fbed61eSchristos OUTPUT => \*CONFIGDATA, 28368fbed61eSchristos HASH => { %template_vars, 28378fbed61eSchristos autowarntext => [ 28388fbed61eSchristos 'WARNING: do not edit!', 28398fbed61eSchristos "Generated by Configure from $configdata_tmplname", 28408fbed61eSchristos ] } 28418fbed61eSchristos) or die $Text::Template::ERROR; 28428fbed61eSchristosclose CONFIGDATA; 28435af53050Schristos 28448fbed61eSchristosrename "$configdata_outname.new", $configdata_outname; 2845e0ea3921Schristosif ($builder_platform eq 'unix') { 2846e0ea3921Schristos my $mode = (0755 & ~umask); 2847e0ea3921Schristos chmod $mode, 'configdata.pm' 2848e0ea3921Schristos or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!); 2849e0ea3921Schristos} 28508fbed61eSchristosprint "Created $configdata_outname\n"; 28515af53050Schristos 28528fbed61eSchristosprint "Running $configdata_outname\n"; 28538fbed61eSchristosmy $perlcmd = (quotify("maybeshell", $config{PERL}))[0]; 28548fbed61eSchristosmy $cmd = "$perlcmd $configdata_outname"; 28558fbed61eSchristos#print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n"; 28568fbed61eSchristossystem($cmd); 28578fbed61eSchristosexit 1 if $? != 0; 28585af53050Schristos 28592500041cSchristos$SIG{__DIE__} = $orig_death_handler; 28602500041cSchristos 28615af53050Schristosprint <<"EOF" if ($disabled{threads} eq "unavailable"); 2862a89c9211Schristos 2863a89c9211SchristosThe library could not be configured for supporting multi-threaded 2864a89c9211Schristosapplications as the compiler options required on this system are not known. 28658fbed61eSchristosSee file INSTALL.md for details if you need multi-threading. 2866a89c9211SchristosEOF 2867a89c9211Schristos 28685af53050Schristosprint <<"EOF" if ($no_shared_warn); 2869a89c9211Schristos 28705af53050SchristosThe options 'shared', 'pic' and 'dynamic-engine' aren't supported on this 28715af53050Schristosplatform, so we will pretend you gave the option 'no-pic', which also disables 28725af53050Schristos'shared' and 'dynamic-engine'. If you know how to implement shared libraries 28735af53050Schristosor position independent code, please let us know (but please first make sure 28745af53050Schristosyou have tried with a current version of OpenSSL). 28754060c40eSchristosEOF 28764060c40eSchristos 28778fbed61eSchristosprint $banner; 2878e0ea3921Schristos 2879a89c9211Schristosexit(0); 2880a89c9211Schristos 28815af53050Schristos###################################################################### 28825af53050Schristos# 28835af53050Schristos# Helpers and utility functions 28845af53050Schristos# 28855af53050Schristos 28862500041cSchristos# Death handler, to print a helpful message in case of failure ####### 28872500041cSchristos# 28882500041cSchristossub death_handler { 28892500041cSchristos die @_ if $^S; # To prevent the added message in eval blocks 2890be43b372Schristos my $build_file = $config{build_file} // "build file"; 28912500041cSchristos my @message = ( <<"_____", @_ ); 28922500041cSchristos 28932500041cSchristosFailure! $build_file wasn't produced. 28948fbed61eSchristosPlease read INSTALL.md and associated NOTES-* files. You may also have to 28958fbed61eSchristoslook over your available compiler tool chain or change your configuration. 28962500041cSchristos 28972500041cSchristos_____ 28982500041cSchristos 28992500041cSchristos # Dying is terminal, so it's ok to reset the signal handler here. 29002500041cSchristos $SIG{__DIE__} = $orig_death_handler; 29012500041cSchristos die @message; 29022500041cSchristos} 29032500041cSchristos 29045af53050Schristos# Configuration file reading ######################################### 29055af53050Schristos 29065af53050Schristos# Note: All of the helper functions are for lazy evaluation. They all 29075af53050Schristos# return a CODE ref, which will return the intended value when evaluated. 29085af53050Schristos# Thus, whenever there's mention of a returned value, it's about that 29095af53050Schristos# intended value. 29105af53050Schristos 29115af53050Schristos# Helper function to implement conditional value variants, with a default 29125af53050Schristos# plus additional values based on the value of $config{build_type}. 29135af53050Schristos# Arguments are given in hash table form: 29145af53050Schristos# 29155af53050Schristos# picker(default => "Basic string: ", 29165af53050Schristos# debug => "debug", 29175af53050Schristos# release => "release") 29185af53050Schristos# 29195af53050Schristos# When configuring with --debug, the resulting string will be 29205af53050Schristos# "Basic string: debug", and when not, it will be "Basic string: release" 29215af53050Schristos# 29225af53050Schristos# This can be used to create variants of sets of flags according to the 29235af53050Schristos# build type: 29245af53050Schristos# 29255af53050Schristos# cflags => picker(default => "-Wall", 29265af53050Schristos# debug => "-g -O0", 29275af53050Schristos# release => "-O3") 29285af53050Schristos# 29295af53050Schristossub picker { 29305af53050Schristos my %opts = @_; 29315af53050Schristos return sub { add($opts{default} || (), 29325af53050Schristos $opts{$config{build_type}} || ())->(); } 29335af53050Schristos} 29345af53050Schristos 29355af53050Schristos# Helper function to combine several values of different types into one. 29365af53050Schristos# This is useful if you want to combine a string with the result of a 29375af53050Schristos# lazy function, such as: 29385af53050Schristos# 29395af53050Schristos# cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" }) 29405af53050Schristos# 29415af53050Schristossub combine { 29425af53050Schristos my @stuff = @_; 29435af53050Schristos return sub { add(@stuff)->(); } 29445af53050Schristos} 29455af53050Schristos 29465af53050Schristos# Helper function to implement conditional values depending on the value 29475af53050Schristos# of $disabled{threads}. Can be used as follows: 29485af53050Schristos# 29495af53050Schristos# cflags => combine("-Wall", threads("-pthread")) 29505af53050Schristos# 29515af53050Schristossub threads { 29525af53050Schristos my @flags = @_; 29535af53050Schristos return sub { add($disabled{threads} ? () : @flags)->(); } 29545af53050Schristos} 29555af53050Schristos 2956e0ea3921Schristossub shared { 2957e0ea3921Schristos my @flags = @_; 2958e0ea3921Schristos return sub { add($disabled{shared} ? () : @flags)->(); } 2959e0ea3921Schristos} 29605af53050Schristos 29615af53050Schristosour $add_called = 0; 29625af53050Schristos# Helper function to implement adding values to already existing configuration 29635af53050Schristos# values. It handles elements that are ARRAYs, CODEs and scalars 29645af53050Schristossub _add { 29655af53050Schristos my $separator = shift; 29665af53050Schristos 29675af53050Schristos # If there's any ARRAY in the collection of values OR the separator 29685af53050Schristos # is undef, we will return an ARRAY of combined values, otherwise a 29695af53050Schristos # string of joined values with $separator as the separator. 29705af53050Schristos my $found_array = !defined($separator); 29715af53050Schristos 29725af53050Schristos my @values = 29735af53050Schristos map { 29745af53050Schristos my $res = $_; 29755af53050Schristos while (ref($res) eq "CODE") { 29765af53050Schristos $res = $res->(); 29775af53050Schristos } 29785af53050Schristos if (defined($res)) { 29795af53050Schristos if (ref($res) eq "ARRAY") { 29805af53050Schristos $found_array = 1; 29815af53050Schristos @$res; 29825af53050Schristos } else { 29835af53050Schristos $res; 29845af53050Schristos } 29855af53050Schristos } else { 29865af53050Schristos (); 29875af53050Schristos } 29885af53050Schristos } (@_); 29895af53050Schristos 29905af53050Schristos $add_called = 1; 29915af53050Schristos 29925af53050Schristos if ($found_array) { 29935af53050Schristos [ @values ]; 29945af53050Schristos } else { 29955af53050Schristos join($separator, grep { defined($_) && $_ ne "" } @values); 29965af53050Schristos } 29975af53050Schristos} 29985af53050Schristossub add_before { 29995af53050Schristos my $separator = " "; 30005af53050Schristos if (ref($_[$#_]) eq "HASH") { 30015af53050Schristos my $opts = pop; 30025af53050Schristos $separator = $opts->{separator}; 30035af53050Schristos } 30045af53050Schristos my @x = @_; 30055af53050Schristos sub { _add($separator, @x, @_) }; 30065af53050Schristos} 30075af53050Schristossub add { 30085af53050Schristos my $separator = " "; 30095af53050Schristos if (ref($_[$#_]) eq "HASH") { 30105af53050Schristos my $opts = pop; 30115af53050Schristos $separator = $opts->{separator}; 30125af53050Schristos } 30135af53050Schristos my @x = @_; 30145af53050Schristos sub { _add($separator, @_, @x) }; 30155af53050Schristos} 30165af53050Schristos 3017e0ea3921Schristossub read_eval_file { 3018e0ea3921Schristos my $fname = shift; 3019e0ea3921Schristos my $content; 3020e0ea3921Schristos my @result; 3021e0ea3921Schristos 3022e0ea3921Schristos open F, "< $fname" or die "Can't open '$fname': $!\n"; 3023e0ea3921Schristos { 3024e0ea3921Schristos undef local $/; 3025e0ea3921Schristos $content = <F>; 3026e0ea3921Schristos } 3027e0ea3921Schristos close F; 3028e0ea3921Schristos { 3029e0ea3921Schristos local $@; 3030e0ea3921Schristos 3031e0ea3921Schristos @result = ( eval $content ); 3032e0ea3921Schristos warn $@ if $@; 3033e0ea3921Schristos } 3034e0ea3921Schristos return wantarray ? @result : $result[0]; 3035e0ea3921Schristos} 3036e0ea3921Schristos 30375af53050Schristos# configuration reader, evaluates the input file as a perl script and expects 30385af53050Schristos# it to fill %targets with target configurations. Those are then added to 30395af53050Schristos# %table. 30405af53050Schristossub read_config { 30415af53050Schristos my $fname = shift; 3042e0ea3921Schristos my %targets; 3043e0ea3921Schristos 30445af53050Schristos { 30455af53050Schristos # Protect certain tables from tampering 3046e0ea3921Schristos local %table = (); 30475af53050Schristos 3048e0ea3921Schristos %targets = read_eval_file($fname); 30495af53050Schristos } 305078327f04Schristos my %preexisting = (); 305178327f04Schristos foreach (sort keys %targets) { 305278327f04Schristos $preexisting{$_} = 1 if $table{$_}; 305378327f04Schristos } 305478327f04Schristos die <<"EOF", 305578327f04SchristosThe following config targets from $fname 305678327f04Schristosshadow pre-existing config targets with the same name: 305778327f04SchristosEOF 305878327f04Schristos map { " $_\n" } sort keys %preexisting 305978327f04Schristos if %preexisting; 306078327f04Schristos 30615af53050Schristos 30625af53050Schristos # For each target, check that it's configured with a hash table. 30635af53050Schristos foreach (keys %targets) { 30645af53050Schristos if (ref($targets{$_}) ne "HASH") { 30655af53050Schristos if (ref($targets{$_}) eq "") { 30665af53050Schristos warn "Deprecated target configuration for $_, ignoring...\n"; 30675af53050Schristos } else { 30685af53050Schristos warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n"; 30695af53050Schristos } 30705af53050Schristos delete $targets{$_}; 30715af53050Schristos } else { 30725af53050Schristos $targets{$_}->{_conf_fname_int} = add([ $fname ]); 30735af53050Schristos } 30745af53050Schristos } 30755af53050Schristos 30765af53050Schristos %table = (%table, %targets); 30775af53050Schristos 30785af53050Schristos} 30795af53050Schristos 30805af53050Schristos# configuration resolver. Will only resolve all the lazy evaluation 30815af53050Schristos# codeblocks for the chosen target and all those it inherits from, 30825af53050Schristos# recursively 30835af53050Schristossub resolve_config { 30845af53050Schristos my $target = shift; 30855af53050Schristos my @breadcrumbs = @_; 30865af53050Schristos 30875af53050Schristos# my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS}); 30885af53050Schristos 30895af53050Schristos if (grep { $_ eq $target } @breadcrumbs) { 30905af53050Schristos die "inherit_from loop! target backtrace:\n " 30915af53050Schristos ,$target,"\n ",join("\n ", @breadcrumbs),"\n"; 30925af53050Schristos } 30935af53050Schristos 30945af53050Schristos if (!defined($table{$target})) { 30955af53050Schristos warn "Warning! target $target doesn't exist!\n"; 30965af53050Schristos return (); 30975af53050Schristos } 30985af53050Schristos # Recurse through all inheritances. They will be resolved on the 30995af53050Schristos # fly, so when this operation is done, they will all just be a 31005af53050Schristos # bunch of attributes with string values. 31015af53050Schristos # What we get here, though, are keys with references to lists of 31025af53050Schristos # the combined values of them all. We will deal with lists after 31035af53050Schristos # this stage is done. 31045af53050Schristos my %combined_inheritance = (); 31055af53050Schristos if ($table{$target}->{inherit_from}) { 31065af53050Schristos my @inherit_from = 31075af53050Schristos map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}}; 31085af53050Schristos foreach (@inherit_from) { 31095af53050Schristos my %inherited_config = resolve_config($_, $target, @breadcrumbs); 31105af53050Schristos 31115af53050Schristos # 'template' is a marker that's considered private to 31125af53050Schristos # the config that had it. 31135af53050Schristos delete $inherited_config{template}; 31145af53050Schristos 31155af53050Schristos foreach (keys %inherited_config) { 31165af53050Schristos if (!$combined_inheritance{$_}) { 31175af53050Schristos $combined_inheritance{$_} = []; 31185af53050Schristos } 31195af53050Schristos push @{$combined_inheritance{$_}}, $inherited_config{$_}; 31205af53050Schristos } 31215af53050Schristos } 31225af53050Schristos } 31235af53050Schristos 31245af53050Schristos # We won't need inherit_from in this target any more, since we've 31255af53050Schristos # resolved all the inheritances that lead to this 31265af53050Schristos delete $table{$target}->{inherit_from}; 31275af53050Schristos 31285af53050Schristos # Now is the time to deal with those lists. Here's the place to 31295af53050Schristos # decide what shall be done with those lists, all based on the 31305af53050Schristos # values of the target we're currently dealing with. 31315af53050Schristos # - If a value is a coderef, it will be executed with the list of 31325af53050Schristos # inherited values as arguments. 31335af53050Schristos # - If the corresponding key doesn't have a value at all or is the 31345af53050Schristos # empty string, the inherited value list will be run through the 31355af53050Schristos # default combiner (below), and the result becomes this target's 31365af53050Schristos # value. 31375af53050Schristos # - Otherwise, this target's value is assumed to be a string that 31385af53050Schristos # will simply override the inherited list of values. 31395af53050Schristos my $default_combiner = add(); 31405af53050Schristos 31415af53050Schristos my %all_keys = 31425af53050Schristos map { $_ => 1 } (keys %combined_inheritance, 31435af53050Schristos keys %{$table{$target}}); 31445af53050Schristos 31455af53050Schristos sub process_values { 31465af53050Schristos my $object = shift; 31475af53050Schristos my $inherited = shift; # Always a [ list ] 31485af53050Schristos my $target = shift; 31495af53050Schristos my $entry = shift; 31505af53050Schristos 31515af53050Schristos $add_called = 0; 31525af53050Schristos 31535af53050Schristos while(ref($object) eq "CODE") { 31545af53050Schristos $object = $object->(@$inherited); 31555af53050Schristos } 31565af53050Schristos if (!defined($object)) { 31575af53050Schristos return (); 31585af53050Schristos } 31595af53050Schristos elsif (ref($object) eq "ARRAY") { 31605af53050Schristos local $add_called; # To make sure recursive calls don't affect it 31615af53050Schristos return [ map { process_values($_, $inherited, $target, $entry) } 31625af53050Schristos @$object ]; 31635af53050Schristos } elsif (ref($object) eq "") { 31645af53050Schristos return $object; 31655af53050Schristos } else { 31665af53050Schristos die "cannot handle reference type ",ref($object) 31675af53050Schristos ," found in target ",$target," -> ",$entry,"\n"; 31685af53050Schristos } 31695af53050Schristos } 31705af53050Schristos 31719330ead5Schristos foreach my $key (sort keys %all_keys) { 31729330ead5Schristos my $previous = $combined_inheritance{$key}; 31735af53050Schristos 31745af53050Schristos # Current target doesn't have a value for the current key? 31755af53050Schristos # Assign it the default combiner, the rest of this loop body 31765af53050Schristos # will handle it just like any other coderef. 31779330ead5Schristos if (!exists $table{$target}->{$key}) { 31789330ead5Schristos $table{$target}->{$key} = $default_combiner; 31795af53050Schristos } 31805af53050Schristos 31819330ead5Schristos $table{$target}->{$key} = process_values($table{$target}->{$key}, 31829330ead5Schristos $combined_inheritance{$key}, 31839330ead5Schristos $target, $key); 31849330ead5Schristos unless(defined($table{$target}->{$key})) { 31859330ead5Schristos delete $table{$target}->{$key}; 31865af53050Schristos } 31875af53050Schristos# if ($extra_checks && 31889330ead5Schristos# $previous && !($add_called || $previous ~~ $table{$target}->{$key})) { 31899330ead5Schristos# warn "$key got replaced in $target\n"; 31905af53050Schristos# } 31915af53050Schristos } 31925af53050Schristos 31935af53050Schristos # Finally done, return the result. 31945af53050Schristos return %{$table{$target}}; 31955af53050Schristos} 31965af53050Schristos 3197a89c9211Schristossub usage 3198a89c9211Schristos { 3199a89c9211Schristos print STDERR $usage; 3200a89c9211Schristos print STDERR "\npick os/compiler from:\n"; 3201a89c9211Schristos my $j=0; 3202a89c9211Schristos my $i; 3203a89c9211Schristos my $k=0; 3204a89c9211Schristos foreach $i (sort keys %table) 3205a89c9211Schristos { 32065af53050Schristos next if $table{$i}->{template}; 3207a89c9211Schristos next if $i =~ /^debug/; 3208a89c9211Schristos $k += length($i) + 1; 3209a89c9211Schristos if ($k > 78) 3210a89c9211Schristos { 3211a89c9211Schristos print STDERR "\n"; 3212a89c9211Schristos $k=length($i); 3213a89c9211Schristos } 3214a89c9211Schristos print STDERR $i . " "; 3215a89c9211Schristos } 3216a89c9211Schristos foreach $i (sort keys %table) 3217a89c9211Schristos { 32185af53050Schristos next if $table{$i}->{template}; 3219a89c9211Schristos next if $i !~ /^debug/; 3220a89c9211Schristos $k += length($i) + 1; 3221a89c9211Schristos if ($k > 78) 3222a89c9211Schristos { 3223a89c9211Schristos print STDERR "\n"; 3224a89c9211Schristos $k=length($i); 3225a89c9211Schristos } 3226a89c9211Schristos print STDERR $i . " "; 3227a89c9211Schristos } 3228a89c9211Schristos exit(1); 3229a89c9211Schristos } 3230a89c9211Schristos 3231e0ea3921Schristossub compiler_predefined { 3232e0ea3921Schristos state %predefined; 3233e0ea3921Schristos my $cc = shift; 3234e0ea3921Schristos 3235e0ea3921Schristos return () if $^O eq 'VMS'; 3236e0ea3921Schristos 3237e0ea3921Schristos die 'compiler_predefined called without a compiler command' 3238e0ea3921Schristos unless $cc; 3239e0ea3921Schristos 3240e0ea3921Schristos if (! $predefined{$cc}) { 3241e0ea3921Schristos 3242e0ea3921Schristos $predefined{$cc} = {}; 3243e0ea3921Schristos 3244e0ea3921Schristos # collect compiler pre-defines from gcc or gcc-alike... 3245e0ea3921Schristos open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |"); 3246e0ea3921Schristos while (my $l = <PIPE>) { 3247e0ea3921Schristos $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last; 3248e0ea3921Schristos $predefined{$cc}->{$1} = $2 // ''; 3249e0ea3921Schristos } 3250e0ea3921Schristos close(PIPE); 3251e0ea3921Schristos } 3252e0ea3921Schristos 3253e0ea3921Schristos return %{$predefined{$cc}}; 3254e0ea3921Schristos} 3255e0ea3921Schristos 3256a89c9211Schristossub which 3257a89c9211Schristos{ 3258a89c9211Schristos my ($name)=@_; 32595af53050Schristos 32605af53050Schristos if (eval { require IPC::Cmd; 1; }) { 32615af53050Schristos IPC::Cmd->import(); 32625af53050Schristos return scalar IPC::Cmd::can_run($name); 32635af53050Schristos } else { 32645af53050Schristos # if there is $directories component in splitpath, 32655af53050Schristos # then it's not something to test with $PATH... 32665af53050Schristos return $name if (File::Spec->splitpath($name))[1]; 32675af53050Schristos 32685af53050Schristos foreach (File::Spec->path()) { 32695af53050Schristos my $fullpath = catfile($_, "$name$target{exe_extension}"); 32705af53050Schristos if (-f $fullpath and -x $fullpath) { 32715af53050Schristos return $fullpath; 32725af53050Schristos } 3273a89c9211Schristos } 3274a89c9211Schristos } 3275a89c9211Schristos} 3276a89c9211Schristos 3277e0ea3921Schristossub env 3278e0ea3921Schristos{ 3279e0ea3921Schristos my $name = shift; 3280e0ea3921Schristos my %opts = @_; 3281e0ea3921Schristos 3282e0ea3921Schristos unless ($opts{cacheonly}) { 3283e0ea3921Schristos # Note that if $ENV{$name} doesn't exist or is undefined, 3284e0ea3921Schristos # $config{perlenv}->{$name} will be created with the value 3285e0ea3921Schristos # undef. This is intentional. 3286e0ea3921Schristos 3287e0ea3921Schristos $config{perlenv}->{$name} = $ENV{$name} 3288e0ea3921Schristos if ! exists $config{perlenv}->{$name}; 3289e0ea3921Schristos } 3290e0ea3921Schristos return $config{perlenv}->{$name}; 3291e0ea3921Schristos} 3292e0ea3921Schristos 32935af53050Schristos# Configuration printer ############################################## 3294a89c9211Schristos 3295a89c9211Schristossub print_table_entry 3296a89c9211Schristos{ 3297e0ea3921Schristos local $now_printing = shift; 3298e0ea3921Schristos my %target = resolve_config($now_printing); 32995af53050Schristos my $type = shift; 3300a89c9211Schristos 33015af53050Schristos # Don't print the templates 33025af53050Schristos return if $target{template}; 3303a89c9211Schristos 33045af53050Schristos my @sequence = ( 33055af53050Schristos "sys_id", 3306e0ea3921Schristos "cpp", 3307e0ea3921Schristos "cppflags", 3308e0ea3921Schristos "defines", 3309e0ea3921Schristos "includes", 33105af53050Schristos "cc", 33115af53050Schristos "cflags", 33125af53050Schristos "ld", 33135af53050Schristos "lflags", 33145af53050Schristos "loutflag", 33155af53050Schristos "ex_libs", 33165af53050Schristos "bn_ops", 33178fbed61eSchristos "enable", 33188fbed61eSchristos "disable", 33195af53050Schristos "poly1035_asm_src", 33205af53050Schristos "thread_scheme", 33215af53050Schristos "perlasm_scheme", 33225af53050Schristos "dso_scheme", 33235af53050Schristos "shared_target", 33245af53050Schristos "shared_cflag", 33255af53050Schristos "shared_defines", 33265af53050Schristos "shared_ldflag", 33275af53050Schristos "shared_rcflag", 33285af53050Schristos "shared_extension", 33295af53050Schristos "dso_extension", 33305af53050Schristos "obj_extension", 33315af53050Schristos "exe_extension", 33325af53050Schristos "ranlib", 33335af53050Schristos "ar", 33345af53050Schristos "arflags", 33355af53050Schristos "aroutflag", 33365af53050Schristos "rc", 33375af53050Schristos "rcflags", 33385af53050Schristos "rcoutflag", 33395af53050Schristos "mt", 33405af53050Schristos "mtflags", 33415af53050Schristos "mtinflag", 33425af53050Schristos "mtoutflag", 33435af53050Schristos "multilib", 33445af53050Schristos "build_scheme", 33455af53050Schristos ); 3346a89c9211Schristos 33475af53050Schristos if ($type eq "TABLE") { 33485af53050Schristos print "\n"; 3349e0ea3921Schristos print "*** $now_printing\n"; 33505af53050Schristos foreach (@sequence) { 33515af53050Schristos if (ref($target{$_}) eq "ARRAY") { 33525af53050Schristos printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}}); 33535af53050Schristos } else { 33545af53050Schristos printf "\$%-12s = %s\n", $_, $target{$_}; 3355a89c9211Schristos } 3356a89c9211Schristos } 33575af53050Schristos } elsif ($type eq "HASH") { 33585af53050Schristos my $largest = 33595af53050Schristos length((sort { length($a) <=> length($b) } @sequence)[-1]); 3360e0ea3921Schristos print " '$now_printing' => {\n"; 33615af53050Schristos foreach (@sequence) { 33625af53050Schristos if ($target{$_}) { 33635af53050Schristos if (ref($target{$_}) eq "ARRAY") { 33645af53050Schristos print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n"; 33655af53050Schristos } else { 33665af53050Schristos print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n"; 33675af53050Schristos } 33685af53050Schristos } 33695af53050Schristos } 33705af53050Schristos print " },\n"; 33715af53050Schristos } 3372a89c9211Schristos} 3373b367ed38Sspz 33745af53050Schristos# Utility routines ################################################### 33755af53050Schristos 33765af53050Schristos# On VMS, if the given file is a logical name, File::Spec::Functions 33775af53050Schristos# will consider it an absolute path. There are cases when we want a 33785af53050Schristos# purely syntactic check without checking the environment. 33795af53050Schristossub isabsolute { 33805af53050Schristos my $file = shift; 33815af53050Schristos 33825af53050Schristos # On non-platforms, we just use file_name_is_absolute(). 33835af53050Schristos return file_name_is_absolute($file) unless $^O eq "VMS"; 33845af53050Schristos 33855af53050Schristos # If the file spec includes a device or a directory spec, 33865af53050Schristos # file_name_is_absolute() is perfectly safe. 33875af53050Schristos return file_name_is_absolute($file) if $file =~ m|[:\[]|; 33885af53050Schristos 33895af53050Schristos # Here, we know the given file spec isn't absolute 33905af53050Schristos return 0; 33915af53050Schristos} 33925af53050Schristos 33935af53050Schristos# Makes a directory absolute and cleans out /../ in paths like foo/../bar 33945af53050Schristos# On some platforms, this uses rel2abs(), while on others, realpath() is used. 33955af53050Schristos# realpath() requires that at least all path components except the last is an 33965af53050Schristos# existing directory. On VMS, the last component of the directory spec must 33975af53050Schristos# exist. 33985af53050Schristossub absolutedir { 33995af53050Schristos my $dir = shift; 34005af53050Schristos 34015af53050Schristos # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which 34025af53050Schristos # will return the volume name for the device, no matter what. Also, 34035af53050Schristos # it will return an incorrect directory spec if the argument is a 34045af53050Schristos # directory that doesn't exist. 34055af53050Schristos if ($^O eq "VMS") { 34065af53050Schristos return rel2abs($dir); 34075af53050Schristos } 34085af53050Schristos 3409*7d9ffdb3Schristos # realpath() on Windows seems to check if the directory actually exists, 3410*7d9ffdb3Schristos # which isn't what is wanted here. All we want to know is if a directory 3411*7d9ffdb3Schristos # spec is absolute, not if it exists. 3412*7d9ffdb3Schristos if ($^O eq "MSWin32") { 3413*7d9ffdb3Schristos return rel2abs($dir); 3414*7d9ffdb3Schristos } 3415*7d9ffdb3Schristos 34165af53050Schristos # We use realpath() on Unix, since no other will properly clean out 34175af53050Schristos # a directory spec. 34185af53050Schristos use Cwd qw/realpath/; 34195af53050Schristos 34205af53050Schristos return realpath($dir); 34215af53050Schristos} 34225af53050Schristos 34234a7cf967Schristos# Check if all paths are one and the same, using stat. They must both exist 34244a7cf967Schristos# We need this for the cases when File::Spec doesn't detect case insensitivity 34254a7cf967Schristos# (File::Spec::Unix assumes case sensitivity) 34264a7cf967Schristossub samedir { 34274a7cf967Schristos die "samedir expects two arguments\n" unless scalar @_ == 2; 34284a7cf967Schristos 34294a7cf967Schristos my @stat0 = stat($_[0]); # First argument 34304a7cf967Schristos my @stat1 = stat($_[1]); # Second argument 34314a7cf967Schristos 34324a7cf967Schristos die "Couldn't stat $_[0]" unless @stat0; 34334a7cf967Schristos die "Couldn't stat $_[1]" unless @stat1; 34344a7cf967Schristos 34354a7cf967Schristos # Compare device number 34364a7cf967Schristos return 0 unless ($stat0[0] == $stat1[0]); 34374a7cf967Schristos # Compare "inode". The perl manual recommends comparing as 34384a7cf967Schristos # string rather than as number. 34394a7cf967Schristos return 0 unless ($stat0[1] eq $stat1[1]); 34404a7cf967Schristos 34414a7cf967Schristos return 1; # All the same 34424a7cf967Schristos} 34434a7cf967Schristos 34445af53050Schristossub quotify { 34455af53050Schristos my %processors = ( 34465af53050Schristos perl => sub { my $x = shift; 34475af53050Schristos $x =~ s/([\\\$\@"])/\\$1/g; 34485af53050Schristos return '"'.$x.'"'; }, 34495af53050Schristos maybeshell => sub { my $x = shift; 34505af53050Schristos (my $y = $x) =~ s/([\\\"])/\\$1/g; 34515af53050Schristos if ($x ne $y || $x =~ m|\s|) { 34525af53050Schristos return '"'.$y.'"'; 34535af53050Schristos } else { 34545af53050Schristos return $x; 34555af53050Schristos } 34565af53050Schristos }, 34575af53050Schristos ); 34585af53050Schristos my $for = shift; 34595af53050Schristos my $processor = 34605af53050Schristos defined($processors{$for}) ? $processors{$for} : sub { shift; }; 34615af53050Schristos 34625af53050Schristos return map { $processor->($_); } @_; 34635af53050Schristos} 34645af53050Schristos 34655af53050Schristos# collect_from_file($filename, $line_concat_cond_re, $line_concat) 34665af53050Schristos# $filename is a file name to read from 34675af53050Schristos# $line_concat_cond_re is a regexp detecting a line continuation ending 34685af53050Schristos# $line_concat is a CODEref that takes care of concatenating two lines 34695af53050Schristossub collect_from_file { 34705af53050Schristos my $filename = shift; 34715af53050Schristos my $line_concat_cond_re = shift; 34725af53050Schristos my $line_concat = shift; 34735af53050Schristos 34745af53050Schristos open my $fh, $filename || die "unable to read $filename: $!\n"; 34755af53050Schristos return sub { 34765af53050Schristos my $saved_line = ""; 34775af53050Schristos $_ = ""; 34785af53050Schristos while (<$fh>) { 34795af53050Schristos s|\R$||; 34805af53050Schristos if (defined $line_concat) { 34815af53050Schristos $_ = $line_concat->($saved_line, $_); 34825af53050Schristos $saved_line = ""; 34835af53050Schristos } 34845af53050Schristos if (defined $line_concat_cond_re && /$line_concat_cond_re/) { 34855af53050Schristos $saved_line = $_; 34865af53050Schristos next; 34875af53050Schristos } 34885af53050Schristos return $_; 34895af53050Schristos } 34905af53050Schristos die "$filename ending with continuation line\n" if $_; 34915af53050Schristos close $fh; 34925af53050Schristos return undef; 34935af53050Schristos } 34945af53050Schristos} 34955af53050Schristos 34965af53050Schristos# collect_from_array($array, $line_concat_cond_re, $line_concat) 34975af53050Schristos# $array is an ARRAYref of lines 34985af53050Schristos# $line_concat_cond_re is a regexp detecting a line continuation ending 34995af53050Schristos# $line_concat is a CODEref that takes care of concatenating two lines 35005af53050Schristossub collect_from_array { 35015af53050Schristos my $array = shift; 35025af53050Schristos my $line_concat_cond_re = shift; 35035af53050Schristos my $line_concat = shift; 35045af53050Schristos my @array = (@$array); 35055af53050Schristos 35065af53050Schristos return sub { 35075af53050Schristos my $saved_line = ""; 35085af53050Schristos $_ = ""; 35095af53050Schristos while (defined($_ = shift @array)) { 35105af53050Schristos s|\R$||; 35115af53050Schristos if (defined $line_concat) { 35125af53050Schristos $_ = $line_concat->($saved_line, $_); 35135af53050Schristos $saved_line = ""; 35145af53050Schristos } 35155af53050Schristos if (defined $line_concat_cond_re && /$line_concat_cond_re/) { 35165af53050Schristos $saved_line = $_; 35175af53050Schristos next; 35185af53050Schristos } 35195af53050Schristos return $_; 35205af53050Schristos } 35215af53050Schristos die "input text ending with continuation line\n" if $_; 35225af53050Schristos return undef; 35235af53050Schristos } 35245af53050Schristos} 35255af53050Schristos 35265af53050Schristos# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...) 35275af53050Schristos# $lineiterator is a CODEref that delivers one line at a time. 35285af53050Schristos# All following arguments are regex/CODEref pairs, where the regexp detects a 35295af53050Schristos# line and the CODEref does something with the result of the regexp. 35305af53050Schristossub collect_information { 35315af53050Schristos my $lineiterator = shift; 35325af53050Schristos my %collectors = @_; 35335af53050Schristos 35345af53050Schristos while(defined($_ = $lineiterator->())) { 35355af53050Schristos s|\R$||; 35365af53050Schristos my $found = 0; 35375af53050Schristos if ($collectors{"BEFORE"}) { 35385af53050Schristos $collectors{"BEFORE"}->($_); 35395af53050Schristos } 35405af53050Schristos foreach my $re (keys %collectors) { 35415af53050Schristos if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) { 35425af53050Schristos $collectors{$re}->($lineiterator); 35435af53050Schristos $found = 1; 35445af53050Schristos }; 35455af53050Schristos } 35465af53050Schristos if ($collectors{"OTHERWISE"}) { 35475af53050Schristos $collectors{"OTHERWISE"}->($lineiterator, $_) 35485af53050Schristos unless $found || !defined $collectors{"OTHERWISE"}; 35495af53050Schristos } 35505af53050Schristos if ($collectors{"AFTER"}) { 35515af53050Schristos $collectors{"AFTER"}->($_); 35525af53050Schristos } 35535af53050Schristos } 35545af53050Schristos} 35555af53050Schristos 35565af53050Schristos# tokenize($line) 35578fbed61eSchristos# tokenize($line,$separator) 35585af53050Schristos# $line is a line of text to split up into tokens 35598fbed61eSchristos# $separator [optional] is a regular expression that separates the tokens, 35608fbed61eSchristos# the default being spaces. Do not use quotes of any kind as separators, 35618fbed61eSchristos# that will give undefined results. 35628fbed61eSchristos# Returns a list of tokens. 35635af53050Schristos# 35648fbed61eSchristos# Tokens are divided by separator (spaces by default). If the tokens include 35658fbed61eSchristos# the separators, they have to be quoted with single or double quotes. 35668fbed61eSchristos# Double quotes inside a double quoted token must be escaped. Escaping is done 35675af53050Schristos# with backslash. 35685af53050Schristos# Basically, the same quoting rules apply for " and ' as in any 35695af53050Schristos# Unix shell. 35705af53050Schristossub tokenize { 35715af53050Schristos my $line = my $debug_line = shift; 35728fbed61eSchristos my $separator = shift // qr|\s+|; 35735af53050Schristos my @result = (); 35745af53050Schristos 35758fbed61eSchristos if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) { 35768fbed61eSchristos print STDERR "DEBUG[tokenize]: \$separator = $separator\n"; 35778fbed61eSchristos } 35788fbed61eSchristos 35798fbed61eSchristos while ($line =~ s|^${separator}||, $line ne "") { 35805af53050Schristos my $token = ""; 35818fbed61eSchristos again: 35828fbed61eSchristos $line =~ m/^(.*?)(${separator}|"|'|$)/; 35838fbed61eSchristos $token .= $1; 35848fbed61eSchristos $line = $2.$'; 35858fbed61eSchristos 35865af53050Schristos if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) { 35875af53050Schristos $token .= $1; 35885af53050Schristos $line = $'; 35898fbed61eSchristos goto again; 35905af53050Schristos } elsif ($line =~ m/^'([^']*)'/) { 35915af53050Schristos $token .= $1; 35925af53050Schristos $line = $'; 35938fbed61eSchristos goto again; 35945af53050Schristos } 35955af53050Schristos push @result, $token; 35965af53050Schristos } 35975af53050Schristos 35985af53050Schristos if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) { 35995af53050Schristos print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n"; 36005af53050Schristos print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n"; 36015af53050Schristos } 36025af53050Schristos return @result; 3603b367ed38Sspz} 3604