X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=Configure;h=7ff8b0621447a566430923246aa214183a3cdde3;hp=3df3e0c96a82cfc8849600713841455facdfa126;hb=HEAD;hpb=f246f54f18d380791cc60be4aea0fbc7253a9a20 diff --git a/Configure b/Configure index 3df3e0c96a..cef9e8c3e6 100755 --- a/Configure +++ b/Configure @@ -1,6 +1,6 @@ #! /usr/bin/env perl # -*- mode: perl; -*- -# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -20,13 +20,32 @@ use File::Path qw/mkpath/; use OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt"; use OpenSSL::Glob; use OpenSSL::Template; +use OpenSSL::config; -# see INSTALL for instructions. +# see INSTALL.md for instructions. my $orig_death_handler = $SIG{__DIE__}; $SIG{__DIE__} = \&death_handler; -my $usage="Usage: Configure [no- ...] [enable- ...] [-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"; +my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[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"; + +my $banner = <<"EOF"; + +********************************************************************** +*** *** +*** OpenSSL has been successfully configured *** +*** *** +*** If you encounter a problem while building, please open an *** +*** issue on GitHub *** +*** and include the output from the following command: *** +*** *** +*** perl configdata.pm --dump *** +*** *** +*** (If you are new to OpenSSL, you might want to consult the *** +*** 'Troubleshooting' section in the INSTALL.md file first) *** +*** *** +********************************************************************** +EOF # Options: # @@ -42,21 +61,34 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # given with --prefix. # This becomes the value of OPENSSLDIR in Makefile and in C. # (Default: PREFIX/ssl) +# --banner=".." Output specified text instead of default completion banner +# +# -w Don't wait after showing a Configure warning # # --cross-compile-prefix Add specified prefix to binutils components. # -# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0.0 / 3. -# Do not compile support for interfaces deprecated as of the -# specified OpenSSL version. +# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0 +# Define the public APIs as they were for that version +# including patch releases. If 'no-deprecated' is also +# given, do not compile support for interfaces deprecated +# up to and including the specified OpenSSL version. # # no-hw-xxx do not compile support for specific crypto hardware. # Generic OpenSSL-style methods relating to this support # are always compiled but return NULL if the hardware # support isn't compiled. +# +# enable-demos Enable the building of the example code in the demos directory +# enable-h3demo Enable the http3 demo, which currently only links to the +# external nghttp3 library on unix platforms # no-hw do not compile support for any crypto hardware. # [no-]threads [don't] try to create a library that is suitable for # multithreaded applications (default is "threads" if we # know how to do it) +# [no-]thread-pool +# [don't] allow thread pool functionality +# [no-]default-thread-pool +# [don't] allow default thread pool functionality # [no-]shared [don't] try to create shared libraries when supported. # [no-]pic [don't] try to build position independent code when supported. # If disabled, it also disables shared and dynamic-engine. @@ -64,15 +96,16 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # no-egd do not compile support for the entropy-gathering daemon APIs # [no-]zlib [don't] compile support for zlib compression. # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared -# library and will be loaded in run-time by the OpenSSL library. +# library and will be loaded at run-time by the OpenSSL library. # sctp include SCTP support +# no-quic disable QUIC support # no-uplink Don't build support for UPLINK interface. # enable-weak-ssl-ciphers # Enable weak ciphers that are disabled by default. # 386 generate 80386 code in assembly modules # no-sse2 disables IA-32 SSE2 code in assembly modules, the above # mentioned '386' option implies this one -# no- build without specified algorithm (rsa, idea, rc5, ...) +# no- build without specified algorithm (dsa, idea, rc5, ...) # - + All options which are unknown to the 'Configure' script are # / passed through to the compiler. Unix-style options beginning # with a '-' or '+' are recognized, as well as Windows-style @@ -114,7 +147,6 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # get past these. Note that we only use these with C compilers, not with # C++ compilers. -# DEBUG_UNUSED enables __owur (warn unused result) checks. # -DPEDANTIC complements -pedantic and is meant to mask code that # is not strictly standard-compliant and/or implementation-specific, # e.g. inline assembly, disregards to alignment requirements, such @@ -128,9 +160,9 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # but 'long long' type. my @gcc_devteam_warn = qw( - -DDEBUG_UNUSED - -DPEDANTIC -pedantic -Wno-long-long + -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG -Wall + -Wmissing-declarations -Wextra -Wno-unused-parameter -Wno-missing-field-initializers @@ -138,7 +170,8 @@ my @gcc_devteam_warn = qw( -Wsign-compare -Wshadow -Wformat - -Wtype-limits + -Wno-type-limits + -Wno-tautological-constant-out-of-range-compare -Wundef -Werror -Wmissing-prototypes @@ -159,14 +192,15 @@ my @clang_devteam_warn = qw( -Wno-parentheses-equality -Wno-language-extension-token -Wno-extended-offsetof + -Wno-missing-braces -Wconditional-uninitialized -Wincompatible-pointer-types-discards-qualifiers -Wmissing-variable-declarations ); -# This adds backtrace information to the memory leak info. Is only used -# when crypto-mdebug-backtrace is enabled. -my $memleak_devteam_backtrace = "-rdynamic"; +my @cl_devteam_warn = qw( + /WX +); my $strict_warnings = 0; @@ -182,17 +216,31 @@ our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT"; # # API compatibility name to version number mapping. # -my $maxapi = "3.0.0"; # API for "no-deprecated" builds my $apitable = { - "3.0.0" => 3, - "1.1.1" => 2, - "1.1.0" => 2, - "1.0.2" => 1, - "1.0.1" => 1, - "1.0.0" => 1, - "0.9.8" => 0, + # This table expresses when API additions or changes can occur. + # The numbering used changes from 3.0 and on because we updated + # (solidified) our version numbering scheme at that point. + + # From 3.0 and on, we internalise the given version number in decimal + # as MAJOR * 10000 + MINOR * 100 + 0 + "3.0.0" => 30000, + "3.0" => 30000, + + # Note that before 3.0, we didn't have the same version number scheme. + # Still, the numbering we use here covers what we need. + "1.1.1" => 10101, + "1.1.0" => 10100, + "1.0.2" => 10002, + "1.0.1" => 10001, + "1.0.0" => 10000, + "0.9.8" => 908, }; +# For OpenSSL::config::get_platform +my %guess_opts = (); + +my $dryrun = 0; + our %table = (); our %config = (); our %withargs = (); @@ -221,12 +269,25 @@ sub resolve_config; # Unified build supports separate build dir my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax + +# File::Spec::Unix doesn't detect case insensitivity, so we make sure to +# check if the source and build directory are really the same, and make +# them so. This avoids all kinds of confusion later on. +# We must check @File::Spec::ISA rather than using File::Spec->isa() to +# know if File::Spec ended up loading File::Spec::Unix. +$srcdir = $blddir + if (grep(/::Unix$/, @File::Spec::ISA) + && samedir($srcdir, $blddir)); + my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl")); my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR'; -$config{sourcedir} = abs2rel($srcdir); -$config{builddir} = abs2rel($blddir); +$config{sourcedir} = abs2rel($srcdir, $blddir); +$config{builddir} = abs2rel($blddir, $blddir); +# echo -n 'holy hand grenade of antioch' | openssl sha256 +$config{FIPSKEY} = + 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813'; # Collect reconfiguration information if needed my @argvcopy=@ARGV; @@ -254,39 +315,59 @@ if (grep /^reconf(igure)?$/, @argvcopy) { $config{perlargv} = [ @argvcopy ]; +# Historical: if known directories in crypto/ have been removed, it means +# that those sub-systems are disabled. +# (the other option would be to removed them from the SUBDIRS statement in +# crypto/build.info) +# We reverse the input list for cosmetic purely reasons, to compensate that +# 'unshift' adds at the front of the list (i.e. in reverse input order). +foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh', + 'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2', + 'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha', + 'sm2', 'sm3', 'sm4') ) { + unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_); +} + # Collect version numbers -$config{major} = "unknown"; -$config{minor} = "unknown"; -$config{patch} = "unknown"; -$config{prerelease} = ""; -$config{build_metadata} = ""; -$config{shlib_version} = "unknown"; +my %version = (); collect_information( - collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')), - qr/#\s+define\s+OPENSSL_VERSION_MAJOR\s+(\d+)/ => - sub { $config{major} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_MINOR\s+(\d+)/ => - sub { $config{minor} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_PATCH\s+(\d+)/ => - sub { $config{patch} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_PRE_RELEASE\s+"((?:\\.|[^"])*)"/ => - sub { $config{prerelease} = $1; }, - qr/#\s+define\s+OPENSSL_VERSION_BUILD_METADATA\s+"((?:\\.|[^"])*)"/ => - sub { $config{build_metadata} = $1; }, - qr/#\s+define\s+OPENSSL_SHLIB_VERSION\s+([\d\.]+)/ => - sub { $config{shlib_version} = $1; }, + collect_from_file(catfile($srcdir,'VERSION.dat')), + qr/\s*(\w+)\s*=\s*(.*?)\s*$/ => + sub { + # Only define it if there is a value at all + if ($2 ne '') { + my $k = $1; + my $v = $2; + # Some values are quoted. Trim the quotes + $v = $1 if $v =~ /^"(.*)"$/; + $version{uc $k} = $v; + } + }, + "OTHERWISE" => + sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" }, ); -die "erroneous version information in opensslv.h: ", - "$config{major}.$config{minor}.$config{patch}, $config{shlib_version}\n" - if ($config{major} eq "unknown" - || $config{minor} eq "unknown" - || $config{patch} eq "unknown" - || $config{shlib_version} eq "unknown"); + +$config{major} = $version{MAJOR} // 'unknown'; +$config{minor} = $version{MINOR} // 'unknown'; +$config{patch} = $version{PATCH} // 'unknown'; +$config{prerelease} = + defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : ''; +$config{build_metadata} = + defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : ''; +$config{shlib_version} = $version{SHLIB_VERSION} // 'unknown'; +$config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx'; $config{version} = "$config{major}.$config{minor}.$config{patch}"; $config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}"; +die "erroneous version information in VERSION.dat: ", + "$config{version}, $config{shlib_version}\n" + unless (defined $version{MAJOR} + && defined $version{MINOR} + && defined $version{PATCH} + && defined $version{SHLIB_VERSION}); + # Collect target configurations my $pattern = catfile(dirname($0), "Configurations", "*.conf"); @@ -308,6 +389,12 @@ if (defined env($local_config_envname)) { } } +# Fail if no configuration is apparent +if (!%table) { + print "Failed to find any os/compiler configurations. Please make sure the Configurations directory is included.\n"; + &usage; +} + # Save away perl command information $config{perl_cmd} = $^X; $config{perl_version} = $Config{version}; @@ -329,20 +416,28 @@ my @dtls = qw(dtls1 dtls1_2); # For developers: keep it sorted alphabetically my @disablables = ( - "ktls", + "acvp-tests", "afalgeng", + "apps", + "argon2", "aria", "asan", "asm", "async", + "atexit", "autoalginit", "autoerrinit", "autoload-config", "bf", "blake2", + "brotli", + "brotli-dynamic", "buildtest-c++", + "bulk", + "cached-fetch", "camellia", "capieng", + "winstore", "cast", "chacha", "cmac", @@ -350,33 +445,41 @@ my @disablables = ( "cms", "comp", "crypto-mdebug", - "crypto-mdebug-backtrace", "ct", + "default-thread-pool", + "demos", + "h3demo", "deprecated", "des", "devcryptoeng", "dgram", "dh", + "docs", "dsa", "dso", "dtls", "dynamic-engine", "ec", "ec2m", + "ec_nistp_64_gcc_128", "ecdh", "ecdsa", - "ec_nistp_64_gcc_128", + "ecx", "egd", "engine", "err", "external-tests", "filenames", "fips", - "fuzz-libfuzzer", + "fips-securitychecks", "fuzz-afl", + "fuzz-libfuzzer", "gost", + "http", "idea", + "ktls", "legacy", + "loadereng", "makedepend", "md2", "md4", @@ -385,14 +488,16 @@ my @disablables = ( "msan", "multiblock", "nextprotoneg", - "pinshared", "ocb", "ocsp", "padlockeng", "pic", + "pinshared", "poly1305", "posix-io", "psk", + "quic", + "unstable-qlog", "rc2", "rc4", "rc5", @@ -401,11 +506,13 @@ my @disablables = ( "rmd160", "scrypt", "sctp", + "secure-memory", "seed", "shared", "siphash", "siv", "sm2", + "sm2-precomp", "sm3", "sm4", "sock", @@ -417,6 +524,8 @@ my @disablables = ( "static-engine", "stdio", "tests", + "tfo", + "thread-pool", "threads", "tls", "trace", @@ -425,10 +534,12 @@ my @disablables = ( "ui-console", "unit-test", "uplink", - "whirlpool", "weak-ssl-ciphers", + "whirlpool", "zlib", "zlib-dynamic", + "zstd", + "zstd-dynamic", ); foreach my $proto ((@tls, @dtls)) { @@ -447,6 +558,7 @@ my @disablables_int = qw( my %deprecated_disablables = ( "ssl2" => undef, "buf-freelists" => undef, + "crypto-mdebug-backtrace" => undef, "hw" => "hw", # causes cascade, but no macro "hw-padlock" => "padlockeng", "ripemd" => "rmd160", @@ -457,46 +569,70 @@ my %deprecated_disablables = ( # All of the following are disabled by default: our %disabled = ( # "what" => "comment" + "fips" => "default", "asan" => "default", + "brotli" => "default", + "brotli-dynamic" => "default", "buildtest-c++" => "default", "crypto-mdebug" => "default", "crypto-mdebug-backtrace" => "default", + "demos" => "default", + "h3demo" => "default", "devcryptoeng" => "default", "ec_nistp_64_gcc_128" => "default", "egd" => "default", "external-tests" => "default", - "fuzz-libfuzzer" => "default", "fuzz-afl" => "default", + "fuzz-libfuzzer" => "default", + "ktls" => "default", "md2" => "default", "msan" => "default", "rc5" => "default", "sctp" => "default", - "ssl-trace" => "default", "ssl3" => "default", "ssl3-method" => "default", + "tfo" => "default", "trace" => "default", "ubsan" => "default", "unit-test" => "default", "weak-ssl-ciphers" => "default", "zlib" => "default", "zlib-dynamic" => "default", - "ktls" => "default", + "zstd" => "default", + "zstd-dynamic" => "default", ); # Note: => pair form used for aesthetics, not to truly make a hash table my @disable_cascades = ( # "what" => [ "cascade", ... ] + "bulk" => [ "shared", "dso", + "aria", "async", "atexit", "autoload-config", + "blake2", "bf", "camellia", "cast", "chacha", + "cmac", "cms", "cmp", "comp", "ct", + "des", "dgram", "dh", "dsa", + "ec", "engine", + "filenames", + "idea", "ktls", + "md4", "multiblock", "nextprotoneg", + "ocsp", "ocb", "poly1305", "psk", + "rc2", "rc4", "rmd160", + "seed", "siphash", "siv", + "sm3", "sm4", "srp", + "srtp", "ssl3-method", "ssl-trace", + "tfo", + "ts", "ui-console", "whirlpool", + "fips-securitychecks" ], sub { $config{processor} eq "386" } => [ "sse2" ], "ssl" => [ "ssl3" ], "ssl3-method" => [ "ssl3" ], "zlib" => [ "zlib-dynamic" ], + "brotli" => [ "brotli-dynamic" ], + "zstd" => [ "zstd-dynamic" ], "des" => [ "mdc2" ], - "ec" => [ "ecdsa", "ecdh", "sm2" ], - sub { $disabled{"ec"} && $disabled{"dh"} } - => [ "tls1_3" ], - "dgram" => [ "dtls", "sctp" ], - "sock" => [ "dgram" ], + "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost", "ecx" ], + "dgram" => [ "dtls", "quic", "sctp" ], + "sock" => [ "dgram", "tfo" ], "dtls" => [ @dtls ], sub { 0 == scalar grep { !$disabled{$_} } @dtls } => [ "dtls" ], @@ -504,16 +640,17 @@ my @disable_cascades = ( "tls" => [ @tls ], sub { 0 == scalar grep { !$disabled{$_} } @tls } => [ "tls" ], + "tls1_3" => [ "quic" ], + "quic" => [ "unstable-qlog" ], "crypto-mdebug" => [ "crypto-mdebug-backtrace" ], - # If no modules, then no dynamic engines either - "module" => [ "dynamic-engine" ], + "module" => [ "dynamic-engine", "fips" ], # Without shared libraries, dynamic engines aren't possible. # This is due to them having to link with libcrypto and register features # using the ENGINE functionality, and since that relies on global tables, - # those *have* to be exacty the same as the ones accessed from the app, + # those *have* to be exactly the same as the ones accessed from the app, # which cannot be guaranteed if shared libraries aren't present. # (note that even with shared libraries, both the app and dynamic engines # must be linked with the same library) @@ -526,27 +663,37 @@ my @disable_cascades = ( # or modules. "pic" => [ "shared", "module" ], - "module" => [ "fips" ], - - "engine" => [ grep /eng$/, @disablables ], + "engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ], + "dynamic-engine" => [ "loadereng" ], "hw" => [ "padlockeng" ], # no-autoalginit is only useful when building non-shared - "autoalginit" => [ "shared", "apps" ], + "autoalginit" => [ "shared", "apps", "fips" ], "stdio" => [ "apps", "capieng", "egd" ], "apps" => [ "tests" ], "tests" => [ "external-tests" ], - "comp" => [ "zlib" ], + "comp" => [ "zlib", "brotli", "zstd" ], "sm3" => [ "sm2" ], sub { !$disabled{"unit-test"} } => [ "heartbeats" ], sub { !$disabled{"msan"} } => [ "asm" ], - sub { $disabled{cmac}; } => [ "siv" ], - "legacy" => [ "md2" ], + "cmac" => [ "siv" ], + "legacy" => [ "md2" ], "cmp" => [ "crmf" ], + + "fips" => [ "fips-securitychecks", "acvp-tests" ], + + "threads" => [ "thread-pool" ], + "thread-pool" => [ "default-thread-pool" ], + + "blake2" => [ "argon2" ], + + "deprecated-3.0" => [ "engine", "srp" ], + + "http" => [ "ocsp" ] ); # Avoid protocol support holes. Also disable all versions below N, if version @@ -571,9 +718,7 @@ while ((my $first, my $second) = (shift @list, shift @list)) { # To remove something from %disabled, use "enable-foo". # For symmetry, "disable-foo" is a synonym for "no-foo". -&usage if ($#ARGV < 0); - -# For the "make variables" CINCLUDES and CDEFINES, we support lists with +# For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with # platform specific list separators. Users from those platforms should # recognise those separators from how you set up the PATH to find executables. # The default is the Unix like separator, :, but as an exception, we also @@ -617,6 +762,7 @@ my @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC ); # input, as opposed to the VAR=string option that override the corresponding # config target attributes my %useradd = ( + ASFLAGS => [], CPPDEFINES => [], CPPINCLUDES => [], CPPFLAGS => [], @@ -707,6 +853,7 @@ while (@argvcopy) s /^threads$/enable-threads/; s /^zlib$/enable-zlib/; s /^zlib-dynamic$/enable-zlib-dynamic/; + s /^fips$/enable-fips/; if (/^(no|disable|enable)-(.+)$/) { @@ -792,12 +939,36 @@ while (@argvcopy) { delete $disabled{"zlib"}; } + elsif ($1 eq "brotli-dynamic") + { + delete $disabled{"brotli"}; + } + elsif ($1 eq "zstd-dynamic") + { + delete $disabled{"zstd"}; + } my $algo = $1; delete $disabled{$algo}; # No longer an automatic choice $auto_threads = 0 if ($1 eq "threads"); } + elsif (/^-d$/) # From older 'config' + { + $config{build_type} = "debug"; + } + elsif (/^-v$/) # From older 'config' + { + $guess_opts{verbose} = 1; + } + elsif (/^-w$/) + { + $guess_opts{nowait} = 1; + } + elsif (/^-t$/) # From older 'config' + { + $dryrun = 1; + } elsif (/^--strict-warnings$/) { # Pretend that our strict flags is a C flag, and replace it @@ -815,31 +986,24 @@ while (@argvcopy) } elsif (/^386$/) { $config{processor}=386; } - elsif (/^fips$/) - { - die "FIPS mode not supported\n"; - } elsif (/^rsaref$/) { # No RSAref support any more since it's not needed. # The check for the option is there so scripts aren't # broken } - elsif (/^nofipscanistercheck$/) - { - die "FIPS mode not supported\n"; - } elsif (m|^[-+/]|) { if (/^--prefix=(.*)$/) { $config{prefix}=$1; - die "Directory given with --prefix MUST be absolute\n" - unless file_name_is_absolute($config{prefix}); } elsif (/^--api=(.*)$/) { - $config{api}=$1; + my $api = $1; + die "Unknown API compatibility level $api" + unless defined $apitable->{$api}; + $config{api}=$apitable->{$api}; } elsif (/^--libdir=(.*)$/) { @@ -857,6 +1021,22 @@ while (@argvcopy) { $withargs{zlib_include}=$1; } + elsif (/^--with-brotli-lib=(.*)$/) + { + $withargs{brotli_lib}=$1; + } + elsif (/^--with-brotli-include=(.*)$/) + { + $withargs{brotli_include}=$1; + } + elsif (/^--with-zstd-lib=(.*)$/) + { + $withargs{zstd_lib}=$1; + } + elsif (/^--with-zstd-include=(.*)$/) + { + $withargs{zstd_include}=$1; + } elsif (/^--with-fuzzer-lib=(.*)$/) { $withargs{fuzzer_lib}=$1; @@ -874,6 +1054,20 @@ while (@argvcopy) push @seed_sources, $x; } } + elsif (/^--fips-key=(.*)$/) + { + $user{FIPSKEY}=lc($1); + die "Non-hex character in FIPS key\n" + if $user{FIPSKEY} =~ /[^a-f0-9]/; + die "FIPS key must have even number of characters\n" + if length $1 & 1; + die "FIPS key too long (64 bytes max)\n" + if length $1 > 64; + } + elsif (/^--banner=(.*)$/) + { + $banner = $1 . "\n"; + } elsif (/^--cross-compile-prefix=(.*)$/) { $user{CROSS_COMPILE}=$1; @@ -956,10 +1150,6 @@ while (@argvcopy) } } -if (defined($config{api}) && !exists $apitable->{$config{api}}) { - die "***** Unsupported api compatibility level: $config{api}\n", -} - if (keys %deprecated_options) { warn "***** Deprecated options: ", @@ -1014,7 +1204,11 @@ foreach (keys %user) { if (defined $value) { if (ref $user{$_} eq 'ARRAY') { - $user{$_} = [ split /$list_separator_re/, $value ]; + if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') { + $user{$_} = [ split /$list_separator_re/, $value ]; + } else { + $user{$_} = [ $value ]; + } } elsif (!defined $user{$_}) { $user{$_} = $value; } @@ -1028,6 +1222,23 @@ if (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ()) "***** any of asan, msan or ubsan\n"; } +# If no target was given, try guessing. +unless ($target) { + my %system_config = OpenSSL::config::get_platform(%guess_opts, %user); + + # The $system_config{disable} is used to populate %disabled with + # entries that aren't already there. + foreach ( @{$system_config{disable} // []} ) { + $disabled{$_} = 'system' unless defined $disabled{$_}; + } + delete $system_config{disable}; + + # Override config entries with stuff from the guesser. + # It's assumed that this really is nothing new. + %config = ( %config, %system_config ); + $target = $system_config{target}; +} + sub disable { my $disable_type = shift; @@ -1085,6 +1296,9 @@ if (scalar(@seed_sources) == 0) { print "Using os-specific seed configuration\n"; push @seed_sources, 'os'; } +if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) { + delete $disabled{'egd'}; +} if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) { die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1; warn <<_____ if scalar(@seed_sources) == 1; @@ -1097,7 +1311,8 @@ will not work unless the random generator is seeded manually by the application. Please read the 'Note on random number generation' section in the -INSTALL instructions and the RAND_DRBG(7) manual page for more details. +INSTALL.md instructions and the RAND_DRBG(7) manual page for more +details. ============================== WARNING =============================== _____ @@ -1122,7 +1337,26 @@ if ($d) { } } -&usage if !$table{$target} || $table{$target}->{template}; +if ($target) { + # It's possible that we have different config targets for specific + # toolchains, so we try to detect them, and go for the plain config + # target if not. + my $found; + foreach ( ( "$target-$user{CC}", "$target", undef ) ) { + $found=$_ if $table{$_} && !$table{$_}->{template}; + last if $found; + } + $target = $found; +} else { + # If we don't have a config target now, we try the C compiler as we + # fallback + my $cc = $user{CC} // 'cc'; + $target = $cc if $table{$cc} && !$table{$cc}->{template}; +} + +&usage unless $target; + +exit 0 if $dryrun; # From older 'config' $config{target} = $target; my %target = resolve_config($target); @@ -1221,49 +1455,18 @@ foreach (keys %useradd) { # At this point, we can forget everything about %user and %useradd, # because it's now all been merged into the corresponding $config entry -# Allow overriding the build file name -$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile"; - -###################################################################### -# Build up information for skipping certain directories depending on disabled -# features, as well as setting up macros for disabled features. - -# This is a tentative database of directories to skip. Some entries may not -# correspond to anything real, but that's ok, they will simply be ignored. -# The actual processing of these entries is done in the build.info lookup -# loop further down. -# -# The key is a Unix formated path in the source tree, the value is an index -# into %disabled_info, so any existing path gets added to a corresponding -# 'skipped' entry in there with the list of skipped directories. -my %skipdir = (); -my %disabled_info = (); # For configdata.pm -foreach my $what (sort keys %disabled) { - # There are deprecated disablables that translate to themselves. - # They cause disabling cascades, but should otherwise not regiter. - next if $deprecated_disablables{$what}; - - $config{options} .= " no-$what"; - - if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared', - 'module', 'pic', 'dynamic-engine', 'makedepend', - 'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) { - (my $WHAT = uc $what) =~ s|-|_|g; - my $skipdir = $what; - - # fix-up crypto/directory name(s) - $skipdir = "ripemd" if $what eq "rmd160"; - $skipdir = "whrlpool" if $what eq "whirlpool"; - - my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; - push @{$config{openssl_feature_defines}}, $macro; +if ($config{prefix} && !$config{CROSS_COMPILE}) { + die "Directory given with --prefix MUST be absolute\n" + unless file_name_is_absolute($config{prefix}); +} - $skipdir{engines} = $what if $what eq 'engine'; - $skipdir{"crypto/$skipdir"} = $what - unless $what eq 'async' || $what eq 'err' || $what eq 'dso'; - } +if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) { + disable('static', 'pic', 'threads'); } +# Allow overriding the build file name +$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile"; + # Make sure build_scheme is consistent. $target{build_scheme} = [ $target{build_scheme} ] if ref($target{build_scheme}) ne "ARRAY"; @@ -1271,7 +1474,7 @@ $target{build_scheme} = [ $target{build_scheme} ] my ($builder, $builder_platform, @builder_opts) = @{$target{build_scheme}}; -foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm", +foreach my $checker (($builder_platform."-".$config{build_file}."-checker.pm", $builder_platform."-checker.pm")) { my $checker_path = catfile($srcdir, "Configurations", $checker); if (-f $checker_path) { @@ -1300,7 +1503,7 @@ if ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m) } if ($target =~ /linux.*-mips/ && !$disabled{asm} - && !grep { $_ !~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) { + && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) { # minimally required architecture flags for assembly modules my $value; $value = '-mips2' if ($target =~ /mips32/); @@ -1360,13 +1563,12 @@ unless($disabled{threads}) { push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS"; } -# With "deprecated" disable all deprecated features. -if (defined($disabled{"deprecated"})) { - $config{api} = $maxapi; +if ($disabled{"unstable-qlog"}) { + $disabled{"qlog"} = 1; } my $no_shared_warn=0; -if ($target{shared_target} eq "") +if (($target{shared_target} // '') eq "") { $no_shared_warn = 1 if (!$disabled{shared} || !$disabled{"dynamic-engine"}); @@ -1374,10 +1576,8 @@ if ($target{shared_target} eq "") } if ($disabled{"dynamic-engine"}) { - push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; $config{dynamic_engines} = 0; } else { - push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE"; $config{dynamic_engines} = 1; } @@ -1386,9 +1586,7 @@ unless ($disabled{asan} || defined $detected_sanitizers{asan}) { } unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) { - # -DPEDANTIC or -fnosanitize=alignment may also be required on some - # platforms. - push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all"; + push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC"; } unless ($disabled{msan} || defined $detected_sanitizers{msan}) { @@ -1426,32 +1624,46 @@ if ($target{sys_id} ne "") push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}"; } -unless ($disabled{asm}) { -} - my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC}); my %predefined_CXX = $config{CXX} ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX}) : (); +unless ($disabled{asm}) { + # big endian systems can use ELFv2 ABI + if ($target eq "linux-ppc64" || $target eq "BSD-ppc64") { + $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2); + } +} + # Check for makedepend capabilities. if (!$disabled{makedepend}) { - if ($config{target} =~ /^(VC|vms)-/) { - # For VC- and vms- targets, there's nothing more to do here. The - # functionality is hard coded in the corresponding build files for - # cl (Windows) and CC/DECC (VMS). + # If the attribute makedep_scheme is defined, then we assume that the + # config target and its associated build file are programmed to deal + # with it. + # If makedep_scheme is undefined, we go looking for GCC compatible + # dependency making, and if that's not available, we try to fall back + # on 'makedepend'. + if ($target{makedep_scheme}) { + $config{makedep_scheme} = $target{makedep_scheme}; + # If the makedepcmd attribute is defined, copy it. If not, the + # build files will have to fend for themselves. + $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd}; } elsif (($predefined_C{__GNUC__} // -1) >= 3 && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) { # We know that GNU C version 3 and up as well as all clang # versions support dependency generation, but Xcode did not # handle $cc -M before clang support (but claims __GNUC__ = 3) - $config{makedepprog} = "\$(CROSS_COMPILE)$config{CC}"; + $config{makedep_scheme} = 'gcc'; } else { - # In all other cases, we look for 'makedepend', and disable the - # capability if not found. - $config{makedepprog} = which('makedepend'); - disable('unavailable', 'makedepend') unless $config{makedepprog}; + # In all other cases, we look for 'makedepend', and set the + # makedep_scheme value if we found it. + $config{makedepcmd} = which('makedepend'); + $config{makedep_scheme} = 'makedepend' if $config{makedepcmd}; } + + # If no depend scheme is set, we disable makedepend + disable('unavailable', 'makedepend') unless $config{makedep_scheme}; } if (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') { @@ -1498,6 +1710,14 @@ foreach (sort split(/\s+/,$target{bn_ops})) { die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n" if $count > 1; +$config{api} = $config{major} * 10000 + $config{minor} * 100 + unless $config{api}; +foreach (keys %$apitable) { + $disabled{"deprecated-$_"} = "deprecation" + if $disabled{deprecated} && $config{api} >= $apitable->{$_}; +} + +disable(); # Run a cascade now # Hack cflags for better warnings (dev option) ####################### @@ -1509,7 +1729,7 @@ $config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } @{$config{cxxflags}} ] if $config{CXX}; $config{openssl_api_defines} = [ - "OPENSSL_MIN_API=".($apitable->{$config{api} // ""} // -1) + "OPENSSL_CONFIGURED_API=".$config{api}, ]; my @strict_warnings_collection=(); @@ -1518,75 +1738,72 @@ if ($strict_warnings) my $wopt; my $gccver = $predefined_C{__GNUC__} // -1; - warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike" - unless $gccver >= 4; - push @strict_warnings_collection, @gcc_devteam_warn; - push @strict_warnings_collection, @clang_devteam_warn - if (defined($predefined_C{__clang__})); + if ($gccver >= 4) + { + push @strict_warnings_collection, @gcc_devteam_warn; + push @strict_warnings_collection, @clang_devteam_warn + if (defined($predefined_C{__clang__})); + } + elsif ($config{target} =~ /^VC-/) + { + push @strict_warnings_collection, @cl_devteam_warn; + } + else + { + warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC" + } } -if (grep { $_ eq '-static' } @{$config{LDFLAGS}}) { - disable('static', 'pic', 'threads'); -} - $config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings' ? @strict_warnings_collection : ( $_ ) } @{$config{CFLAGS}} ]; -unless ($disabled{"crypto-mdebug-backtrace"}) - { - foreach my $wopt (split /\s+/, $memleak_devteam_backtrace) - { - push @{$config{cflags}}, $wopt - unless grep { $_ eq $wopt } @{$config{cflags}}; - } - if ($target =~ /^BSD-/) - { - push @{$config{ex_libs}}, "-lexecinfo"; - } - } - unless ($disabled{afalgeng}) { $config{afalgeng}=""; if (grep { $_ eq 'afalgeng' } @{$target{enable}}) { - my $minver = 4*10000 + 1*100 + 0; - if ($config{CROSS_COMPILE} eq "") { - my $verstr = `uname -r`; - my ($ma, $mi1, $mi2) = split("\\.", $verstr); - ($mi2) = $mi2 =~ /(\d+)/; - my $ver = $ma*10000 + $mi1*100 + $mi2; - if ($ver < $minver) { - disable('too-old-kernel', 'afalgeng'); - } else { - push @{$config{engdirs}}, "afalg"; - } - } else { - disable('cross-compiling', 'afalgeng'); - } + push @{$config{engdirs}}, "afalg"; } else { disable('not-linux', 'afalgeng'); } } -push @{$config{openssl_feature_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng}); +unless ($disabled{devcryptoeng}) { + if ($target =~ m/^BSD/) { + my $maxver = 5*100 + 7; + my $sysstr = `uname -s`; + my $verstr = `uname -r`; + $sysstr =~ s|\R$||; + $verstr =~ s|\R$||; + my ($ma, $mi, @rest) = split m|\.|, $verstr; + my $ver = $ma*100 + $mi; + if ($sysstr eq 'OpenBSD' && $ver >= $maxver) { + disable('too-new-kernel', 'devcryptoeng'); + } + } +} unless ($disabled{ktls}) { $config{ktls}=""; + my $cc = $config{CROSS_COMPILE}.$config{CC}; if ($target =~ m/^linux/) { - my $usr = "/usr/$config{cross_compile_prefix}"; - chop($usr); - if ($config{cross_compile_prefix} eq "") { - $usr = "/usr"; - } - my $minver = (4 << 16) + (13 << 8) + 0; - my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`); - - if ($verstr[2] < $minver) { + system("printf '#include \n#include ' | $cc -E - >/dev/null 2>&1"); + if ($? != 0) { disable('too-old-kernel', 'ktls'); } + } elsif ($target =~ m/^BSD/) { + system("printf '#include \n#include ' | $cc -E - >/dev/null 2>&1"); + if ($? != 0) { + disable('too-old-freebsd', 'ktls'); + } } else { - disable('not-linux', 'ktls'); + disable('not-linux-or-freebsd', 'ktls'); + } +} + +unless ($disabled{winstore}) { + unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) { + disable('not-windows', 'winstore'); } } @@ -1635,6 +1852,55 @@ $target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_l # ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON +###################################################################### +# Build up information for skipping certain directories depending on disabled +# features, as well as setting up macros for disabled features. + +# This is a tentative database of directories to skip. Some entries may not +# correspond to anything real, but that's ok, they will simply be ignored. +# The actual processing of these entries is done in the build.info lookup +# loop further down. +# +# The key is a Unix formatted path in the source tree, the value is an index +# into %disabled_info, so any existing path gets added to a corresponding +# 'skipped' entry in there with the list of skipped directories. +my %skipdir = (); +my %disabled_info = (); # For configdata.pm +foreach my $what (sort keys %disabled) { + # There are deprecated disablables that translate to themselves. + # They cause disabling cascades, but should otherwise not register. + next if $deprecated_disablables{$what}; + # The generated $disabled{"deprecated-x.y"} entries are special + # and treated properly elsewhere + next if $what =~ m|^deprecated-|; + + $config{options} .= " no-$what"; + + if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared', + 'module', 'pic', 'dynamic-engine', 'makedepend', + 'sse2', 'legacy' )) { + (my $WHAT = uc $what) =~ s|-|_|g; + my $skipdir = $what; + + # fix-up crypto/directory name(s) + $skipdir = "ripemd" if $what eq "rmd160"; + $skipdir = "whrlpool" if $what eq "whirlpool"; + + my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; + push @{$config{openssl_feature_defines}}, $macro; + + $skipdir{engines} = $what if $what eq 'engine'; + $skipdir{"crypto/$skipdir"} = $what + unless $what eq 'async' || $what eq 'err' || $what eq 'dso'; + } +} + +if ($disabled{"dynamic-engine"}) { + push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; +} else { + push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE"; +} + # If we use the unified build, collect information from build.info files my %unified_info = (); @@ -1646,11 +1912,12 @@ if ($builder eq "unified") { my $base = shift; my $dir = shift; my $relativeto = shift || "."; + my $no_mkpath = shift // 0; $dir = catdir($base,$dir) unless isabsolute($dir); # Make sure the directories we're building in exists - mkpath($dir); + mkpath($dir) unless $no_mkpath; my $res = abs2rel(absolutedir($dir), rel2abs($relativeto)); #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n"; @@ -1661,6 +1928,7 @@ if ($builder eq "unified") { my $base = shift; my $file = shift; my $relativeto = shift || "."; + my $no_mkpath = shift // 0; $file = catfile($base,$file) unless isabsolute($file); @@ -1668,7 +1936,7 @@ if ($builder eq "unified") { my $f = basename($file); # Make sure the directories we're building in exists - mkpath($d); + mkpath($d) unless $no_mkpath; my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto)); #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n"; @@ -1678,8 +1946,8 @@ if ($builder eq "unified") { # Store the name of the template file we will build the build file from # in %config. This may be useful for the build file itself. my @build_file_template_names = - ( $builder_platform."-".$target{build_file}.".tmpl", - $target{build_file}.".tmpl" ); + ( $builder_platform."-".$config{build_file}.".tmpl", + $config{build_file}.".tmpl" ); my @build_file_templates = (); # First, look in the user provided directory, if given @@ -1698,7 +1966,7 @@ if ($builder eq "unified") { } # Then, look in our standard directory push @build_file_templates, - ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) } + ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir, 1) } @build_file_template_names ); my $build_file_template; @@ -1713,15 +1981,24 @@ if ($builder eq "unified") { } $config{build_file_templates} = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"), - $blddir), - $build_file_template, - cleanfile($srcdir, catfile("Configurations", "common.tmpl"), - $blddir) ]; + $blddir, 1), + $build_file_template ]; my @build_dirs = ( [ ] ); # current directory $config{build_infos} = [ ]; + # We want to detect configdata.pm in the source tree, so we + # don't use it if the build tree is different. + my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir, 1); + + # Any source file that we recognise is placed in this hash table, with + # the list of its intended destinations as value. When everything has + # been collected, there's a routine that checks that these source files + # exist, or if they are generated, that the generator exists. + my %check_exist = (); + my %check_generate = (); + my %ordinals = (); while (@build_dirs) { my @curd = @{shift @build_dirs}; @@ -1750,29 +2027,65 @@ if ($builder eq "unified") { my %defines = (); my %depends = (); my %generate = (); + my %imagedocs = (); + my %htmldocs = (); + my %mandocs = (); # Support for $variablename in build.info files. # Embedded perl code is the ultimate master, still. If its output # contains a dollar sign, it had better be escaped, or it will be # taken for a variable name prefix. my %variables = (); - my $variable_re = qr/\$(?P[[:alpha:]][[:alnum:]_]*)/; + # Variable name syntax + my $variable_name_re = qr/(?P[[:alpha:]][[:alnum:]_]*)/; + # Value modifier syntaxes + my $variable_subst_re = qr/\/(?P(?:\\\/|.)*?)\/(?P.*?)/; + # Variable reference + my $variable_simple_re = qr/(?(?:\\\/|.)*?)\}/; + # Tie it all together + my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/; + my $expand_variables = sub { my $value = ''; my $value_rest = shift; if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) { print STDERR - "DEBUG[\$expand_variables] Parsed '$value_rest' into:\n" + "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n" } - while ($value_rest =~ /(?{$_}}, @values; + if (defined $attrref) { + $handle_attributes->($attr_str, \$$attrref->{$_}, + @values); + } + } + } else { + push @$valueref, @values; + $handle_attributes->($attr_str, $attrref, @values) + if defined $attrref; + } + }; + if ($buildinfo_debug) { + print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n"; + } push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f); my $template = Text::Template->new(TYPE => 'FILE', @@ -1840,7 +2180,7 @@ if ($builder eq "unified") { my $index_re = qr/\[\s*(?P(?:\\.|.)*?)\s*\]/; my $cond_re = qr/\[\s*(?P(?:\\.|.)*?)\s*\]/; my $attribs_re = qr/(?:\{\s*(?P(?:\\.|.)*?)\s*\})?/; - my $value_re = qr/\s*(?P.*?)\s*/; + my $value_re = qr/(?P.*?)/; collect_information( collect_from_array([ @text ], qr/\\$/ => sub { my $l1 = shift; my $l2 = shift; @@ -1867,13 +2207,13 @@ if ($builder eq "unified") { qr/^\s* ENDIF \s*$/x => sub { die "ENDIF out of scope" if ! @skip; pop @skip; }, - qr/^\s* ${variable_re} \s* = ${value_re} $/x + qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x => sub { if (!@skip || $skip[$#skip] > 0) { $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE}); } }, - qr/^\s* SUBDIRS \s* = ${value_re} $/x + qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x => sub { if (!@skip || $skip[$#skip] > 0) { foreach (tokenize($expand_variables->($+{VALUE}))) { @@ -1881,82 +2221,71 @@ if ($builder eq "unified") { } } }, - qr/^\s* PROGRAMS ${attribs_re} \s* = ${value_re} $/x - => sub { - if (!@skip || $skip[$#skip] > 0) { - my @p = tokenize($expand_variables->($+{VALUE})); - push @programs, @p; - $handle_attributes->($+{ATTRIBS}, - \$attributes{programs}, - @p); - } - }, - qr/^\s* LIBS ${attribs_re} \s* = ${value_re} $/x - => sub { - if (!@skip || $skip[$#skip] > 0) { - my @l = tokenize($expand_variables->($+{VALUE})); - push @libraries, @l; - $handle_attributes->($+{ATTRIBS}, - \$attributes{libraries}, - @l); - } - }, - qr/^\s* MODULES ${attribs_re} \s* = ${value_re} $/x - => sub { - if (!@skip || $skip[$#skip] > 0) { - my @m = tokenize($expand_variables->($+{VALUE})); - push @modules, @m; - $handle_attributes->($+{ATTRIBS}, - \$attributes{modules}, - @m); - } - }, - qr/^\s* SCRIPTS ${attribs_re} \s* = ${value_re} $/x - => sub { - if (!@skip || $skip[$#skip] > 0) { - my @s = tokenize($expand_variables->($+{VALUE})); - push @scripts, @s; - $handle_attributes->($+{ATTRIBS}, - \$attributes{scripts}, - @s); - } - }, - - qr/^\s* ORDINALS ${index_re} = ${value_re} $/x - => sub { push @{$ordinals{$expand_variables->($+{INDEX})}}, - tokenize($expand_variables->($+{VALUE})) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s* SOURCE ${index_re} = ${value_re} $/x - => sub { push @{$sources{$expand_variables->($+{INDEX})}}, - tokenize($expand_variables->($+{VALUE})) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s* SHARED_SOURCE ${index_re} = ${value_re} $/x - => sub { push @{$shared_sources{$expand_variables->($+{INDEX})}}, - tokenize($expand_variables->($+{VALUE})) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s* INCLUDE ${index_re} = ${value_re} $/x - => sub { push @{$includes{$expand_variables->($+{INDEX})}}, - tokenize($expand_variables->($+{VALUE})) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s* DEFINE ${index_re} = ${value_re} $/x - => sub { push @{$defines{$expand_variables->($+{INDEX})}}, - tokenize($expand_variables->($+{VALUE})) - if !@skip || $skip[$#skip] > 0 }, - qr/^\s* DEPEND ${index_re} ${attribs_re} = ${value_re} $/x - => sub { - if (!@skip || $skip[$#skip] > 0) { - my $i = $expand_variables->($+{INDEX}); - my @d = tokenize($expand_variables->($+{VALUE})); - push @{$depends{$i}}, @d; - $handle_attributes->($+{ATTRIBS}, - \$attributes{depends}->{$i}, - @d); - } - }, - qr/^\s* GENERATE ${index_re} = ${value_re} $/x - => sub { push @{$generate{$expand_variables->($+{INDEX})}}, - $+{VALUE} - if !@skip || $skip[$#skip] > 0 }, + qr/^\s* PROGRAMS ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@programs, undef, + \$attributes{programs}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* LIBS ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@libraries, undef, + \$attributes{libraries}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* MODULES ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@modules, undef, + \$attributes{modules}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\@scripts, undef, + \$attributes{scripts}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%sources, $expand_variables->($+{INDEX}), + \$attributes{sources}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}), + \$attributes{sources}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%includes, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%defines, $expand_variables->($+{INDEX}), + undef, undef, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%depends, $expand_variables->($+{INDEX}), + \$attributes{depends}, $+{ATTRIBS}, + tokenize($expand_variables->($+{VALUE}))) + if !@skip || $skip[$#skip] > 0; }, + qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x + => sub { $push_to->(\%generate, $expand_variables->($+{INDEX}), + \$attributes{generate}, $+{ATTRIBS}, + $expand_variables->($+{VALUE})) + if !@skip || $skip[$#skip] > 0; }, qr/^\s* (?:\#.*)? $/x => sub { }, "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }, "BEFORE" => sub { @@ -2014,16 +2343,17 @@ EOF my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); foreach (@{$sources{$dest}}) { - my $s = cleanfile($sourced, $_, $blddir); + my $s = cleanfile($sourced, $_, $blddir, 1); - # If it isn't in the source tree, we assume it's generated - # in the build tree - if ($s eq $src_configdata || ! -f $s || $generate{$_}) { + # If it's generated or we simply don't find it in the source + # tree, we assume it's in the build tree. + if ($s eq $src_configdata || $generate{$_} || ! -f $s) { $s = cleanfile($buildd, $_, $blddir); } + my $o = $_; # We recognise C++, C and asm files if ($s =~ /\.(cc|cpp|c|s|S)$/) { - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.[csS]$/.o/; # C and assembler $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ $o = cleanfile($buildd, $o, $blddir); @@ -2031,14 +2361,26 @@ EOF $unified_info{sources}->{$o}->{$s} = -1; } elsif ($s =~ /\.rc$/) { # We also recognise resource files - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.rc$/.res/; # Resource configuration - my $o = cleanfile($buildd, $o, $blddir); + $o = cleanfile($buildd, $o, $blddir); $unified_info{sources}->{$ddest}->{$o} = -1; $unified_info{sources}->{$o}->{$s} = -1; } else { + push @{$check_exist{$s}}, $ddest; $unified_info{sources}->{$ddest}->{$s} = 1; } + # Fix up associated attributes + if ($o ne $_) { + $unified_info{attributes}->{sources}->{$ddest}->{$o} = + $unified_info{attributes}->{sources}->{$o}->{$s} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } else { + $unified_info{attributes}->{sources}->{$ddest}->{$s} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } } } @@ -2046,17 +2388,18 @@ EOF my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); foreach (@{$shared_sources{$dest}}) { - my $s = cleanfile($sourced, $_, $blddir); + my $s = cleanfile($sourced, $_, $blddir, 1); - # If it isn't in the source tree, we assume it's generated - # in the build tree - if ($s eq $src_configdata || ! -f $s || $generate{$_}) { + # If it's generated or we simply don't find it in the source + # tree, we assume it's in the build tree. + if ($s eq $src_configdata || $generate{$_} || ! -f $s) { $s = cleanfile($buildd, $_, $blddir); } + my $o = $_; if ($s =~ /\.(cc|cpp|c|s|S)$/) { # We recognise C++, C and asm files - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.[csS]$/.o/; # C and assembler $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ $o = cleanfile($buildd, $o, $blddir); @@ -2064,19 +2407,31 @@ EOF $unified_info{sources}->{$o}->{$s} = -1; } elsif ($s =~ /\.rc$/) { # We also recognise resource files - my $o = $_; + push @{$check_exist{$s}}, $ddest; $o =~ s/\.rc$/.res/; # Resource configuration - my $o = cleanfile($buildd, $o, $blddir); + $o = cleanfile($buildd, $o, $blddir); $unified_info{shared_sources}->{$ddest}->{$o} = -1; $unified_info{sources}->{$o}->{$s} = -1; } elsif ($s =~ /\.ld$/) { # We also recognise linker scripts (or corresponding) # We know they are generated files - my $ld = cleanfile($buildd, $_, $blddir); - $unified_info{shared_sources}->{$ddest}->{$ld} = 1; + push @{$check_exist{$s}}, $ddest; + $o = cleanfile($buildd, $_, $blddir); + $unified_info{shared_sources}->{$ddest}->{$o} = 1; } else { die "unrecognised source file type for shared library: $s\n"; } + # Fix up associated attributes + if ($o ne $_) { + $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} = + $unified_info{attributes}->{sources}->{$o}->{$s} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } else { + $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} = + $attributes{sources}->{$dest}->{$_} + if defined $attributes{sources}->{$dest}->{$_}; + } } } @@ -2084,56 +2439,99 @@ EOF my $dest = $_; my $ddest = cleanfile($buildd, $_, $blddir); die "more than one generator for $dest: " - ,join(" ", @{$generate{$_}}),"\n" - if scalar @{$generate{$_}} > 1; + ,join(" ", @{$generate{$_}}),"\n" + if scalar @{$generate{$_}} > 1; my @generator = split /\s+/, $generate{$dest}->[0]; - $generator[0] = cleanfile($sourced, $generator[0], $blddir), + my $gen = $generator[0]; + $generator[0] = cleanfile($sourced, $gen, $blddir, 1); + + # If the generator is itself generated, it's in the build tree + if ($generate{$gen} || ! -f $generator[0]) { + $generator[0] = cleanfile($buildd, $gen, $blddir); + } + $check_generate{$ddest}->{$generator[0]}++; + $unified_info{generate}->{$ddest} = [ @generator ]; + # Fix up associated attributes + $unified_info{attributes}->{generate}->{$ddest} = + $attributes{generate}->{$dest}->{$gen} + if defined $attributes{generate}->{$dest}->{$gen}; } foreach (keys %depends) { my $dest = $_; - my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir); + my $ddest = $dest; + + if ($dest =~ /^\|(.*)\|$/) { + # Collect the raw target + $unified_info{targets}->{$1} = 1; + $ddest = $1; + } elsif ($dest eq '') { + $ddest = ''; + } else { + $ddest = cleanfile($sourced, $dest, $blddir, 1); - # If the destination doesn't exist in source, it can only be - # a generated file in the build tree. - if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) { - $ddest = cleanfile($buildd, $_, $blddir); + # If the destination doesn't exist in source, it can only be + # a generated file in the build tree. + if ($ddest eq $src_configdata || ! -f $ddest) { + $ddest = cleanfile($buildd, $dest, $blddir); + } } - foreach (@{$depends{$dest}}) { - my $d = cleanfile($sourced, $_, $blddir); + foreach my $f (@{$depends{$dest}}) { + # If the dependency destination is generated, dependencies + # may have an extra syntax to separate the intended inclusion + # directory from the module to be loaded: a | instead of a + # / as directory separator. + # Do note that this has to be handled in the build file + # template as well. + # $i = inclusion path in source directory + # $i2 = inclusion path in build directory + # $m = module path (within the inclusion path) + # $i = full module path in source directory + # $i2 = full module path in build directory + my $i; my $i2; my $m; my $d; my $d2; + if ($unified_info{generate}->{$ddest} + && $f =~ m/^(.*?)\|(.*)$/) { + $i = $1; + $m = $2; + # We must be very careful to modify $i last + $d = cleanfile($sourced, "$i/$m", $blddir, 1); + $d2 = cleanfile($buildd, "$i/$m", $blddir); + $i2 = cleandir($buildd, $i, $blddir); + $i = cleandir($sourced, $i, $blddir, 1); + } else { + $d = cleanfile($sourced, $f, $blddir, 1); + $d2 = cleanfile($buildd, $f, $blddir); + } # If we know it's generated, or assume it is because we can't # find it in the source tree, we set file we depend on to be - # in the build tree rather than the source tree, and assume - # and that there are lines to build it in a BEGINRAW..ENDRAW - # section or in the Makefile template. + # in the build tree rather than the source tree. if ($d eq $src_configdata - || ! -f $d - || (grep { $d eq $_ } - map { cleanfile($srcdir, $_, $blddir) } - grep { /\.h$/ } keys %{$unified_info{generate}})) { - $d = cleanfile($buildd, $_, $blddir); + || (grep { $d2 eq $_ } + keys %{$unified_info{generate}}) + || ! -f $d) { + $d = $d2; + $i = $i2; + } + if ($i) { + # Put together the computed inclusion dir with the + # original module name. Do note that we conserve the + # Unixly path syntax for the module path. + $d = "$i|$m"; } - # Take note if the file to depend on is being renamed - # Take extra care with files ending with .a, they should - # be treated without that extension, and the extension - # should be added back after treatment. - $d =~ /(\.a)?$/; - my $e = $1 // ""; - $d = $`.$e; $unified_info{depends}->{$ddest}->{$d} = 1; # Fix up associated attributes $unified_info{attributes}->{depends}->{$ddest}->{$d} = - $attributes{depends}->{$dest}->{$_} - if defined $attributes{depends}->{$dest}->{$_}; + $attributes{depends}->{$dest}->{$f} + if defined $attributes{depends}->{$dest}->{$f}; } } foreach (keys %includes) { my $dest = $_; - my $ddest = cleanfile($sourced, $_, $blddir); + my $ddest = cleanfile($sourced, $_, $blddir, 1); # If the destination doesn't exist in source, it can only be # a generated file in the build tree. @@ -2141,7 +2539,7 @@ EOF $ddest = cleanfile($buildd, $_, $blddir); } foreach (@{$includes{$dest}}) { - my $is = cleandir($sourced, $_, $blddir); + my $is = cleandir($sourced, $_, $blddir, 1); my $ib = cleandir($buildd, $_, $blddir); push @{$unified_info{includes}->{$ddest}->{source}}, $is unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}}; @@ -2154,15 +2552,12 @@ EOF my $ddest; if ($dest ne "") { - $ddest = cleanfile($sourced, $dest, $blddir); + $ddest = cleanfile($sourced, $dest, $blddir, 1); # If the destination doesn't exist in source, it can only # be a generated file in the build tree. if (! -f $ddest) { $ddest = cleanfile($buildd, $dest, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; - } } } foreach my $v (@{$defines{$dest}}) { @@ -2179,6 +2574,27 @@ EOF } } } + + foreach my $section (keys %imagedocs) { + foreach (@{$imagedocs{$section}}) { + my $imagedocs = cleanfile($buildd, $_, $blddir); + $unified_info{imagedocs}->{$section}->{$imagedocs} = 1; + } + } + + foreach my $section (keys %htmldocs) { + foreach (@{$htmldocs{$section}}) { + my $htmldocs = cleanfile($buildd, $_, $blddir); + $unified_info{htmldocs}->{$section}->{$htmldocs} = 1; + } + } + + foreach my $section (keys %mandocs) { + foreach (@{$mandocs{$section}}) { + my $mandocs = cleanfile($buildd, $_, $blddir); + $unified_info{mandocs}->{$section}->{$mandocs} = 1; + } + } } my $ordinals_text = join(', ', sort keys %ordinals); @@ -2189,6 +2605,60 @@ They are ignored and should be replaced with a combination of GENERATE, DEPEND and SHARED_SOURCE. EOF + # Check that each generated file is only generated once + my $ambiguous_generation = 0; + foreach (sort keys %check_generate) { + my @generators = sort keys %{$check_generate{$_}}; + my $generators_txt = join(', ', @generators); + if (scalar @generators > 1) { + warn "$_ is GENERATEd by more than one generator ($generators_txt)\n"; + $ambiguous_generation++; + } + if ($check_generate{$_}->{$generators[0]} > 1) { + warn "INFO: $_ has more than one GENERATE declaration (same generator)\n" + } + } + die "There are ambiguous source file generations\n" + if $ambiguous_generation > 0; + + # All given source files should exist, or if generated, their + # generator should exist. This loop ensures this is true. + my $missing = 0; + foreach my $orig (sort keys %check_exist) { + foreach my $dest (@{$check_exist{$orig}}) { + if ($orig ne $src_configdata) { + if ($orig =~ /\.a$/) { + # Static library names may be used as sources, so we + # need to detect those and give them special treatment. + unless (grep { $_ eq $orig } + keys %{$unified_info{libraries}}) { + warn "$orig is given as source for $dest, but no such library is built\n"; + $missing++; + } + } else { + # A source may be generated, and its generator may be + # generated as well. We therefore loop to dig out the + # first generator. + my $gen = $orig; + + while (my @next = keys %{$check_generate{$gen}}) { + $gen = $next[0]; + } + + if (! -f $gen) { + if ($gen ne $orig) { + $missing++; + warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n"; + } else { + $missing++; + warn "$orig is given as source for $dest, but is missing\n"; + } + } + } + } + } + } + die "There are files missing\n" if $missing > 0; # Go through the sources of all libraries and check that the same basename # doesn't appear more than once. Some static library archivers depend on @@ -2225,7 +2695,9 @@ EOF next if $dest eq ""; foreach my $d (keys %{$unified_info{depends}->{$dest}}) { next unless $d =~ /\.(h|pm)$/; - my $i = dirname($d); + # Take into account when a dependency uses the inclusion|module + # syntax + my $i = $d =~ m/\|/ ? $` : dirname($d); my $spot = $d eq "configdata.pm" || defined($unified_info{generate}->{$d}) ? 'build' : 'source'; @@ -2306,6 +2778,19 @@ EOF $unified_info{$dst}->{$prod}->{$newobj} = 1; foreach my $src (@{$prod_sources{$_}}) { $unified_info{sources}->{$newobj}->{$src} = 1; + # Adjust source attributes + my $attrs = $unified_info{attributes}->{sources}; + if (defined $attrs->{$prod} + && defined $attrs->{$prod}->{$_}) { + $attrs->{$prod}->{$newobj} = + $attrs->{$prod}->{$_}; + delete $attrs->{$prod}->{$_}; + } + foreach my $objsrc (keys %{$attrs->{$_} // {}}) { + $attrs->{$newobj}->{$objsrc} = + $attrs->{$_}->{$objsrc}; + delete $attrs->{$_}->{$objsrc}; + } } # Adjust dependencies foreach my $deps (keys %{$unified_info{depends}->{$_}}) { @@ -2335,11 +2820,12 @@ EOF ### Make unified_info a bit more efficient # One level structures - foreach (("programs", "libraries", "modules", "scripts")) { + foreach (("programs", "libraries", "modules", "scripts", "targets")) { $unified_info{$_} = [ sort keys %{$unified_info{$_}} ]; } # Two level structures - foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) { + foreach my $l1 (("sources", "shared_sources", "ldadd", "depends", + "imagedocs", "htmldocs", "mandocs")) { foreach my $l2 (sort keys %{$unified_info{$l1}}) { my @items = sort @@ -2385,8 +2871,14 @@ EOF my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ], "dso" => [ @{$unified_info{modules}} ], "bin" => [ @{$unified_info{programs}} ], - "script" => [ @{$unified_info{scripts}} ] ); - foreach my $type (keys %loopinfo) { + "script" => [ @{$unified_info{scripts}} ], + "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} } + keys %{$unified_info{imagedocs} // {}}), + (map { @{$unified_info{htmldocs}->{$_} // []} } + keys %{$unified_info{htmldocs} // {}}), + (map { @{$unified_info{mandocs}->{$_} // []} } + keys %{$unified_info{mandocs} // {}}) ] ); + foreach my $type (sort keys %loopinfo) { foreach my $product (@{$loopinfo{$type}}) { my %dirs = (); my $pd = dirname($product); @@ -2407,7 +2899,7 @@ EOF push @{$unified_info{dirinfo}->{$d}->{deps}}, $_ if $d ne $pd; } - foreach (keys %dirs) { + foreach (sort keys %dirs) { push @{$unified_info{dirinfo}->{$_}->{products}->{$type}}, $product; } @@ -2442,10 +2934,9 @@ my %template_vars = ( user_crossable => \@user_crossable, ); my $configdata_outname = 'configdata.pm'; -print "Creating $configdata_outname\n"; open CONFIGDATA, ">$configdata_outname.new" - or die "Trying to create $configdata_outname.new: $!"; -my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir); + or die "Trying to create $configdata_outname.new: $!"; +my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir, 1); my $configdata_tmpl = OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname); $configdata_tmpl->fill_in( @@ -2458,12 +2949,14 @@ $configdata_tmpl->fill_in( ] } ) or die $Text::Template::ERROR; close CONFIGDATA; + rename "$configdata_outname.new", $configdata_outname; if ($builder_platform eq 'unix') { my $mode = (0755 & ~umask); chmod $mode, 'configdata.pm' or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!); } +print "Created $configdata_outname\n"; print "Running $configdata_outname\n"; my $perlcmd = (quotify("maybeshell", $config{PERL}))[0]; @@ -2478,7 +2971,7 @@ print <<"EOF" if ($disabled{threads} eq "unavailable"); The library could not be configured for supporting multi-threaded applications as the compiler options required on this system are not known. -See file INSTALL for details if you need multi-threading. +See file INSTALL.md for details if you need multi-threading. EOF print <<"EOF" if ($no_shared_warn); @@ -2490,23 +2983,7 @@ or position independent code, please let us know (but please first make sure you have tried with a current version of OpenSSL). EOF -print <<"EOF"; - -********************************************************************** -*** *** -*** OpenSSL has been successfully configured *** -*** *** -*** If you encounter a problem while building, please open an *** -*** issue on GitHub *** -*** and include the output from the following command: *** -*** *** -*** perl configdata.pm --dump *** -*** *** -*** (If you are new to OpenSSL, you might want to consult the *** -*** 'Troubleshooting' section in the INSTALL file first) *** -*** *** -********************************************************************** -EOF +print $banner; exit(0); @@ -2519,12 +2996,12 @@ exit(0); # sub death_handler { die @_ if $^S; # To prevent the added message in eval blocks - my $build_file = $target{build_file} // "build file"; + my $build_file = $config{build_file} // "build file"; my @message = ( <<"_____", @_ ); Failure! $build_file wasn't produced. -Please read INSTALL and associated NOTES files. You may also have to look over -your available compiler tool chain or change your configuration. +Please read INSTALL.md and associated NOTES-* files. You may also have to +look over your available compiler tool chain or change your configuration. _____ @@ -2800,25 +3277,25 @@ sub resolve_config { } } - foreach (sort keys %all_keys) { - my $previous = $combined_inheritance{$_}; + foreach my $key (sort keys %all_keys) { + my $previous = $combined_inheritance{$key}; # Current target doesn't have a value for the current key? # Assign it the default combiner, the rest of this loop body # will handle it just like any other coderef. - if (!exists $table{$target}->{$_}) { - $table{$target}->{$_} = $default_combiner; + if (!exists $table{$target}->{$key}) { + $table{$target}->{$key} = $default_combiner; } - $table{$target}->{$_} = process_values($table{$target}->{$_}, - $combined_inheritance{$_}, - $target, $_); - unless(defined($table{$target}->{$_})) { - delete $table{$target}->{$_}; + $table{$target}->{$key} = process_values($table{$target}->{$key}, + $combined_inheritance{$key}, + $target, $key); + unless(defined($table{$target}->{$key})) { + delete $table{$target}->{$key}; } # if ($extra_checks && -# $previous && !($add_called || $previous ~~ $table{$target}->{$_})) { -# warn "$_ got replaced in $target\n"; +# $previous && !($add_called || $previous ~~ $table{$target}->{$key})) { +# warn "$key got replaced in $target\n"; # } } @@ -2857,7 +3334,6 @@ sub usage } print STDERR $i . " "; } - print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n"; exit(1); } @@ -2947,6 +3423,8 @@ sub print_table_entry "loutflag", "ex_libs", "bn_ops", + "enable", + "disable", "poly1035_asm_src", "thread_scheme", "perlasm_scheme", @@ -3044,6 +3522,27 @@ sub absolutedir { return realpath($dir); } +# Check if all paths are one and the same, using stat. They must both exist +# We need this for the cases when File::Spec doesn't detect case insensitivity +# (File::Spec::Unix assumes case sensitivity) +sub samedir { + die "samedir expects two arguments\n" unless scalar @_ == 2; + + my @stat0 = stat($_[0]); # First argument + my @stat1 = stat($_[1]); # Second argument + + die "Couldn't stat $_[0]" unless @stat0; + die "Couldn't stat $_[1]" unless @stat1; + + # Compare device number + return 0 unless ($stat0[0] == $stat1[0]); + # Compare "inode". The perl manual recommends comparing as + # string rather than as number. + return 0 unless ($stat0[1] eq $stat1[1]); + + return 1; # All the same +} + sub quotify { my %processors = ( perl => sub { my $x = shift;