VirtualBox

Ignore:
Timestamp:
Mar 3, 2022 7:17:34 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
150325
Message:

libs/openssl-3.0.1: started applying and adjusting our OpenSSL changes to 3.0.1. bugref:10128

Location:
trunk/src/libs/openssl-3.0.1
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/openssl-3.0.1

    • Property svn:mergeinfo
      •  

        old new  
        1212/vendor/openssl/1.1.1c:131722-131725
        1313/vendor/openssl/1.1.1k:145841-145843
         14/vendor/openssl/3.0.1:150323-150324
         15/vendor/openssl/current:147554-150322
  • trunk/src/libs/openssl-3.0.1/Configure

    r91772 r94082  
    33# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
    44#
    5 # Licensed under the OpenSSL license (the "License").  You may not use
     5# Licensed under the Apache License 2.0 (the "License").  You may not use
    66# this file except in compliance with the License.  You can obtain a copy
    77# in the file LICENSE in the source distribution or at
     
    1616use lib "$FindBin::Bin/util/perl";
    1717use File::Basename;
    18 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
     18use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs splitdir/;
    1919use File::Path qw/mkpath/;
     20use OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt";
    2021use OpenSSL::Glob;
    21 
    22 # see INSTALL for instructions.
     22use OpenSSL::Template;
     23use OpenSSL::config;
     24
     25# see INSTALL.md for instructions.
    2326
    2427my $orig_death_handler = $SIG{__DIE__};
     
    2629
    2730my $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";
     31
     32my $banner = <<"EOF";
     33
     34**********************************************************************
     35***                                                                ***
     36***   OpenSSL has been successfully configured                     ***
     37***                                                                ***
     38***   If you encounter a problem while building, please open an    ***
     39***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
     40***   and include the output from the following command:           ***
     41***                                                                ***
     42***       perl configdata.pm --dump                                ***
     43***                                                                ***
     44***   (If you are new to OpenSSL, you might want to consult the    ***
     45***   'Troubleshooting' section in the INSTALL.md file first)      ***
     46***                                                                ***
     47**********************************************************************
     48EOF
    2849
    2950# Options:
     
    4162#               This becomes the value of OPENSSLDIR in Makefile and in C.
    4263#               (Default: PREFIX/ssl)
     64# --banner=".." Output specified text instead of default completion banner
     65#
     66# -w            Don't wait after showing a Configure warning
    4367#
    4468# --cross-compile-prefix Add specified prefix to binutils components.
    4569#
    46 # --api         One of 0.9.8, 1.0.0 or 1.1.0.  Do not compile support for
    47 #               interfaces deprecated as of the specified OpenSSL version.
     70# --api         One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0
     71#               Define the public APIs as they were for that version
     72#               including patch releases.  If 'no-deprecated' is also
     73#               given, do not compile support for interfaces deprecated
     74#               up to and including the specified OpenSSL version.
    4875#
    4976# no-hw-xxx     do not compile support for specific crypto hardware.
     
    6491#               library and will be loaded in run-time by the OpenSSL library.
    6592# sctp          include SCTP support
     93# no-uplink     Don't build support for UPLINK interface.
    6694# enable-weak-ssl-ciphers
    6795#               Enable weak ciphers that are disabled by default.
     
    6997# no-sse2       disables IA-32 SSE2 code in assembly modules, the above
    7098#               mentioned '386' option implies this one
    71 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
     99# no-<cipher>   build without specified algorithm (dsa, idea, rc5, ...)
    72100# -<xxx> +<xxx> All options which are unknown to the 'Configure' script are
    73101# /<xxx>        passed through to the compiler. Unix-style options beginning
     
    111139# C++ compilers.
    112140
    113 # DEBUG_UNUSED enables __owur (warn unused result) checks.
    114141# -DPEDANTIC complements -pedantic and is meant to mask code that
    115142# is not strictly standard-compliant and/or implementation-specific,
     
    125152
    126153my @gcc_devteam_warn = qw(
    127     -DDEBUG_UNUSED
    128     -DPEDANTIC -pedantic -Wno-long-long
     154    -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG
    129155    -Wall
     156    -Wmissing-declarations
    130157    -Wextra
    131158    -Wno-unused-parameter
     
    165192);
    166193
    167 # This adds backtrace information to the memory leak info.  Is only used
    168 # when crypto-mdebug-backtrace is enabled.
    169 my $memleak_devteam_backtrace = "-rdynamic";
    170 
    171194my $strict_warnings = 0;
    172195
     
    183206# API compatibility name to version number mapping.
    184207#
    185 my $maxapi = "1.1.0";           # API for "no-deprecated" builds
    186208my $apitable = {
    187     "1.1.0" => "0x10100000L",
    188     "1.0.0" => "0x10000000L",
    189     "0.9.8" => "0x00908000L",
     209    # This table expresses when API additions or changes can occur.
     210    # The numbering used changes from 3.0 and on because we updated
     211    # (solidified) our version numbering scheme at that point.
     212
     213    # From 3.0 and on, we internalise the given version number in decimal
     214    # as MAJOR * 10000 + MINOR * 100 + 0
     215    "3.0.0" => 30000,
     216    "3.0"   => 30000,
     217
     218    # Note that before 3.0, we didn't have the same version number scheme.
     219    # Still, the numbering we use here covers what we need.
     220    "1.1.1" => 10101,
     221    "1.1.0" => 10100,
     222    "1.0.2" => 10002,
     223    "1.0.1" => 10001,
     224    "1.0.0" => 10000,
     225    "0.9.8" =>   908,
    190226};
     227
     228# For OpenSSL::config::get_platform
     229my %guess_opts = ();
     230
     231my $dryrun = 0;
    191232
    192233our %table = ();
     
    234275$config{sourcedir} = abs2rel($srcdir, $blddir);
    235276$config{builddir} = abs2rel($blddir, $blddir);
     277# echo -n 'holy hand grenade of antioch' | openssl sha256
     278$config{FIPSKEY} =
     279    'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
    236280
    237281# Collect reconfiguration information if needed
     
    261305$config{perlargv} = [ @argvcopy ];
    262306
     307# Historical: if known directories in crypto/ have been removed, it means
     308# that those sub-systems are disabled.
     309# (the other option would be to removed them from the SUBDIRS statement in
     310# crypto/build.info)
     311# We reverse the input list for cosmetic purely reasons, to compensate that
     312# 'unshift' adds at the front of the list (i.e. in reverse input order).
     313foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh',
     314                        'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2',
     315                        'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha',
     316                        'sm2', 'sm3', 'sm4') ) {
     317    unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_);
     318}
     319
    263320# Collect version numbers
    264 $config{version} = "unknown";
    265 $config{version_num} = "unknown";
    266 $config{shlib_version_number} = "unknown";
    267 $config{shlib_version_history} = "unknown";
     321my %version = ();
    268322
    269323collect_information(
    270     collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
    271     qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
    272     qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/      => sub { $config{version_num}=$1 },
    273     qr/SHLIB_VERSION_NUMBER *"([^"]+)"/      => sub { $config{shlib_version_number}=$1 },
    274     qr/SHLIB_VERSION_HISTORY *"([^"]*)"/     => sub { $config{shlib_version_history}=$1 }
     324    collect_from_file(catfile($srcdir,'VERSION.dat')),
     325    qr/\s*(\w+)\s*=\s*(.*?)\s*$/ =>
     326        sub {
     327            # Only define it if there is a value at all
     328            if ($2 ne '') {
     329                my $k = $1;
     330                my $v = $2;
     331                # Some values are quoted.  Trim the quotes
     332                $v = $1 if $v =~ /^"(.*)"$/;
     333                $version{uc $k} = $v;
     334            }
     335        },
     336    "OTHERWISE" =>
     337        sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" },
    275338    );
    276 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
    277 
    278 ($config{major}, $config{minor})
    279     = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
    280 ($config{shlib_major}, $config{shlib_minor})
    281     = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
    282 die "erroneous version information in opensslv.h: ",
    283     "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
    284     if ($config{major} eq "" || $config{minor} eq ""
    285         || $config{shlib_major} eq "" ||  $config{shlib_minor} eq "");
     339
     340$config{major} = $version{MAJOR} // 'unknown';
     341$config{minor} = $version{MINOR} // 'unknown';
     342$config{patch} = $version{PATCH} // 'unknown';
     343$config{prerelease} =
     344    defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : '';
     345$config{build_metadata} =
     346    defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : '';
     347$config{shlib_version} = $version{SHLIB_VERSION} // 'unknown';
     348$config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx';
     349
     350$config{version} = "$config{major}.$config{minor}.$config{patch}";
     351$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
     352
     353die "erroneous version information in VERSION.dat: ",
     354    "$config{version}, $config{shlib_version}\n"
     355    unless (defined $version{MAJOR}
     356            && defined $version{MINOR}
     357            && defined $version{PATCH}
     358            && defined $version{SHLIB_VERSION});
    286359
    287360# Collect target configurations
     
    318391my $default_ranlib;
    319392
    320 # Top level directories to build
    321 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
    322 # crypto/ subdirectories to build
    323 $config{sdirs} = [
    324     "objects",
    325     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3",
    326     "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes",
    327     "bn", "ec", "rsa", "dsa", "dh", "sm2", "dso", "engine",
    328     "buffer", "bio", "stack", "lhash", "rand", "err",
    329     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
    330     "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store"
    331     ];
    332 # test/ subdirectories to build
    333 $config{tdirs} = [ "ossl_shim" ];
    334 
    335393# Known TLS and DTLS protocols
    336394my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
     
    342400
    343401my @disablables = (
     402    "acvp-tests",
    344403    "afalgeng",
    345404    "aria",
     
    352411    "bf",
    353412    "blake2",
    354     "buildtest-c\\+\\+",
     413    "buildtest-c++",
     414    "bulk",
     415    "cached-fetch",
    355416    "camellia",
    356417    "capieng",
     
    358419    "chacha",
    359420    "cmac",
     421    "cmp",
    360422    "cms",
    361423    "comp",
    362424    "crypto-mdebug",
    363     "crypto-mdebug-backtrace",
    364425    "ct",
    365426    "deprecated",
     
    374435    "ec",
    375436    "ec2m",
     437    "ec_nistp_64_gcc_128",
    376438    "ecdh",
    377439    "ecdsa",
    378     "ec_nistp_64_gcc_128",
    379440    "egd",
    380441    "engine",
     
    382443    "external-tests",
    383444    "filenames",
     445    "fips",
     446    "fips-securitychecks",
     447    "fuzz-afl",
    384448    "fuzz-libfuzzer",
    385     "fuzz-afl",
    386449    "gost",
    387     "heartbeats",
    388     "hw(-.+)?",
    389450    "idea",
     451    "ktls",
     452    "legacy",
     453    "loadereng",
    390454    "makedepend",
    391455    "md2",
    392456    "md4",
    393457    "mdc2",
     458    "module",
    394459    "msan",
    395460    "multiblock",
    396461    "nextprotoneg",
    397     "pinshared",
    398462    "ocb",
    399463    "ocsp",
     464    "padlockeng",
    400465    "pic",
     466    "pinshared",
    401467    "poly1305",
    402468    "posix-io",
     
    410476    "scrypt",
    411477    "sctp",
     478    "secure-memory",
    412479    "seed",
    413480    "shared",
    414481    "siphash",
     482    "siv",
    415483    "sm2",
    416484    "sm3",
     
    427495    "threads",
    428496    "tls",
     497    "trace",
    429498    "ts",
    430499    "ubsan",
    431500    "ui-console",
    432501    "unit-test",
     502    "uplink",
     503    "weak-ssl-ciphers",
    433504    "whirlpool",
    434     "weak-ssl-ciphers",
    435505    "zlib",
    436506    "zlib-dynamic",
     
    442512        }
    443513
     514# Internal disablables, for aliasing purposes.  They serve no special
     515# purpose here, but allow scripts to get to know them through configdata.pm,
     516# where these are merged with @disablables.
     517# The actual aliasing mechanism is done via %disable_cascades
     518my @disablables_int = qw(
     519    crmf
     520    );
     521
    444522my %deprecated_disablables = (
    445523    "ssl2" => undef,
    446524    "buf-freelists" => undef,
     525    "crypto-mdebug-backtrace" => undef,
     526    "hw" => "hw",               # causes cascade, but no macro
     527    "hw-padlock" => "padlockeng",
    447528    "ripemd" => "rmd160",
    448529    "ui" => "ui-console",
     530    "heartbeats" => undef,
    449531    );
    450532
     
    452534
    453535our %disabled = ( # "what"         => "comment"
     536                  "fips"                => "default",
    454537                  "asan"                => "default",
    455538                  "buildtest-c++"       => "default",
     
    460543                  "egd"                 => "default",
    461544                  "external-tests"      => "default",
     545                  "fuzz-afl"            => "default",
    462546                  "fuzz-libfuzzer"      => "default",
    463                   "fuzz-afl"            => "default",
    464                   "heartbeats"          => "default",
     547                  "ktls"                => "default",
    465548                  "md2"                 => "default",
    466549                  "msan"                => "default",
    467550                  "rc5"                 => "default",
    468551                  "sctp"                => "default",
    469                   "ssl-trace"           => "default",
    470552                  "ssl3"                => "default",
    471553                  "ssl3-method"         => "default",
     554                  "trace"               => "default",
    472555                  "ubsan"               => "default",
    473556                  "unit-test"           => "default",
     
    480563my @disable_cascades = (
    481564    # "what"            => [ "cascade", ... ]
     565    "bulk"              => [ "shared", "dso",
     566                             "aria", "async", "autoload-config",
     567                             "blake2", "bf", "camellia", "cast", "chacha",
     568                             "cmac", "cms", "cmp", "comp", "ct",
     569                             "des", "dgram", "dh", "dsa",
     570                             "ec", "engine",
     571                             "filenames",
     572                             "idea", "ktls",
     573                             "md4", "multiblock", "nextprotoneg",
     574                             "ocsp", "ocb", "poly1305", "psk",
     575                             "rc2", "rc4", "rmd160",
     576                             "seed", "siphash", "siv",
     577                             "sm3", "sm4", "srp",
     578                             "srtp", "ssl3-method", "ssl-trace",
     579                             "ts", "ui-console", "whirlpool",
     580                             "fips-securitychecks" ],
    482581    sub { $config{processor} eq "386" }
    483582                        => [ "sse2" ],
     
    486585    "zlib"              => [ "zlib-dynamic" ],
    487586    "des"               => [ "mdc2" ],
    488     "ec"                => [ "ecdsa", "ecdh" ],
    489 
     587    "ec"                => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ],
    490588    "dgram"             => [ "dtls", "sctp" ],
    491589    "sock"              => [ "dgram" ],
     
    500598    "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
    501599
    502     # Without position independent code, there can be no shared libraries or DSOs
    503     "pic"               => [ "shared" ],
    504     "shared"            => [ "dynamic-engine" ],
    505     "dso"               => [ "dynamic-engine" ],
    506     "engine"            => [ "afalgeng", "devcryptoeng" ],
     600    # If no modules, then no dynamic engines either
     601    "module"            => [ "dynamic-engine" ],
     602
     603    # Without shared libraries, dynamic engines aren't possible.
     604    # This is due to them having to link with libcrypto and register features
     605    # using the ENGINE functionality, and since that relies on global tables,
     606    # those *have* to be exacty the same as the ones accessed from the app,
     607    # which cannot be guaranteed if shared libraries aren't present.
     608    # (note that even with shared libraries, both the app and dynamic engines
     609    # must be linked with the same library)
     610    "shared"            => [ "dynamic-engine", "uplink" ],
     611    "dso"               => [ "dynamic-engine", "module" ],
     612    # Other modules don't necessarily have to link with libcrypto, so shared
     613    # libraries do not have to be a condition to produce those.
     614
     615    # Without position independent code, there can be no shared libraries
     616    # or modules.
     617    "pic"               => [ "shared", "module" ],
     618
     619    "module"            => [ "fips", "dso" ],
     620
     621    "engine"            => [ "dynamic-engine", grep(/eng$/, @disablables) ],
     622    "dynamic-engine"    => [ "loadereng" ],
     623    "hw"                => [ "padlockeng" ],
    507624
    508625    # no-autoalginit is only useful when building non-shared
    509     "autoalginit"       => [ "shared", "apps" ],
     626    "autoalginit"       => [ "shared", "apps", "fips" ],
    510627
    511628    "stdio"             => [ "apps", "capieng", "egd" ],
     
    513630    "tests"             => [ "external-tests" ],
    514631    "comp"              => [ "zlib" ],
    515     "ec"                => [ "tls1_3", "sm2" ],
    516632    "sm3"               => [ "sm2" ],
    517633    sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
    518634
    519635    sub { !$disabled{"msan"} } => [ "asm" ],
     636
     637    "cmac"              => [ "siv" ],
     638    "legacy"            => [ "md2" ],
     639
     640    "cmp"               => [ "crmf" ],
     641
     642    "fips"              => [ "fips-securitychecks", "acvp-tests" ],
     643
     644    "deprecated-3.0"    => [ "engine", "srp" ]
    520645    );
    521646
     
    541666# To remove something from %disabled, use "enable-foo".
    542667# For symmetry, "disable-foo" is a synonym for "no-foo".
    543 
    544 &usage if ($#ARGV < 0);
    545668
    546669# For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with
     
    628751
    629752$config{openssl_api_defines}=[];
    630 $config{openssl_algorithm_defines}=[];
    631 $config{openssl_thread_defines}=[];
    632753$config{openssl_sys_defines}=[];
    633 $config{openssl_other_defines}=[];
     754$config{openssl_feature_defines}=[];
    634755$config{options}="";
    635756$config{build_type} = "release";
     
    680801        s /^zlib$/enable-zlib/;
    681802        s /^zlib-dynamic$/enable-zlib-dynamic/;
     803        s /^fips$/enable-fips/;
    682804
    683805        if (/^(no|disable|enable)-(.+)$/)
    684806                {
    685807                my $word = $2;
    686                 if (!exists $deprecated_disablables{$word}
    687                         && !grep { $word =~ /^${_}$/ } @disablables)
     808                if ($word !~ m|hw(?:-.+)| # special treatment for hw regexp opt
     809                        && !exists $deprecated_disablables{$word}
     810                        && !grep { $word eq $_ } @disablables)
    688811                        {
    689812                        $unsupported_options{$_} = 1;
     
    733856                elsif (exists $deprecated_disablables{$1})
    734857                        {
    735                         if ($deprecated_disablables{$1} ne "")
     858                        $deprecated_options{$_} = 1;
     859                        if (defined $deprecated_disablables{$1})
    736860                                {
    737                                 $deprecated_options{$_} = 1;
    738                                 if (defined $deprecated_disablables{$1})
    739                                         {
    740                                         $disabled{$deprecated_disablables{$1}} = "option";
    741                                         }
     861                                $disabled{$deprecated_disablables{$1}} = "option";
    742862                                }
     863                        }
     864                elsif ($1 =~ m|hw(?:-.+)|) # deprecate hw options in regexp form
     865                        {
     866                        $deprecated_options{$_} = 1;
    743867                        }
    744868                else
     
    768892                # No longer an automatic choice
    769893                $auto_threads = 0 if ($1 eq "threads");
     894                }
     895        elsif (/^-d$/)          # From older 'config'
     896                {
     897                $config{build_type} = "debug";
     898                }
     899        elsif (/^-v$/)          # From older 'config'
     900                {
     901                $guess_opts{verbose} = 1;
     902                }
     903        elsif (/^-w$/)
     904                {
     905                $guess_opts{nowait} = 1;
     906                }
     907        elsif (/^-t$/)          # From older 'config'
     908                {
     909                $dryrun = 1;
    770910                }
    771911        elsif (/^--strict-warnings$/)
     
    786926        elsif (/^386$/)
    787927                { $config{processor}=386; }
    788         elsif (/^fips$/)
    789                 {
    790                 die "FIPS mode not supported\n";
    791                 }
    792928        elsif (/^rsaref$/)
    793929                {
     
    796932                # broken
    797933                }
    798         elsif (/^nofipscanistercheck$/)
    799                 {
    800                 die "FIPS mode not supported\n";
    801                 }
    802934        elsif (m|^[-+/]|)
    803935                {
     
    810942                elsif (/^--api=(.*)$/)
    811943                        {
    812                         $config{api}=$1;
     944                        my $api = $1;
     945                        die "Unknown API compatibility level $api"
     946                                unless defined $apitable->{$api};
     947                        $config{api}=$apitable->{$api};
    813948                        }
    814949                elsif (/^--libdir=(.*)$/)
     
    844979                            push @seed_sources, $x;
    845980                            }
     981                        }
     982                elsif (/^--fips-key=(.*)$/)
     983                        {
     984                        $user{FIPSKEY}=lc($1);
     985                        die "Non-hex character in FIPS key\n"
     986                           if $user{FIPSKEY} =~ /[^a-f0-9]/;
     987                        die "FIPS key must have even number of characters\n"
     988                           if length $1 & 1;
     989                        die "FIPS key too long (64 bytes max)\n"
     990                           if length $1 > 64;
     991                        }
     992                elsif (/^--banner=(.*)$/)
     993                        {
     994                        $banner = $1 . "\n";
    846995                        }
    847996                elsif (/^--cross-compile-prefix=(.*)$/)
     
    9261075                }
    9271076        }
    928 
    929 if (defined($config{api}) && !exists $apitable->{$config{api}}) {
    930         die "***** Unsupported api compatibility level: $config{api}\n",
    931 }
    9321077
    9331078if (keys %deprecated_options)
     
    10031148}
    10041149
     1150# If no target was given, try guessing.
     1151unless ($target) {
     1152    my %system_config = OpenSSL::config::get_platform(%guess_opts, %user);
     1153
     1154    # The $system_config{disable} is used to populate %disabled with
     1155    # entries that aren't already there.
     1156    foreach ( @{$system_config{disable} // []} ) {
     1157        $disabled{$_} = 'system' unless defined $disabled{$_};
     1158    }
     1159    delete $system_config{disable};
     1160
     1161    # Override config entries with stuff from the guesser.
     1162    # It's assumed that this really is nothing new.
     1163    %config = ( %config, %system_config );
     1164    $target = $system_config{target};
     1165}
     1166
    10051167sub disable {
    10061168    my $disable_type = shift;
     
    10531215}
    10541216
    1055 print "Configuring OpenSSL version $config{version} ($config{version_num}) ";
    1056 print "for $target\n";
     1217print "Configuring OpenSSL version $config{full_version} ";
     1218print "for target $target\n";
    10571219
    10581220if (scalar(@seed_sources) == 0) {
     
    10751237
    10761238Please read the 'Note on random number generation' section in the
    1077 INSTALL instructions and the RAND_DRBG(7) manual page for more details.
     1239INSTALL.md instructions and the RAND_DRBG(7) manual page for more
     1240details.
    10781241============================== WARNING ===============================
    10791242
    10801243_____
    10811244}
    1082 push @{$config{openssl_other_defines}},
     1245push @{$config{openssl_feature_defines}},
    10831246     map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
    10841247        @seed_sources;
     
    11001263}
    11011264
    1102 &usage if !$table{$target} || $table{$target}->{template};
     1265if ($target) {
     1266    # It's possible that we have different config targets for specific
     1267    # toolchains, so we try to detect them, and go for the plain config
     1268    # target if not.
     1269    my $found;
     1270    foreach ( ( "$target-$user{CC}", "$target", undef ) ) {
     1271        $found=$_ if $table{$_} && !$table{$_}->{template};
     1272        last if $found;
     1273    }
     1274    $target = $found;
     1275} else {
     1276    # If we don't have a config target now, we try the C compiler as we
     1277    # fallback
     1278    my $cc = $user{CC} // 'cc';
     1279    $target = $cc if $table{$cc} && !$table{$cc}->{template};
     1280}
     1281
     1282&usage unless $target;
     1283
     1284exit 0 if $dryrun;              # From older 'config'
    11031285
    11041286$config{target} = $target;
     
    11361318    }
    11371319}
     1320
     1321# If uplink_arch isn't defined, disable uplink
     1322$disabled{uplink} = 'no uplink_arch' unless (defined $target{uplink_arch});
     1323# If asm_arch isn't defined, disable asm
     1324$disabled{asm} = 'no asm_arch' unless (defined $target{asm_arch});
     1325
    11381326disable();                      # Run a cascade now
    11391327
    11401328$target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX};
    11411329$target{cxxflags}//=$target{cflags} if $target{CXX};
    1142 $target{exe_extension}="";
    1143 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
    1144                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
     1330$target{exe_extension}=".exe" if ($config{target} eq "DJGPP");
    11451331$target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
    1146 
    1147 ($target{shared_extension_simple}=$target{shared_extension})
    1148     =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||
    1149     unless defined($target{shared_extension_simple});
    1150 $target{dso_extension}//=$target{shared_extension_simple};
    1151 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
    1152     if ($config{target} =~ /^(?:Cygwin|mingw)/);
    11531332
    11541333# Fill %config with values from %user, and in case those are undefined or
     
    12021381# because it's now all been merged into the corresponding $config entry
    12031382
    1204 if (grep { $_ eq '-static' } @{$config{LDFLAGS}}) {
     1383if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) {
    12051384    disable('static', 'pic', 'threads');
    12061385}
     
    12781457}
    12791458
     1459# Find out if clang's sanitizers have been enabled with -fsanitize
     1460# flags and ensure that the corresponding %disabled elements area
     1461# removed to reflect that the sanitizers are indeed enabled.
     1462my %detected_sanitizers = ();
     1463foreach (grep /^-fsanitize=/, @{$config{CFLAGS} || []}) {
     1464    (my $checks = $_) =~ s/^-fsanitize=//;
     1465    foreach (split /,/, $checks) {
     1466        my $d = { address       => 'asan',
     1467                  undefined     => 'ubsan',
     1468                  memory        => 'msan' } -> {$_};
     1469        next unless defined $d;
     1470
     1471        $detected_sanitizers{$d} = 1;
     1472        if (defined $disabled{$d}) {
     1473            die "***** Conflict between disabling $d and enabling $_ sanitizer"
     1474                if $disabled{$d} ne "default";
     1475            delete $disabled{$d};
     1476        }
     1477    }
     1478}
     1479
    12801480# If threads still aren't disabled, add a C macro to ensure the source
    12811481# code knows about it.  Any other flag is taken care of by the configs.
    12821482unless($disabled{threads}) {
    1283     push @{$config{openssl_thread_defines}}, "OPENSSL_THREADS";
    1284 }
    1285 
    1286 # With "deprecated" disable all deprecated features.
    1287 if (defined($disabled{"deprecated"})) {
    1288         $config{api} = $maxapi;
     1483    push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
    12891484}
    12901485
    12911486my $no_shared_warn=0;
    1292 if ($target{shared_target} eq "")
     1487if (($target{shared_target} // '') eq "")
    12931488        {
    12941489        $no_shared_warn = 1
     
    13031498}
    13041499
    1305 unless ($disabled{asan}) {
     1500unless ($disabled{asan} || defined $detected_sanitizers{asan}) {
    13061501    push @{$config{cflags}}, "-fsanitize=address";
    13071502}
    13081503
    1309 unless ($disabled{ubsan}) {
     1504unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) {
    13101505    # -DPEDANTIC or -fnosanitize=alignment may also be required on some
    13111506    # platforms.
     
    13131508}
    13141509
    1315 unless ($disabled{msan}) {
     1510unless ($disabled{msan} || defined $detected_sanitizers{msan}) {
    13161511  push @{$config{cflags}}, "-fsanitize=memory";
    13171512}
     
    13481543        }
    13491544
    1350 unless ($disabled{asm}) {
    1351     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
    1352     push @{$config{lib_defines}}, "OPENSSL_CPUID_OBJ" if ($target{cpuid_asm_src} ne "mem_clr.c");
    1353 
    1354     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
    1355 
    1356     # bn-586 is the only one implementing bn_*_part_words
    1357     push @{$config{lib_defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
    1358     push @{$config{lib_defines}}, "OPENSSL_IA32_SSE2" if (!$disabled{sse2} && $target{bn_asm_src} =~ /86/);
    1359 
    1360     push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
    1361     push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
    1362     push @{$config{lib_defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
    1363     push @{$config{lib_defines}}, "BN_DIV3W" if ($target{bn_asm_src} =~ /-div3w/);
    1364 
    1365     if ($target{sha1_asm_src}) {
    1366         push @{$config{lib_defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
    1367         push @{$config{lib_defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
    1368         push @{$config{lib_defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
    1369     }
    1370     if ($target{keccak1600_asm_src} ne $table{DEFAULTS}->{keccak1600_asm_src}) {
    1371         push @{$config{lib_defines}}, "KECCAK1600_ASM";
    1372     }
    1373     if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
    1374         push @{$config{lib_defines}}, "RC4_ASM";
    1375     }
    1376     if ($target{md5_asm_src}) {
    1377         push @{$config{lib_defines}}, "MD5_ASM";
    1378     }
    1379     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
    1380     if ($target{rmd160_asm_src}) {
    1381         push @{$config{lib_defines}}, "RMD160_ASM";
    1382     }
    1383     if ($target{aes_asm_src}) {
    1384         push @{$config{lib_defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
    1385         push @{$config{lib_defines}}, "AESNI_ASM" if ($target{aes_asm_src} =~ m/\baesni-/);;
    1386         # aes-ctr.fake is not a real file, only indication that assembler
    1387         # module implements AES_ctr32_encrypt...
    1388         push @{$config{lib_defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
    1389         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
    1390         push @{$config{lib_defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
    1391         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($disabled{sse2});
    1392         push @{$config{lib_defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
    1393         push @{$config{lib_defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
    1394     }
    1395     if ($target{wp_asm_src} =~ /mmx/) {
    1396         if ($config{processor} eq "386") {
    1397             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
    1398         } elsif (!$disabled{"whirlpool"}) {
    1399             push @{$config{lib_defines}}, "WHIRLPOOL_ASM";
    1400         }
    1401     }
    1402     if ($target{modes_asm_src} =~ /ghash-/) {
    1403         push @{$config{lib_defines}}, "GHASH_ASM";
    1404     }
    1405     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
    1406         push @{$config{lib_defines}}, "ECP_NISTZ256_ASM";
    1407     }
    1408     if ($target{ec_asm_src} =~ /x25519/) {
    1409         push @{$config{lib_defines}}, "X25519_ASM";
    1410     }
    1411     if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
    1412         push @{$config{dso_defines}}, "PADLOCK_ASM";
    1413     }
    1414     if ($target{poly1305_asm_src} ne "") {
    1415         push @{$config{lib_defines}}, "POLY1305_ASM";
    1416     }
    1417 }
    1418 
    14191545my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC});
    14201546my %predefined_CXX = $config{CXX}
     
    14221548    : ();
    14231549
     1550unless ($disabled{asm}) {
     1551    # big endian systems can use ELFv2 ABI
     1552    if ($target eq "linux-ppc64") {
     1553        $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2);
     1554    }
     1555}
     1556
    14241557# Check for makedepend capabilities.
    14251558if (!$disabled{makedepend}) {
    1426     if ($config{target} =~ /^(VC|vms)-/) {
    1427         # For VC- and vms- targets, there's nothing more to do here.  The
    1428         # functionality is hard coded in the corresponding build files for
    1429         # cl (Windows) and CC/DECC (VMS).
     1559    # If the attribute makedep_scheme is defined, then we assume that the
     1560    # config target and its associated build file are programmed to deal
     1561    # with it.
     1562    # If makedep_scheme is undefined, we go looking for GCC compatible
     1563    # dependency making, and if that's not available, we try to fall back
     1564    # on 'makedepend'.
     1565    if ($target{makedep_scheme}) {
     1566        $config{makedep_scheme} = $target{makedep_scheme};
     1567        # If the makedepcmd attribute is defined, copy it.  If not, the
     1568        # build files will have to fend for themselves.
     1569        $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd};
    14301570    } elsif (($predefined_C{__GNUC__} // -1) >= 3
    14311571             && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) {
     
    14331573        # versions support dependency generation, but Xcode did not
    14341574        # handle $cc -M before clang support (but claims __GNUC__ = 3)
    1435         $config{makedepprog} = "\$(CROSS_COMPILE)$config{CC}";
     1575        $config{makedep_scheme} = 'gcc';
    14361576    } else {
    1437         # In all other cases, we look for 'makedepend', and disable the
    1438         # capability if not found.
    1439         $config{makedepprog} = which('makedepend');
    1440         disable('unavailable', 'makedepend') unless $config{makedepprog};
    1441     }
     1577        # In all other cases, we look for 'makedepend', and set the
     1578        # makedep_scheme value if we found it.
     1579        $config{makedepcmd} = which('makedepend');
     1580        $config{makedep_scheme} = 'makedepend' if $config{makedepcmd};
     1581    }
     1582
     1583    # If no depend scheme is set, we disable makedepend
     1584    disable('unavailable', 'makedepend') unless $config{makedep_scheme};
    14421585}
    14431586
     
    14671610
    14681611$config{bn_ll}                  =0;
    1469 $config{export_var_as_fn}       =0;
    14701612my $def_int="unsigned int";
    14711613$config{rc4_int}                =$def_int;
     
    14751617foreach (sort split(/\s+/,$target{bn_ops})) {
    14761618    $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
    1477     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
    14781619    $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
    14791620    $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
     
    14881629    if $count > 1;
    14891630
     1631$config{api} = $config{major} * 10000 + $config{minor} * 100
     1632    unless $config{api};
     1633foreach (keys %$apitable) {
     1634    $disabled{"deprecated-$_"} = "deprecation"
     1635        if $disabled{deprecated} && $config{api} >= $apitable->{$_};
     1636}
     1637
     1638disable();                      # Run a cascade now
    14901639
    14911640# Hack cflags for better warnings (dev option) #######################
     
    14981647                          @{$config{cxxflags}} ] if $config{CXX};
    14991648
    1500 if (defined($config{api})) {
    1501     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
    1502     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
    1503     push @{$config{defines}}, $apiflag;
    1504 }
     1649$config{openssl_api_defines} = [
     1650    "OPENSSL_CONFIGURED_API=".$config{api},
     1651];
    15051652
    15061653my @strict_warnings_collection=();
     
    15301677                              : ( $_ ) }
    15311678                    @{$config{CFLAGS}} ];
    1532 
    1533 unless ($disabled{"crypto-mdebug-backtrace"})
    1534         {
    1535         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
    1536                 {
    1537                 push @{$config{cflags}}, $wopt
    1538                         unless grep { $_ eq $wopt } @{$config{cflags}};
    1539                 }
    1540         if ($target =~ /^BSD-/)
    1541                 {
    1542                 push @{$config{ex_libs}}, "-lexecinfo";
    1543                 }
    1544         }
    15451679
    15461680unless ($disabled{afalgeng}) {
     
    15801714    }
    15811715}
     1716
     1717unless ($disabled{ktls}) {
     1718    $config{ktls}="";
     1719    if ($target =~ m/^linux/) {
     1720        my $usr = "/usr/$config{cross_compile_prefix}";
     1721        chop($usr);
     1722        if ($config{cross_compile_prefix} eq "") {
     1723            $usr = "/usr";
     1724        }
     1725        my $minver = (4 << 16) + (13 << 8) + 0;
     1726        my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`);
     1727
     1728        if ($verstr[2] < $minver) {
     1729            disable('too-old-kernel', 'ktls');
     1730        }
     1731    } elsif ($target =~ m/^BSD/) {
     1732        my $cc = $config{CROSS_COMPILE}.$config{CC};
     1733        system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1");
     1734        if ($? != 0) {
     1735            disable('too-old-freebsd', 'ktls');
     1736        }
     1737    } else {
     1738        disable('not-linux-or-freebsd', 'ktls');
     1739    }
     1740}
     1741
     1742push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
    15821743
    15831744# Get the extra flags used when building shared libraries and modules.  We
     
    16241785# ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON
    16251786
     1787######################################################################
     1788# Build up information for skipping certain directories depending on disabled
     1789# features, as well as setting up macros for disabled features.
     1790
     1791# This is a tentative database of directories to skip.  Some entries may not
     1792# correspond to anything real, but that's ok, they will simply be ignored.
     1793# The actual processing of these entries is done in the build.info lookup
     1794# loop further down.
     1795#
     1796# The key is a Unix formatted path in the source tree, the value is an index
     1797# into %disabled_info, so any existing path gets added to a corresponding
     1798# 'skipped' entry in there with the list of skipped directories.
     1799my %skipdir = ();
    16261800my %disabled_info = ();         # For configdata.pm
    16271801foreach my $what (sort keys %disabled) {
     1802    # There are deprecated disablables that translate to themselves.
     1803    # They cause disabling cascades, but should otherwise not regiter.
     1804    next if $deprecated_disablables{$what};
     1805    # The generated $disabled{"deprecated-x.y"} entries are special
     1806    # and treated properly elsewhere
     1807    next if $what =~ m|^deprecated-|;
     1808
    16281809    $config{options} .= " no-$what";
    16291810
    1630     if (!grep { $what eq $_ } ( 'buildtest-c++', 'threads', 'shared', 'pic',
    1631                                 'dynamic-engine', 'makedepend',
    1632                                 'zlib-dynamic', 'zlib', 'sse2' )) {
     1811    if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
     1812                                'module', 'pic', 'dynamic-engine', 'makedepend',
     1813                                'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) {
    16331814        (my $WHAT = uc $what) =~ s|-|_|g;
    1634 
    1635         # Fix up C macro end names
    1636         $WHAT = "RMD160" if $what eq "ripemd";
     1815        my $skipdir = $what;
    16371816
    16381817        # fix-up crypto/directory name(s)
    1639         $what = "ripemd" if $what eq "rmd160";
    1640         $what = "whrlpool" if $what eq "whirlpool";
     1818        $skipdir = "ripemd" if $what eq "rmd160";
     1819        $skipdir = "whrlpool" if $what eq "whirlpool";
    16411820
    16421821        my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT";
    1643 
    1644         if ((grep { $what eq $_ } @{$config{sdirs}})
    1645                 && $what ne 'async' && $what ne 'err' && $what ne 'dso') {
    1646             @{$config{sdirs}} = grep { $what ne $_} @{$config{sdirs}};
    1647             $disabled_info{$what}->{skipped} = [ catdir('crypto', $what) ];
    1648 
    1649             if ($what ne 'engine') {
    1650                 push @{$config{openssl_algorithm_defines}}, $macro;
    1651             } else {
    1652                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
    1653                 push @{$disabled_info{engine}->{skipped}}, catdir('engines');
    1654                 push @{$config{openssl_other_defines}}, $macro;
    1655             }
    1656         } else {
    1657             push @{$config{openssl_other_defines}}, $macro;
    1658         }
    1659 
     1822        push @{$config{openssl_feature_defines}}, $macro;
     1823
     1824        $skipdir{engines} = $what if $what eq 'engine';
     1825        $skipdir{"crypto/$skipdir"} = $what
     1826            unless $what eq 'async' || $what eq 'err' || $what eq 'dso';
    16601827    }
    16611828}
    16621829
    16631830if ($disabled{"dynamic-engine"}) {
    1664     push @{$config{openssl_other_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
     1831    push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
    16651832} else {
    1666     push @{$config{openssl_other_defines}}, "OPENSSL_NO_STATIC_ENGINE";
     1833    push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE";
    16671834}
    16681835
     
    16721839my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
    16731840if ($builder eq "unified") {
    1674     use with_fallback qw(Text::Template);
     1841    use Text::Template 1.46;
    16751842
    16761843    sub cleandir {
     
    17461913      = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"),
    17471914                    $blddir),
    1748           $build_file_template,
    1749           cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
    1750                     $blddir) ];
    1751 
    1752     my @build_infos = ( [ ".", "build.info" ] );
    1753     foreach (@{$config{dirs}}) {
    1754         push @build_infos, [ $_, "build.info" ]
    1755             if (-f catfile($srcdir, $_, "build.info"));
    1756     }
    1757     foreach (@{$config{sdirs}}) {
    1758         push @build_infos, [ catdir("crypto", $_), "build.info" ]
    1759             if (-f catfile($srcdir, "crypto", $_, "build.info"));
    1760     }
    1761     foreach (@{$config{engdirs}}) {
    1762         push @build_infos, [ catdir("engines", $_), "build.info" ]
    1763             if (-f catfile($srcdir, "engines", $_, "build.info"));
    1764     }
    1765     foreach (@{$config{tdirs}}) {
    1766         push @build_infos, [ catdir("test", $_), "build.info" ]
    1767             if (-f catfile($srcdir, "test", $_, "build.info"));
    1768     }
     1915           $build_file_template ];
     1916
     1917    my @build_dirs = ( [ ] );   # current directory
    17691918
    17701919    $config{build_infos} = [ ];
    17711920
     1921    # We want to detect configdata.pm in the source tree, so we
     1922    # don't use it if the build tree is different.
     1923    my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir);
     1924
     1925    # Any source file that we recognise is placed in this hash table, with
     1926    # the list of its intended destinations as value.  When everything has
     1927    # been collected, there's a routine that checks that these source files
     1928    # exist, or if they are generated, that the generator exists.
     1929    my %check_exist = ();
     1930    my %check_generate = ();
     1931
    17721932    my %ordinals = ();
    1773     foreach (@build_infos) {
    1774         my $sourced = catdir($srcdir, $_->[0]);
    1775         my $buildd = catdir($blddir, $_->[0]);
     1933    while (@build_dirs) {
     1934        my @curd = @{shift @build_dirs};
     1935        my $sourced = catdir($srcdir, @curd);
     1936        my $buildd = catdir($blddir, @curd);
     1937
     1938        my $unixdir = join('/', @curd);
     1939        if (exists $skipdir{$unixdir}) {
     1940            my $what = $skipdir{$unixdir};
     1941            push @{$disabled_info{$what}->{skipped}}, catdir(@curd);
     1942            next;
     1943        }
    17761944
    17771945        mkpath($buildd);
    17781946
    1779         my $f = $_->[1];
     1947        my $f = 'build.info';
    17801948        # The basic things we're trying to build
    17811949        my @programs = ();
    1782         my @programs_install = ();
    17831950        my @libraries = ();
    1784         my @libraries_install = ();
    1785         my @engines = ();
    1786         my @engines_install = ();
     1951        my @modules = ();
    17871952        my @scripts = ();
    1788         my @scripts_install = ();
    1789         my @extra = ();
    1790         my @overrides = ();
    1791         my @intermediates = ();
    1792         my @rawlines = ();
    17931953
    17941954        my %sources = ();
    17951955        my %shared_sources = ();
    17961956        my %includes = ();
     1957        my %defines = ();
    17971958        my %depends = ();
    1798         my %renames = ();
    1799         my %sharednames = ();
    18001959        my %generate = ();
    1801 
    1802         # We want to detect configdata.pm in the source tree, so we
    1803         # don't use it if the build tree is different.
    1804         my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir);
    1805 
     1960        my %imagedocs = ();
     1961        my %htmldocs = ();
     1962        my %mandocs = ();
     1963
     1964        # Support for $variablename in build.info files.
     1965        # Embedded perl code is the ultimate master, still.  If its output
     1966        # contains a dollar sign, it had better be escaped, or it will be
     1967        # taken for a variable name prefix.
     1968        my %variables = ();
     1969        # Variable name syntax
     1970        my $variable_name_re = qr/(?P<VARIABLE>[[:alpha:]][[:alnum:]_]*)/;
     1971        # Value modifier syntaxes
     1972        my $variable_subst_re = qr/\/(?P<RE>(?:\\\/|.)*?)\/(?P<SUBST>.*?)/;
     1973        # Variable reference
     1974        my $variable_simple_re = qr/(?<!\\)\$${variable_name_re}/;
     1975        my $variable_w_mod_re =
     1976            qr/(?<!\\)\$\{${variable_name_re}(?P<MOD>(?:\\\/|.)*?)\}/;
     1977        # Tie it all together
     1978        my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/;
     1979
     1980        my $expand_variables = sub {
     1981            my $value = '';
     1982            my $value_rest = shift;
     1983
     1984            if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
     1985                print STDERR
     1986                    "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n"
     1987            }
     1988
     1989            while ($value_rest =~ /${variable_re}/) {
     1990                # We must save important regexp values, because the next
     1991                # regexp clears them
     1992                my $mod = $+{MOD};
     1993                my $variable_value = $variables{$+{VARIABLE}};
     1994
     1995                $value_rest = $';
     1996                $value .= $`;
     1997
     1998                # Process modifier expressions, if present
     1999                if (defined $mod) {
     2000                    if ($mod =~ /^${variable_subst_re}$/) {
     2001                        my $re = $+{RE};
     2002                        my $subst = $+{SUBST};
     2003
     2004                        $variable_value =~ s/\Q$re\E/$subst/g;
     2005
     2006                        if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
     2007                            print STDERR
     2008                                "DEBUG[\$expand_variables] ... and substituted ",
     2009                                "'$re' with '$subst'\n";
     2010                        }
     2011                    }
     2012                }
     2013
     2014                $value .= $variable_value;
     2015            }
     2016            if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
     2017                print STDERR
     2018                    "DEBUG[\$expand_variables] ... into: '$value$value_rest'\n";
     2019            }
     2020            return $value . $value_rest;
     2021        };
     2022
     2023        # Support for attributes in build.info files
     2024        my %attributes = ();
     2025        my $handle_attributes = sub {
     2026            my $attr_str = shift;
     2027            my $ref = shift;
     2028            my @goals = @_;
     2029
     2030            return unless defined $attr_str;
     2031
     2032            my @a = tokenize($attr_str, qr|\s*,\s*|);
     2033            foreach my $a (@a) {
     2034                my $ac = 1;
     2035                my $ak = $a;
     2036                my $av = 1;
     2037                if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) {
     2038                    $ac = ! $1;
     2039                    $ak = $2;
     2040                    $av = $3;
     2041                }
     2042                foreach my $g (@goals) {
     2043                    if ($ac) {
     2044                        $$ref->{$g}->{$ak} = $av;
     2045                    } else {
     2046                        delete $$ref->{$g}->{$ak};
     2047                    }
     2048                }
     2049            }
     2050        };
     2051
     2052        # Support for pushing values on multiple indexes of a given hash
     2053        # array.
     2054        my $push_to = sub {
     2055            my $valueref = shift;
     2056            my $index_str = shift; # May be undef or empty
     2057            my $attrref = shift;   # May be undef
     2058            my $attr_str = shift;
     2059            my @values = @_;
     2060
     2061            if (defined $index_str) {
     2062                my @indexes = ( '' );
     2063                if ($index_str !~ m|^\s*$|) {
     2064                    @indexes = tokenize($index_str);
     2065                }
     2066                foreach (@indexes) {
     2067                    push @{$valueref->{$_}}, @values;
     2068                    if (defined $attrref) {
     2069                        $handle_attributes->($attr_str, \$$attrref->{$_},
     2070                                             @values);
     2071                    }
     2072                }
     2073            } else {
     2074                push @$valueref, @values;
     2075                $handle_attributes->($attr_str, $attrref, @values)
     2076                    if defined $attrref;
     2077            }
     2078        };
     2079
     2080        if ($buildinfo_debug) {
     2081            print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n";
     2082        }
    18062083        push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
    18072084        my $template =
     
    18292106        # 2 positive ELSE (following ELSIF should fail)
    18302107        my @skip = ();
     2108
     2109        # A few useful generic regexps
     2110        my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/;
     2111        my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/;
     2112        my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/;
     2113        my $value_re = qr/(?P<VALUE>.*?)/;
    18312114        collect_information(
    18322115            collect_from_array([ @text ],
     
    18342117                                                $l1 =~ s/\\$//; $l1.$l2 }),
    18352118            # Info we're looking for
    1836             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
     2119            qr/^\s* IF ${cond_re} \s*$/x
    18372120            => sub {
    18382121                if (! @skip || $skip[$#skip] > 0) {
    1839                     push @skip, !! $1;
     2122                    push @skip, !! $expand_variables->($+{COND});
    18402123                } else {
    18412124                    push @skip, -1;
    18422125                }
    18432126            },
    1844             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
     2127            qr/^\s* ELSIF ${cond_re} \s*$/x
    18452128            => sub { die "ELSIF out of scope" if ! @skip;
    18462129                     die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
    18472130                     $skip[$#skip] = -1 if $skip[$#skip] != 0;
    1848                      $skip[$#skip] = !! $1
     2131                     $skip[$#skip] = !! $expand_variables->($+{COND})
    18492132                         if $skip[$#skip] == 0; },
    1850             qr/^\s*ELSE\s*$/
     2133            qr/^\s* ELSE \s*$/x
    18512134            => sub { die "ELSE out of scope" if ! @skip;
    18522135                     $skip[$#skip] = -2 if $skip[$#skip] != 0;
    18532136                     $skip[$#skip] = 2 if $skip[$#skip] == 0; },
    1854             qr/^\s*ENDIF\s*$/
     2137            qr/^\s* ENDIF \s*$/x
    18552138            => sub { die "ENDIF out of scope" if ! @skip;
    18562139                     pop @skip; },
    1857             qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
     2140            qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x
    18582141            => sub {
    18592142                if (!@skip || $skip[$#skip] > 0) {
    1860                     my $install = $1;
    1861                     my @x = tokenize($2);
    1862                     push @programs, @x;
    1863                     push @programs_install, @x unless $install;
     2143                    $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE});
    18642144                }
    18652145            },
    1866             qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
     2146            qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x
    18672147            => sub {
    18682148                if (!@skip || $skip[$#skip] > 0) {
    1869                     my $install = $1;
    1870                     my @x = tokenize($2);
    1871                     push @libraries, @x;
    1872                     push @libraries_install, @x unless $install;
     2149                    foreach (tokenize($expand_variables->($+{VALUE}))) {
     2150                        push @build_dirs, [ @curd, splitdir($_, 1) ];
     2151                    }
    18732152                }
    18742153            },
    1875             qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
    1876             => sub {
    1877                 if (!@skip || $skip[$#skip] > 0) {
    1878                     my $install = $1;
    1879                     my @x = tokenize($2);
    1880                     push @engines, @x;
    1881                     push @engines_install, @x unless $install;
    1882                 }
    1883             },
    1884             qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
    1885             => sub {
    1886                 if (!@skip || $skip[$#skip] > 0) {
    1887                     my $install = $1;
    1888                     my @x = tokenize($2);
    1889                     push @scripts, @x;
    1890                     push @scripts_install, @x unless $install;
    1891                 }
    1892             },
    1893             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
    1894             => sub { push @extra, tokenize($1)
    1895                          if !@skip || $skip[$#skip] > 0 },
    1896             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
    1897             => sub { push @overrides, tokenize($1)
    1898                          if !@skip || $skip[$#skip] > 0 },
    1899 
    1900             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
    1901             => sub { push @{$ordinals{$1}}, tokenize($2)
    1902                          if !@skip || $skip[$#skip] > 0 },
    1903             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
    1904             => sub { push @{$sources{$1}}, tokenize($2)
    1905                          if !@skip || $skip[$#skip] > 0 },
    1906             qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
    1907             => sub { push @{$shared_sources{$1}}, tokenize($2)
    1908                          if !@skip || $skip[$#skip] > 0 },
    1909             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
    1910             => sub { push @{$includes{$1}}, tokenize($2)
    1911                          if !@skip || $skip[$#skip] > 0 },
    1912             qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
    1913             => sub { push @{$depends{$1}}, tokenize($2)
    1914                          if !@skip || $skip[$#skip] > 0 },
    1915             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
    1916             => sub { push @{$generate{$1}}, $2
    1917                          if !@skip || $skip[$#skip] > 0 },
    1918             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
    1919             => sub { push @{$renames{$1}}, tokenize($2)
    1920                          if !@skip || $skip[$#skip] > 0 },
    1921             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
    1922             => sub { push @{$sharednames{$1}}, tokenize($2)
    1923                          if !@skip || $skip[$#skip] > 0 },
    1924             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
    1925             => sub {
    1926                 my $lineiterator = shift;
    1927                 my $target_kind = $1;
    1928                 while (defined $lineiterator->()) {
    1929                     s|\R$||;
    1930                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
    1931                         die "ENDRAW doesn't match BEGINRAW"
    1932                             if $1 ne $target_kind;
    1933                         last;
    1934                     }
    1935                     next if @skip && $skip[$#skip] <= 0;
    1936                     push @rawlines,  $_
    1937                         if ($target_kind eq $target{build_file}
    1938                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
    1939                 }
    1940             },
    1941             qr/^\s*(?:#.*)?$/ => sub { },
     2154            qr/^\s* PROGRAMS ${attribs_re} \s* =  \s* ${value_re} \s* $/x
     2155            => sub { $push_to->(\@programs, undef,
     2156                                \$attributes{programs}, $+{ATTRIBS},
     2157                                tokenize($expand_variables->($+{VALUE})))
     2158                         if !@skip || $skip[$#skip] > 0; },
     2159            qr/^\s* LIBS ${attribs_re} \s* =  \s* ${value_re} \s* $/x
     2160            => sub { $push_to->(\@libraries, undef,
     2161                                \$attributes{libraries}, $+{ATTRIBS},
     2162                                tokenize($expand_variables->($+{VALUE})))
     2163                         if !@skip || $skip[$#skip] > 0; },
     2164            qr/^\s* MODULES ${attribs_re} \s* =  \s* ${value_re} \s* $/x
     2165            => sub { $push_to->(\@modules, undef,
     2166                                \$attributes{modules}, $+{ATTRIBS},
     2167                                tokenize($expand_variables->($+{VALUE})))
     2168                         if !@skip || $skip[$#skip] > 0; },
     2169            qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x
     2170            => sub { $push_to->(\@scripts, undef,
     2171                                \$attributes{scripts}, $+{ATTRIBS},
     2172                                tokenize($expand_variables->($+{VALUE})))
     2173                         if !@skip || $skip[$#skip] > 0; },
     2174            qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
     2175            => sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}),
     2176                                undef, undef,
     2177                                tokenize($expand_variables->($+{VALUE})))
     2178                         if !@skip || $skip[$#skip] > 0; },
     2179            qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
     2180            => sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}),
     2181                                undef, undef,
     2182                                tokenize($expand_variables->($+{VALUE})))
     2183                         if !@skip || $skip[$#skip] > 0; },
     2184            qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
     2185            => sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}),
     2186                                undef, undef,
     2187                                tokenize($expand_variables->($+{VALUE})))
     2188                         if !@skip || $skip[$#skip] > 0; },
     2189            qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
     2190            => sub { $push_to->(\%sources, $expand_variables->($+{INDEX}),
     2191                                \$attributes{sources}, $+{ATTRIBS},
     2192                                tokenize($expand_variables->($+{VALUE})))
     2193                         if !@skip || $skip[$#skip] > 0; },
     2194            qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
     2195            => sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}),
     2196                                \$attributes{sources}, $+{ATTRIBS},
     2197                                tokenize($expand_variables->($+{VALUE})))
     2198                         if !@skip || $skip[$#skip] > 0; },
     2199            qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x
     2200            => sub { $push_to->(\%includes, $expand_variables->($+{INDEX}),
     2201                                undef, undef,
     2202                                tokenize($expand_variables->($+{VALUE})))
     2203                         if !@skip || $skip[$#skip] > 0; },
     2204            qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x
     2205            => sub { $push_to->(\%defines, $expand_variables->($+{INDEX}),
     2206                                undef, undef,
     2207                                tokenize($expand_variables->($+{VALUE})))
     2208                         if !@skip || $skip[$#skip] > 0; },
     2209            qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
     2210            => sub { $push_to->(\%depends, $expand_variables->($+{INDEX}),
     2211                                \$attributes{depends}, $+{ATTRIBS},
     2212                                tokenize($expand_variables->($+{VALUE})))
     2213                         if !@skip || $skip[$#skip] > 0; },
     2214            qr/^\s* GENERATE ${index_re} \s* = \s* ${value_re} \s* $/x
     2215            => sub { $push_to->(\%generate, $expand_variables->($+{INDEX}),
     2216                                undef, undef, $expand_variables->($+{VALUE}))
     2217                         if !@skip || $skip[$#skip] > 0; },
     2218            qr/^\s* (?:\#.*)? $/x => sub { },
    19422219            "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
    19432220            "BEFORE" => sub {
     
    19552232        die "runaway IF?" if (@skip);
    19562233
    1957         foreach (keys %renames) {
    1958             die "$_ renamed to more than one thing: "
    1959                 ,join(" ", @{$renames{$_}}),"\n"
    1960                 if scalar @{$renames{$_}} > 1;
    1961             my $dest = cleanfile($buildd, $_, $blddir);
    1962             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
    1963             die "$dest renamed to more than one thing: "
    1964                 ,$unified_info{rename}->{$dest}, $to
    1965                 unless !defined($unified_info{rename}->{$dest})
    1966                 or $unified_info{rename}->{$dest} eq $to;
    1967             $unified_info{rename}->{$dest} = $to;
    1968         }
    1969 
    1970         foreach (@programs) {
    1971             my $program = cleanfile($buildd, $_, $blddir);
    1972             if ($unified_info{rename}->{$program}) {
    1973                 $program = $unified_info{rename}->{$program};
    1974             }
    1975             $unified_info{programs}->{$program} = 1;
    1976         }
    1977 
    1978         foreach (@programs_install) {
    1979             my $program = cleanfile($buildd, $_, $blddir);
    1980             if ($unified_info{rename}->{$program}) {
    1981                 $program = $unified_info{rename}->{$program};
    1982             }
    1983             $unified_info{install}->{programs}->{$program} = 1;
    1984         }
    1985 
    1986         foreach (@libraries) {
    1987             my $library = cleanfile($buildd, $_, $blddir);
    1988             if ($unified_info{rename}->{$library}) {
    1989                 $library = $unified_info{rename}->{$library};
    1990             }
    1991             $unified_info{libraries}->{$library} = 1;
    1992         }
    1993 
    1994         foreach (@libraries_install) {
    1995             my $library = cleanfile($buildd, $_, $blddir);
    1996             if ($unified_info{rename}->{$library}) {
    1997                 $library = $unified_info{rename}->{$library};
    1998             }
    1999             $unified_info{install}->{libraries}->{$library} = 1;
    2000         }
    2001 
    2002         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
     2234        if (grep { defined $attributes{modules}->{$_}->{engine} } keys %attributes
     2235                and !$config{dynamic_engines}) {
     2236            die <<"EOF"
    20032237ENGINES can only be used if configured with 'dynamic-engine'.
    20042238This is usually a fault in a build.info file.
    20052239EOF
    2006         foreach (@engines) {
    2007             my $library = cleanfile($buildd, $_, $blddir);
    2008             if ($unified_info{rename}->{$library}) {
    2009                 $library = $unified_info{rename}->{$library};
    2010             }
    2011             $unified_info{engines}->{$library} = 1;
    2012         }
    2013 
    2014         foreach (@engines_install) {
    2015             my $library = cleanfile($buildd, $_, $blddir);
    2016             if ($unified_info{rename}->{$library}) {
    2017                 $library = $unified_info{rename}->{$library};
    2018             }
    2019             $unified_info{install}->{engines}->{$library} = 1;
    2020         }
    2021 
    2022         foreach (@scripts) {
    2023             my $script = cleanfile($buildd, $_, $blddir);
    2024             if ($unified_info{rename}->{$script}) {
    2025                 $script = $unified_info{rename}->{$script};
    2026             }
    2027             $unified_info{scripts}->{$script} = 1;
    2028         }
    2029 
    2030         foreach (@scripts_install) {
    2031             my $script = cleanfile($buildd, $_, $blddir);
    2032             if ($unified_info{rename}->{$script}) {
    2033                 $script = $unified_info{rename}->{$script};
    2034             }
    2035             $unified_info{install}->{scripts}->{$script} = 1;
    2036         }
    2037 
    2038         foreach (@extra) {
    2039             my $extra = cleanfile($buildd, $_, $blddir);
    2040             $unified_info{extra}->{$extra} = 1;
    2041         }
    2042 
    2043         foreach (@overrides) {
    2044             my $override = cleanfile($buildd, $_, $blddir);
    2045             $unified_info{overrides}->{$override} = 1;
    2046         }
    2047 
    2048         push @{$unified_info{rawlines}}, @rawlines;
    2049 
    2050         unless ($disabled{shared}) {
    2051             # Check sharednames.
    2052             foreach (keys %sharednames) {
    2053                 my $dest = cleanfile($buildd, $_, $blddir);
    2054                 if ($unified_info{rename}->{$dest}) {
    2055                     $dest = $unified_info{rename}->{$dest};
    2056                 }
    2057                 die "shared_name for $dest with multiple values: "
    2058                     ,join(" ", @{$sharednames{$_}}),"\n"
    2059                     if scalar @{$sharednames{$_}} > 1;
    2060                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
    2061                 die "shared_name found for a library $dest that isn't defined\n"
    2062                     unless $unified_info{libraries}->{$dest};
    2063                 die "shared_name for $dest with multiple values: "
    2064                     ,$unified_info{sharednames}->{$dest}, ", ", $to
    2065                     unless !defined($unified_info{sharednames}->{$dest})
    2066                     or $unified_info{sharednames}->{$dest} eq $to;
    2067                 $unified_info{sharednames}->{$dest} = $to;
    2068             }
    2069 
    2070             # Additionally, we set up sharednames for libraries that don't
    2071             # have any, as themselves.  Only for libraries that aren't
    2072             # explicitly static.
    2073             foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) {
    2074                 if (!defined $unified_info{sharednames}->{$_}) {
    2075                     $unified_info{sharednames}->{$_} = $_
    2076                 }
    2077             }
    2078 
    2079             # Check that we haven't defined any library as both shared and
    2080             # explicitly static.  That is forbidden.
    2081             my @doubles = ();
    2082             foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
    2083                 (my $l = $_) =~ s/\.a$//;
    2084                 push @doubles, $l if defined $unified_info{sharednames}->{$l};
    2085             }
    2086             die "these libraries are both explicitly static and shared:\n  ",
    2087                 join(" ", @doubles), "\n"
    2088                 if @doubles;
    2089         }
     2240        }
     2241
     2242        {
     2243            my %infos = ( programs  => [ @programs  ],
     2244                          libraries => [ @libraries ],
     2245                          modules   => [ @modules   ],
     2246                          scripts   => [ @scripts   ] );
     2247            foreach my $k (keys %infos) {
     2248                foreach (@{$infos{$k}}) {
     2249                    my $item = cleanfile($buildd, $_, $blddir);
     2250                    $unified_info{$k}->{$item} = 1;
     2251
     2252                    # Fix up associated attributes
     2253                    $unified_info{attributes}->{$k}->{$item} =
     2254                        $attributes{$k}->{$_}
     2255                        if defined $attributes{$k}->{$_};
     2256                }
     2257            }
     2258        }
     2259
     2260        # Check that we haven't defined any library as both shared and
     2261        # explicitly static.  That is forbidden.
     2262        my @doubles = ();
     2263        foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
     2264            (my $l = $_) =~ s/\.a$//;
     2265            push @doubles, $l if defined $unified_info{libraries}->{$l};
     2266        }
     2267        die "these libraries are both explicitly static and shared:\n  ",
     2268            join(" ", @doubles), "\n"
     2269            if @doubles;
    20902270
    20912271        foreach (keys %sources) {
    20922272            my $dest = $_;
    20932273            my $ddest = cleanfile($buildd, $_, $blddir);
    2094             if ($unified_info{rename}->{$ddest}) {
    2095                 $ddest = $unified_info{rename}->{$ddest};
    2096             }
    20972274            foreach (@{$sources{$dest}}) {
    20982275                my $s = cleanfile($sourced, $_, $blddir);
    20992276
    2100                 # If it isn't in the source tree, we assume it's generated
    2101                 # in the build tree
    2102                 if ($s eq $src_configdata || ! -f $s || $generate{$_}) {
     2277                # If it's generated or we simply don't find it in the source
     2278                # tree, we assume it's in the build tree.
     2279                if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
    21032280                    $s = cleanfile($buildd, $_, $blddir);
    21042281                }
     2282                my $o = $_;
    21052283                # We recognise C++, C and asm files
    21062284                if ($s =~ /\.(cc|cpp|c|s|S)$/) {
    2107                     my $o = $_;
     2285                    push @{$check_exist{$s}}, $ddest;
    21082286                    $o =~ s/\.[csS]$/.o/; # C and assembler
    21092287                    $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
    21102288                    $o = cleanfile($buildd, $o, $blddir);
    2111                     $unified_info{sources}->{$ddest}->{$o} = 1;
    2112                     $unified_info{sources}->{$o}->{$s} = 1;
     2289                    $unified_info{sources}->{$ddest}->{$o} = -1;
     2290                    $unified_info{sources}->{$o}->{$s} = -1;
    21132291                } elsif ($s =~ /\.rc$/) {
    21142292                    # We also recognise resource files
    2115                     my $o = $_;
     2293                    push @{$check_exist{$s}}, $ddest;
    21162294                    $o =~ s/\.rc$/.res/; # Resource configuration
    2117                     my $o = cleanfile($buildd, $o, $blddir);
    2118                     $unified_info{sources}->{$ddest}->{$o} = 1;
    2119                     $unified_info{sources}->{$o}->{$s} = 1;
     2295                    $o = cleanfile($buildd, $o, $blddir);
     2296                    $unified_info{sources}->{$ddest}->{$o} = -1;
     2297                    $unified_info{sources}->{$o}->{$s} = -1;
    21202298                } else {
     2299                    push @{$check_exist{$s}}, $ddest;
    21212300                    $unified_info{sources}->{$ddest}->{$s} = 1;
     2301                }
     2302                # Fix up associated attributes
     2303                if ($o ne $_) {
     2304                    $unified_info{attributes}->{sources}->{$ddest}->{$o} =
     2305                        $unified_info{attributes}->{sources}->{$o}->{$s} =
     2306                        $attributes{sources}->{$dest}->{$_}
     2307                        if defined $attributes{sources}->{$dest}->{$_};
     2308                } else {
     2309                    $unified_info{attributes}->{sources}->{$ddest}->{$s} =
     2310                        $attributes{sources}->{$dest}->{$_}
     2311                        if defined $attributes{sources}->{$dest}->{$_};
    21222312                }
    21232313            }
     
    21272317            my $dest = $_;
    21282318            my $ddest = cleanfile($buildd, $_, $blddir);
    2129             if ($unified_info{rename}->{$ddest}) {
    2130                 $ddest = $unified_info{rename}->{$ddest};
    2131             }
    21322319            foreach (@{$shared_sources{$dest}}) {
    21332320                my $s = cleanfile($sourced, $_, $blddir);
    21342321
    2135                 # If it isn't in the source tree, we assume it's generated
    2136                 # in the build tree
    2137                 if ($s eq $src_configdata || ! -f $s || $generate{$_}) {
     2322                # If it's generated or we simply don't find it in the source
     2323                # tree, we assume it's in the build tree.
     2324                if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
    21382325                    $s = cleanfile($buildd, $_, $blddir);
    21392326                }
    21402327
     2328                my $o = $_;
    21412329                if ($s =~ /\.(cc|cpp|c|s|S)$/) {
    21422330                    # We recognise C++, C and asm files
    2143                     my $o = $_;
     2331                    push @{$check_exist{$s}}, $ddest;
    21442332                    $o =~ s/\.[csS]$/.o/; # C and assembler
    21452333                    $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
    21462334                    $o = cleanfile($buildd, $o, $blddir);
    2147                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
    2148                     $unified_info{sources}->{$o}->{$s} = 1;
     2335                    $unified_info{shared_sources}->{$ddest}->{$o} = -1;
     2336                    $unified_info{sources}->{$o}->{$s} = -1;
    21492337                } elsif ($s =~ /\.rc$/) {
    21502338                    # We also recognise resource files
    2151                     my $o = $_;
     2339                    push @{$check_exist{$s}}, $ddest;
    21522340                    $o =~ s/\.rc$/.res/; # Resource configuration
    2153                     my $o = cleanfile($buildd, $o, $blddir);
     2341                    $o = cleanfile($buildd, $o, $blddir);
     2342                    $unified_info{shared_sources}->{$ddest}->{$o} = -1;
     2343                    $unified_info{sources}->{$o}->{$s} = -1;
     2344                } elsif ($s =~ /\.ld$/) {
     2345                    # We also recognise linker scripts (or corresponding)
     2346                    # We know they are generated files
     2347                    push @{$check_exist{$s}}, $ddest;
     2348                    $o = cleanfile($buildd, $_, $blddir);
    21542349                    $unified_info{shared_sources}->{$ddest}->{$o} = 1;
    2155                     $unified_info{sources}->{$o}->{$s} = 1;
    2156                 } elsif ($s =~ /\.(def|map|opt)$/) {
    2157                     # We also recognise .def / .map / .opt files
    2158                     # We know they are generated files
    2159                     my $def = cleanfile($buildd, $s, $blddir);
    2160                     $unified_info{shared_sources}->{$ddest}->{$def} = 1;
    21612350                } else {
    21622351                    die "unrecognised source file type for shared library: $s\n";
     2352                }
     2353                # Fix up associated attributes
     2354                if ($o ne $_) {
     2355                    $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
     2356                        $unified_info{attributes}->{sources}->{$o}->{$s} =
     2357                        $attributes{sources}->{$dest}->{$_}
     2358                        if defined $attributes{sources}->{$dest}->{$_};
     2359                } else {
     2360                    $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
     2361                        $attributes{sources}->{$dest}->{$_}
     2362                        if defined $attributes{sources}->{$dest}->{$_};
    21632363                }
    21642364            }
     
    21682368            my $dest = $_;
    21692369            my $ddest = cleanfile($buildd, $_, $blddir);
    2170             if ($unified_info{rename}->{$ddest}) {
    2171                 $ddest = $unified_info{rename}->{$ddest};
    2172             }
    21732370            die "more than one generator for $dest: "
    2174                     ,join(" ", @{$generate{$_}}),"\n"
    2175                     if scalar @{$generate{$_}} > 1;
     2371                ,join(" ", @{$generate{$_}}),"\n"
     2372                if scalar @{$generate{$_}} > 1;
    21762373            my @generator = split /\s+/, $generate{$dest}->[0];
    2177             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
     2374            my $gen = $generator[0];
     2375            $generator[0] = cleanfile($sourced, $gen, $blddir);
     2376
     2377            # If the generator is itself generated, it's in the build tree
     2378            if ($generate{$gen} || ! -f $generator[0]) {
     2379                $generator[0] = cleanfile($buildd, $gen, $blddir);
     2380            }
     2381            $check_generate{$ddest}->{$generator[0]}++;
     2382
    21782383            $unified_info{generate}->{$ddest} = [ @generator ];
    21792384        }
     
    21812386        foreach (keys %depends) {
    21822387            my $dest = $_;
    2183             my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
    2184 
    2185             # If the destination doesn't exist in source, it can only be
    2186             # a generated file in the build tree.
    2187             if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) {
    2188                 $ddest = cleanfile($buildd, $_, $blddir);
    2189                 if ($unified_info{rename}->{$ddest}) {
    2190                     $ddest = $unified_info{rename}->{$ddest};
     2388            my $ddest = $dest;
     2389
     2390            if ($dest =~ /^\|(.*)\|$/) {
     2391                # Collect the raw target
     2392                $unified_info{targets}->{$1} = 1;
     2393                $ddest = $1;
     2394            } elsif ($dest eq '') {
     2395                $ddest = '';
     2396            } else {
     2397                $ddest = cleanfile($sourced, $_, $blddir);
     2398
     2399                # If the destination doesn't exist in source, it can only be
     2400                # a generated file in the build tree.
     2401                if ($ddest eq $src_configdata || ! -f $ddest) {
     2402                    $ddest = cleanfile($buildd, $_, $blddir);
    21912403                }
    21922404            }
    21932405            foreach (@{$depends{$dest}}) {
    21942406                my $d = cleanfile($sourced, $_, $blddir);
     2407                my $d2 = cleanfile($buildd, $_, $blddir);
    21952408
    21962409                # If we know it's generated, or assume it is because we can't
    21972410                # find it in the source tree, we set file we depend on to be
    2198                 # in the build tree rather than the source tree, and assume
    2199                 # and that there are lines to build it in a BEGINRAW..ENDRAW
    2200                 # section or in the Makefile template.
     2411                # in the build tree rather than the source tree.
    22012412                if ($d eq $src_configdata
    2202                     || ! -f $d
    2203                     || (grep { $d eq $_ }
    2204                         map { cleanfile($srcdir, $_, $blddir) }
    2205                         grep { /\.h$/ } keys %{$unified_info{generate}})) {
    2206                     $d = cleanfile($buildd, $_, $blddir);
    2207                 }
    2208                 # Take note if the file to depend on is being renamed
    2209                 # Take extra care with files ending with .a, they should
    2210                 # be treated without that extension, and the extension
    2211                 # should be added back after treatment.
    2212                 $d =~ /(\.a)?$/;
    2213                 my $e = $1 // "";
    2214                 $d = $`;
    2215                 if ($unified_info{rename}->{$d}) {
    2216                     $d = $unified_info{rename}->{$d};
    2217                 }
    2218                 $d .= $e;
     2413                    || (grep { $d2 eq $_ }
     2414                        keys %{$unified_info{generate}})
     2415                    || ! -f $d) {
     2416                    $d = $d2;
     2417                }
    22192418                $unified_info{depends}->{$ddest}->{$d} = 1;
     2419
     2420                # Fix up associated attributes
     2421                $unified_info{attributes}->{depends}->{$ddest}->{$d} =
     2422                    $attributes{depends}->{$dest}->{$_}
     2423                    if defined $attributes{depends}->{$dest}->{$_};
    22202424            }
    22212425        }
     
    22292433            if ($ddest eq $src_configdata || ! -f $ddest) {
    22302434                $ddest = cleanfile($buildd, $_, $blddir);
    2231                 if ($unified_info{rename}->{$ddest}) {
    2232                     $ddest = $unified_info{rename}->{$ddest};
    2233                 }
    22342435            }
    22352436            foreach (@{$includes{$dest}}) {
     
    22422443            }
    22432444        }
     2445
     2446        foreach my $dest (keys %defines) {
     2447            my $ddest;
     2448
     2449            if ($dest ne "") {
     2450                $ddest = cleanfile($sourced, $dest, $blddir);
     2451
     2452                # If the destination doesn't exist in source, it can only
     2453                # be a generated file in the build tree.
     2454                if (! -f $ddest) {
     2455                    $ddest = cleanfile($buildd, $dest, $blddir);
     2456                }
     2457            }
     2458            foreach my $v (@{$defines{$dest}}) {
     2459                $v =~ m|^([^=]*)(=.*)?$|;
     2460                die "0 length macro name not permitted\n" if $1 eq "";
     2461                if ($dest ne "") {
     2462                    die "$1 defined more than once\n"
     2463                        if defined $unified_info{defines}->{$ddest}->{$1};
     2464                    $unified_info{defines}->{$ddest}->{$1} = $2;
     2465                } else {
     2466                    die "$1 defined more than once\n"
     2467                        if grep { $v eq $_ } @{$config{defines}};
     2468                    push @{$config{defines}}, $v;
     2469                }
     2470            }
     2471        }
     2472
     2473        foreach my $section (keys %imagedocs) {
     2474            foreach (@{$imagedocs{$section}}) {
     2475                my $imagedocs = cleanfile($buildd, $_, $blddir);
     2476                $unified_info{imagedocs}->{$section}->{$imagedocs} = 1;
     2477            }
     2478        }
     2479
     2480        foreach my $section (keys %htmldocs) {
     2481            foreach (@{$htmldocs{$section}}) {
     2482                my $htmldocs = cleanfile($buildd, $_, $blddir);
     2483                $unified_info{htmldocs}->{$section}->{$htmldocs} = 1;
     2484            }
     2485        }
     2486
     2487        foreach my $section (keys %mandocs) {
     2488            foreach (@{$mandocs{$section}}) {
     2489                my $mandocs = cleanfile($buildd, $_, $blddir);
     2490                $unified_info{mandocs}->{$section}->{$mandocs} = 1;
     2491            }
     2492        }
    22442493    }
    22452494
     
    22522501EOF
    22532502
     2503    # Check that each generated file is only generated once
     2504    my $ambiguous_generation = 0;
     2505    foreach (sort keys %check_generate) {
     2506        my @generators = sort keys %{$check_generate{$_}};
     2507        my $generators_txt = join(', ', @generators);
     2508        if (scalar @generators > 1) {
     2509            warn "$_ is GENERATEd by more than one generator ($generators_txt)\n";
     2510            $ambiguous_generation++;
     2511        }
     2512        if ($check_generate{$_}->{$generators[0]} > 1) {
     2513            warn "INFO: $_ has more than one GENERATE declaration (same generator)\n"
     2514        }
     2515    }
     2516    die "There are ambiguous source file generations\n"
     2517        if $ambiguous_generation > 0;
     2518
     2519    # All given source files should exist, or if generated, their
     2520    # generator should exist.  This loop ensures this is true.
     2521    my $missing = 0;
     2522    foreach my $orig (sort keys %check_exist) {
     2523        foreach my $dest (@{$check_exist{$orig}}) {
     2524            if ($orig ne $src_configdata) {
     2525                if ($orig =~ /\.a$/) {
     2526                    # Static library names may be used as sources, so we
     2527                    # need to detect those and give them special treatment.
     2528                    unless (grep { $_ eq $orig }
     2529                            keys %{$unified_info{libraries}}) {
     2530                        warn "$orig is given as source for $dest, but no such library is built\n";
     2531                        $missing++;
     2532                    }
     2533                } else {
     2534                    # A source may be generated, and its generator may be
     2535                    # generated as well.  We therefore loop to dig out the
     2536                    # first generator.
     2537                    my $gen = $orig;
     2538
     2539                    while (my @next = keys %{$check_generate{$gen}}) {
     2540                        $gen = $next[0];
     2541                    }
     2542
     2543                    if (! -f $gen) {
     2544                        if ($gen ne $orig) {
     2545                            $missing++;
     2546                            warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n";
     2547                        } else {
     2548                            $missing++;
     2549                            warn "$orig is given as source for $dest, but is missing\n";
     2550                        }
     2551                    }
     2552                }
     2553            }
     2554        }
     2555    }
     2556    die "There are files missing\n" if $missing > 0;
     2557
     2558    # Go through the sources of all libraries and check that the same basename
     2559    # doesn't appear more than once.  Some static library archivers depend on
     2560    # them being unique.
     2561    {
     2562        my $err = 0;
     2563        foreach my $prod (keys %{$unified_info{libraries}}) {
     2564            my @prod_sources =
     2565                map { keys %{$unified_info{sources}->{$_}} }
     2566                keys %{$unified_info{sources}->{$prod}};
     2567            my %srccnt = ();
     2568
     2569            # Count how many times a given each source basename
     2570            # appears for each product.
     2571            foreach my $src (@prod_sources) {
     2572                $srccnt{basename $src}++;
     2573            }
     2574
     2575            foreach my $src (keys %srccnt) {
     2576                if ((my $cnt = $srccnt{$src}) > 1) {
     2577                    print STDERR "$src appears $cnt times for the product $prod\n";
     2578                    $err++
     2579                }
     2580            }
     2581        }
     2582        die if $err > 0;
     2583    }
     2584
    22542585    # Massage the result
    2255 
    2256     # If the user configured no-shared, we allow no shared sources
    2257     if ($disabled{shared}) {
    2258         foreach (keys %{$unified_info{shared_sources}}) {
    2259             foreach (keys %{$unified_info{shared_sources}->{$_}}) {
    2260                 delete $unified_info{sources}->{$_};
    2261             }
    2262         }
    2263         $unified_info{shared_sources} = {};
    2264     }
    22652586
    22662587    # If we depend on a header file or a perl module, add an inclusion of
     
    22792600    }
    22802601
    2281     # Trickle down includes placed on libraries, engines and programs to
    2282     # their sources (i.e. object files)
    2283     foreach my $dest (keys %{$unified_info{engines}},
    2284                       keys %{$unified_info{libraries}},
    2285                       keys %{$unified_info{programs}}) {
    2286         foreach my $k (("source", "build")) {
    2287             next unless defined($unified_info{includes}->{$dest}->{$k});
    2288             my @incs = reverse @{$unified_info{includes}->{$dest}->{$k}};
    2289             foreach my $obj (grep /\.o$/,
    2290                              (keys %{$unified_info{sources}->{$dest} // {}},
    2291                               keys %{$unified_info{shared_sources}->{$dest} // {}})) {
    2292                 foreach my $inc (@incs) {
    2293                     unshift @{$unified_info{includes}->{$obj}->{$k}}, $inc
    2294                         unless grep { $_ eq $inc } @{$unified_info{includes}->{$obj}->{$k}};
    2295                 }
    2296             }
    2297         }
    2298         delete $unified_info{includes}->{$dest};
    2299     }
     2602    # Go through all intermediary files and change their names to something that
     2603    # reflects what they will be built for.  Note that for some source files,
     2604    # this leads to duplicate object files because they are used multiple times.
     2605    # the goal is to rename all object files according to this scheme:
     2606    #    {productname}-{midfix}-{origobjname}.[o|res]
     2607    # the {midfix} is a keyword indicating the type of product, which is mostly
     2608    # valuable for libraries since they come in two forms.
     2609    #
     2610    # This also reorganises the {sources} and {shared_sources} so that the
     2611    # former only contains ALL object files that are supposed to end up in
     2612    # static libraries and programs, while the latter contains ALL object files
     2613    # that are supposed to end up in shared libraries and DSOs.
     2614    # The main reason for having two different source structures is to allow
     2615    # the same name to be used for the static and the shared variants of a
     2616    # library.
     2617    {
     2618        # Take copies so we don't get interference from added stuff
     2619        my %unified_copy = ();
     2620        foreach (('sources', 'shared_sources')) {
     2621            $unified_copy{$_} = { %{$unified_info{$_}} }
     2622                if defined($unified_info{$_});
     2623            delete $unified_info{$_};
     2624        }
     2625        foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) {
     2626            # $intent serves multi purposes:
     2627            # - give a prefix for the new object files names
     2628            # - in the case of libraries, rearrange the object files so static
     2629            #   libraries use the 'sources' structure exclusively, while shared
     2630            #   libraries use the 'shared_sources' structure exclusively.
     2631            my $intent = {
     2632                programs  => { bin    => { src => [ 'sources' ],
     2633                                           dst => 'sources' } },
     2634                libraries => { lib    => { src => [ 'sources' ],
     2635                                           dst => 'sources' },
     2636                               shlib  => { prodselect =>
     2637                                               sub { grep !/\.a$/, @_ },
     2638                                           src => [ 'sources',
     2639                                                    'shared_sources' ],
     2640                                           dst => 'shared_sources' } },
     2641                modules   => { dso    => { src => [ 'sources' ],
     2642                                           dst => 'sources' } },
     2643                scripts   => { script => { src => [ 'sources' ],
     2644                                           dst => 'sources' } }
     2645               } -> {$prodtype};
     2646            foreach my $kind (keys %$intent) {
     2647                next if ($intent->{$kind}->{dst} eq 'shared_sources'
     2648                             && $disabled{shared});
     2649
     2650                my @src = @{$intent->{$kind}->{src}};
     2651                my $dst = $intent->{$kind}->{dst};
     2652                my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ };
     2653                foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) {
     2654                    # %prod_sources has all applicable objects as keys, and
     2655                    # their corresponding sources as values
     2656                    my %prod_sources =
     2657                        map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] }
     2658                        map { keys %{$unified_copy{$_}->{$prod}} }
     2659                        @src;
     2660                    foreach (keys %prod_sources) {
     2661                        # Only affect object files and resource files,
     2662                        # the others simply get a new value
     2663                        # (+1 instead of -1)
     2664                        if ($_ =~ /\.(o|res)$/) {
     2665                            (my $prodname = $prod) =~ s|\.a$||;
     2666                            my $newobj =
     2667                                catfile(dirname($_),
     2668                                        basename($prodname)
     2669                                            . '-' . $kind
     2670                                            . '-' . basename($_));
     2671                            $unified_info{$dst}->{$prod}->{$newobj} = 1;
     2672                            foreach my $src (@{$prod_sources{$_}}) {
     2673                                $unified_info{sources}->{$newobj}->{$src} = 1;
     2674                                # Adjust source attributes
     2675                                my $attrs = $unified_info{attributes}->{sources};
     2676                                if (defined $attrs->{$prod}
     2677                                    && defined $attrs->{$prod}->{$_}) {
     2678                                    $attrs->{$prod}->{$newobj} =
     2679                                        $attrs->{$prod}->{$_};
     2680                                    delete $attrs->{$prod}->{$_};
     2681                                }
     2682                                foreach my $objsrc (keys %{$attrs->{$_} // {}}) {
     2683                                    $attrs->{$newobj}->{$objsrc} =
     2684                                        $attrs->{$_}->{$objsrc};
     2685                                    delete $attrs->{$_}->{$objsrc};
     2686                                }
     2687                            }
     2688                            # Adjust dependencies
     2689                            foreach my $deps (keys %{$unified_info{depends}->{$_}}) {
     2690                                $unified_info{depends}->{$_}->{$deps} = -1;
     2691                                $unified_info{depends}->{$newobj}->{$deps} = 1;
     2692                            }
     2693                            # Adjust includes
     2694                            foreach my $k (('source', 'build')) {
     2695                                next unless
     2696                                    defined($unified_info{includes}->{$_}->{$k});
     2697                                my @incs = @{$unified_info{includes}->{$_}->{$k}};
     2698                                $unified_info{includes}->{$newobj}->{$k} = [ @incs ];
     2699                            }
     2700                        } else {
     2701                            $unified_info{$dst}->{$prod}->{$_} = 1;
     2702                        }
     2703                    }
     2704                }
     2705            }
     2706        }
     2707    }
     2708
     2709    # At this point, we have a number of sources with the value -1.  They
     2710    # aren't part of the local build and are probably meant for a different
     2711    # platform, and can therefore be cleaned away.  That happens when making
     2712    # %unified_info more efficient below.
    23002713
    23012714    ### Make unified_info a bit more efficient
    23022715    # One level structures
    2303     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
     2716    foreach (("programs", "libraries", "modules", "scripts", "targets")) {
    23042717        $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
    23052718    }
    23062719    # Two level structures
    2307     foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
     2720    foreach my $l1 (("sources", "shared_sources", "ldadd", "depends",
     2721                     "imagedocs", "htmldocs", "mandocs")) {
    23082722        foreach my $l2 (sort keys %{$unified_info{$l1}}) {
    2309             $unified_info{$l1}->{$l2} =
    2310                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
    2311         }
     2723            my @items =
     2724                sort
     2725                grep { $unified_info{$l1}->{$l2}->{$_} > 0 }
     2726                keys %{$unified_info{$l1}->{$l2}};
     2727            if (@items) {
     2728                $unified_info{$l1}->{$l2} = [ @items ];
     2729            } else {
     2730                delete $unified_info{$l1}->{$l2};
     2731            }
     2732        }
     2733    }
     2734    # Defines
     2735    foreach my $dest (sort keys %{$unified_info{defines}}) {
     2736        $unified_info{defines}->{$dest}
     2737            = [ map { $_.$unified_info{defines}->{$dest}->{$_} }
     2738                sort keys %{$unified_info{defines}->{$dest}} ];
    23122739    }
    23132740    # Includes
     
    23232750                    unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
    23242751            }
    2325         } else {
     2752        } elsif (defined($unified_info{includes}->{$dest}->{source})) {
    23262753            $unified_info{includes}->{$dest} =
    23272754                [ @{$unified_info{includes}->{$dest}->{source}} ];
     2755        } else {
     2756            delete $unified_info{includes}->{$dest};
    23282757        }
    23292758    }
     
    23342763    # directories
    23352764    my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ],
    2336                      "dso" => [ @{$unified_info{engines}} ],
     2765                     "dso" => [ @{$unified_info{modules}} ],
    23372766                     "bin" => [ @{$unified_info{programs}} ],
    2338                      "script" => [ @{$unified_info{scripts}} ] );
     2767                     "script" => [ @{$unified_info{scripts}} ],
     2768                     "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} }
     2769                                  keys %{$unified_info{imagedocs} // {}}),
     2770                                 (map { @{$unified_info{htmldocs}->{$_} // []} }
     2771                                  keys %{$unified_info{htmldocs} // {}}),
     2772                                 (map { @{$unified_info{mandocs}->{$_} // []} }
     2773                                  keys %{$unified_info{mandocs} // {}}) ] );
    23392774    foreach my $type (keys %loopinfo) {
    23402775        foreach my $product (@{$loopinfo{$type}}) {
     
    23782813# Write down our configuration where it fits #########################
    23792814
    2380 print "Creating configdata.pm\n";
    2381 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
    2382 print OUT <<"EOF";
    2383 #! $config{HASHBANGPERL}
    2384 
    2385 package configdata;
    2386 
    2387 use strict;
    2388 use warnings;
    2389 
    2390 use Exporter;
    2391 #use vars qw(\@ISA \@EXPORT);
    2392 our \@ISA = qw(Exporter);
    2393 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
    2394 
    2395 EOF
    2396 print OUT "our %config = (\n";
    2397 foreach (sort keys %config) {
    2398     if (ref($config{$_}) eq "ARRAY") {
    2399         print OUT "  ", $_, " => [ ", join(", ",
    2400                                            map { quotify("perl", $_) }
    2401                                            @{$config{$_}}), " ],\n";
    2402     } elsif (ref($config{$_}) eq "HASH") {
    2403         print OUT "  ", $_, " => {";
    2404         if (scalar keys %{$config{$_}} > 0) {
    2405             print OUT "\n";
    2406             foreach my $key (sort keys %{$config{$_}}) {
    2407                 print OUT "      ",
    2408                     join(" => ",
    2409                          quotify("perl", $key),
    2410                          defined $config{$_}->{$key}
    2411                              ? quotify("perl", $config{$_}->{$key})
    2412                              : "undef");
    2413                 print OUT ",\n";
    2414             }
    2415             print OUT "  ";
    2416         }
    2417         print OUT "},\n";
    2418     } else {
    2419         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
    2420     }
    2421 }
    2422 print OUT <<"EOF";
     2815my %template_vars = (
     2816    config => \%config,
     2817    target => \%target,
     2818    disablables => \@disablables,
     2819    disablables_int => \@disablables_int,
     2820    disabled => \%disabled,
     2821    withargs => \%withargs,
     2822    unified_info => \%unified_info,
     2823    tls => \@tls,
     2824    dtls => \@dtls,
     2825    makevars => [ sort keys %user ],
     2826    disabled_info => \%disabled_info,
     2827    user_crossable => \@user_crossable,
    24232828);
    2424 
    2425 EOF
    2426 print OUT "our %target = (\n";
    2427 foreach (sort keys %target) {
    2428     if (ref($target{$_}) eq "ARRAY") {
    2429         print OUT "  ", $_, " => [ ", join(", ",
    2430                                            map { quotify("perl", $_) }
    2431                                            @{$target{$_}}), " ],\n";
    2432     } else {
    2433         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
    2434     }
    2435 }
    2436 print OUT <<"EOF";
    2437 );
    2438 
    2439 EOF
    2440 print OUT "our \%available_protocols = (\n";
    2441 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
    2442 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
    2443 print OUT <<"EOF";
    2444 );
    2445 
    2446 EOF
    2447 print OUT "our \@disablables = (\n";
    2448 foreach (@disablables) {
    2449     print OUT "  ", quotify("perl", $_), ",\n";
    2450 }
    2451 print OUT <<"EOF";
    2452 );
    2453 
    2454 EOF
    2455 print OUT "our \%disabled = (\n";
    2456 foreach (sort keys %disabled) {
    2457     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
    2458 }
    2459 print OUT <<"EOF";
    2460 );
    2461 
    2462 EOF
    2463 print OUT "our %withargs = (\n";
    2464 foreach (sort keys %withargs) {
    2465     if (ref($withargs{$_}) eq "ARRAY") {
    2466         print OUT "  ", $_, " => [ ", join(", ",
    2467                                            map { quotify("perl", $_) }
    2468                                            @{$withargs{$_}}), " ],\n";
    2469     } else {
    2470         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
    2471     }
    2472 }
    2473 print OUT <<"EOF";
    2474 );
    2475 
    2476 EOF
    2477 if ($builder eq "unified") {
    2478     my $recurse;
    2479     $recurse = sub {
    2480         my $indent = shift;
    2481         foreach (@_) {
    2482             if (ref $_ eq "ARRAY") {
    2483                 print OUT " "x$indent, "[\n";
    2484                 foreach (@$_) {
    2485                     $recurse->($indent + 4, $_);
    2486                 }
    2487                 print OUT " "x$indent, "],\n";
    2488             } elsif (ref $_ eq "HASH") {
    2489                 my %h = %$_;
    2490                 print OUT " "x$indent, "{\n";
    2491                 foreach (sort keys %h) {
    2492                     if (ref $h{$_} eq "") {
    2493                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
    2494                     } else {
    2495                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
    2496                         $recurse->($indent + 8, $h{$_});
    2497                     }
    2498                 }
    2499                 print OUT " "x$indent, "},\n";
    2500             } else {
    2501                 print OUT " "x$indent, quotify("perl", $_), ",\n";
    2502             }
    2503         }
    2504     };
    2505     print OUT "our %unified_info = (\n";
    2506     foreach (sort keys %unified_info) {
    2507         if (ref $unified_info{$_} eq "") {
    2508             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
    2509         } else {
    2510             print OUT " "x4, quotify("perl", $_), " =>\n";
    2511             $recurse->(8, $unified_info{$_});
    2512         }
    2513     }
    2514     print OUT <<"EOF";
    2515 );
    2516 
    2517 EOF
    2518 }
    2519 print OUT
    2520     "# The following data is only used when this files is use as a script\n";
    2521 print OUT "my \@makevars = (\n";
    2522 foreach (sort keys %user) {
    2523     print OUT "    '",$_,"',\n";
    2524 }
    2525 print OUT ");\n";
    2526 print OUT "my \%disabled_info = (\n";
    2527 foreach my $what (sort keys %disabled_info) {
    2528     print OUT "    '$what' => {\n";
    2529     foreach my $info (sort keys %{$disabled_info{$what}}) {
    2530         if (ref $disabled_info{$what}->{$info} eq 'ARRAY') {
    2531             print OUT "        $info => [ ",
    2532                 join(', ', map { "'$_'" } @{$disabled_info{$what}->{$info}}),
    2533                 " ],\n";
    2534         } else {
    2535             print OUT "        $info => '", $disabled_info{$what}->{$info},
    2536                 "',\n";
    2537         }
    2538     }
    2539     print OUT "    },\n";
    2540 }
    2541 print OUT ");\n";
    2542 print OUT 'my @user_crossable = qw( ', join (' ', @user_crossable), " );\n";
    2543 print OUT << 'EOF';
    2544 # If run directly, we can give some answers, and even reconfigure
    2545 unless (caller) {
    2546     use Getopt::Long;
    2547     use File::Spec::Functions;
    2548     use File::Basename;
    2549     use Pod::Usage;
    2550 
    2551     my $here = dirname($0);
    2552 
    2553     my $dump = undef;
    2554     my $cmdline = undef;
    2555     my $options = undef;
    2556     my $target = undef;
    2557     my $envvars = undef;
    2558     my $makevars = undef;
    2559     my $buildparams = undef;
    2560     my $reconf = undef;
    2561     my $verbose = undef;
    2562     my $help = undef;
    2563     my $man = undef;
    2564     GetOptions('dump|d'                 => \$dump,
    2565                'command-line|c'         => \$cmdline,
    2566                'options|o'              => \$options,
    2567                'target|t'               => \$target,
    2568                'environment|e'          => \$envvars,
    2569                'make-variables|m'       => \$makevars,
    2570                'build-parameters|b'     => \$buildparams,
    2571                'reconfigure|reconf|r'   => \$reconf,
    2572                'verbose|v'              => \$verbose,
    2573                'help'                   => \$help,
    2574                'man'                    => \$man)
    2575         or die "Errors in command line arguments\n";
    2576 
    2577     unless ($dump || $cmdline || $options || $target || $envvars || $makevars
    2578             || $buildparams || $reconf || $verbose || $help || $man) {
    2579         print STDERR <<"_____";
    2580 You must give at least one option.
    2581 For more information, do '$0 --help'
    2582 _____
    2583         exit(2);
    2584     }
    2585 
    2586     if ($help) {
    2587         pod2usage(-exitval => 0,
    2588                   -verbose => 1);
    2589     }
    2590     if ($man) {
    2591         pod2usage(-exitval => 0,
    2592                   -verbose => 2);
    2593     }
    2594     if ($dump || $cmdline) {
    2595         print "\nCommand line (with current working directory = $here):\n\n";
    2596         print '    ',join(' ',
    2597                           $config{PERL},
    2598                           catfile($config{sourcedir}, 'Configure'),
    2599                           @{$config{perlargv}}), "\n";
    2600         print "\nPerl information:\n\n";
    2601         print '    ',$config{perl_cmd},"\n";
    2602         print '    ',$config{perl_version},' for ',$config{perl_archname},"\n";
    2603     }
    2604     if ($dump || $options) {
    2605         my $longest = 0;
    2606         my $longest2 = 0;
    2607         foreach my $what (@disablables) {
    2608             $longest = length($what) if $longest < length($what);
    2609             $longest2 = length($disabled{$what})
    2610                 if $disabled{$what} && $longest2 < length($disabled{$what});
    2611         }
    2612         print "\nEnabled features:\n\n";
    2613         foreach my $what (@disablables) {
    2614             print "    $what\n"
    2615                 unless grep { $_ =~ /^${what}$/ } keys %disabled;
    2616         }
    2617         print "\nDisabled features:\n\n";
    2618         foreach my $what (@disablables) {
    2619             my @what2 = grep { $_ =~ /^${what}$/ } keys %disabled;
    2620             my $what3 = $what2[0];
    2621             if ($what3) {
    2622                 print "    $what3", ' ' x ($longest - length($what3) + 1),
    2623                     "[$disabled{$what3}]", ' ' x ($longest2 - length($disabled{$what3}) + 1);
    2624                 print $disabled_info{$what3}->{macro}
    2625                     if $disabled_info{$what3}->{macro};
    2626                 print ' (skip ',
    2627                     join(', ', @{$disabled_info{$what3}->{skipped}}),
    2628                     ')'
    2629                     if $disabled_info{$what3}->{skipped};
    2630                 print "\n";
    2631             }
    2632         }
    2633     }
    2634     if ($dump || $target) {
    2635         print "\nConfig target attributes:\n\n";
    2636         foreach (sort keys %target) {
    2637             next if $_ =~ m|^_| || $_ eq 'template';
    2638             my $quotify = sub {
    2639                 map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_;
    2640             };
    2641             print '    ', $_, ' => ';
    2642             if (ref($target{$_}) eq "ARRAY") {
    2643                 print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n";
    2644             } else {
    2645                 print $quotify->($target{$_}), ",\n"
    2646             }
    2647         }
    2648     }
    2649     if ($dump || $envvars) {
    2650         print "\nRecorded environment:\n\n";
    2651         foreach (sort keys %{$config{perlenv}}) {
    2652             print '    ',$_,' = ',($config{perlenv}->{$_} || ''),"\n";
    2653         }
    2654     }
    2655     if ($dump || $makevars) {
    2656         print "\nMakevars:\n\n";
    2657         foreach my $var (@makevars) {
    2658             my $prefix = '';
    2659             $prefix = $config{CROSS_COMPILE}
    2660                 if grep { $var eq $_ } @user_crossable;
    2661             $prefix //= '';
    2662             print '    ',$var,' ' x (16 - length $var),'= ',
    2663                 (ref $config{$var} eq 'ARRAY'
    2664                  ? join(' ', @{$config{$var}})
    2665                  : $prefix.$config{$var}),
    2666                 "\n"
    2667                 if defined $config{$var};
    2668         }
    2669 
    2670         my @buildfile = ($config{builddir}, $config{build_file});
    2671         unshift @buildfile, $here
    2672             unless file_name_is_absolute($config{builddir});
    2673         my $buildfile = canonpath(catdir(@buildfile));
    2674         print <<"_____";
    2675 
    2676 NOTE: These variables only represent the configuration view.  The build file
    2677 template may have processed these variables further, please have a look at the
    2678 build file for more exact data:
    2679     $buildfile
    2680 _____
    2681     }
    2682     if ($dump || $buildparams) {
    2683         my @buildfile = ($config{builddir}, $config{build_file});
    2684         unshift @buildfile, $here
    2685             unless file_name_is_absolute($config{builddir});
    2686         print "\nbuild file:\n\n";
    2687         print "    ", canonpath(catfile(@buildfile)),"\n";
    2688 
    2689         print "\nbuild file templates:\n\n";
    2690         foreach (@{$config{build_file_templates}}) {
    2691             my @tmpl = ($_);
    2692             unshift @tmpl, $here
    2693                 unless file_name_is_absolute($config{sourcedir});
    2694             print '    ',canonpath(catfile(@tmpl)),"\n";
    2695         }
    2696     }
    2697     if ($reconf) {
    2698         if ($verbose) {
    2699             print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n";
    2700             foreach (sort keys %{$config{perlenv}}) {
    2701                 print '    ',$_,' = ',($config{perlenv}->{$_} || ""),"\n";
    2702             }
    2703         }
    2704 
    2705         chdir $here;
    2706         exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf';
    2707     }
    2708 }
    2709 
    2710 1;
    2711 
    2712 __END__
    2713 
    2714 =head1 NAME
    2715 
    2716 configdata.pm - configuration data for OpenSSL builds
    2717 
    2718 =head1 SYNOPSIS
    2719 
    2720 Interactive:
    2721 
    2722   perl configdata.pm [options]
    2723 
    2724 As data bank module:
    2725 
    2726   use configdata;
    2727 
    2728 =head1 DESCRIPTION
    2729 
    2730 This module can be used in two modes, interactively and as a module containing
    2731 all the data recorded by OpenSSL's Configure script.
    2732 
    2733 When used interactively, simply run it as any perl script, with at least one
    2734 option, and you will get the information you ask for.  See L</OPTIONS> below.
    2735 
    2736 When loaded as a module, you get a few databanks with useful information to
    2737 perform build related tasks.  The databanks are:
    2738 
    2739     %config             Configured things.
    2740     %target             The OpenSSL config target with all inheritances
    2741                         resolved.
    2742     %disabled           The features that are disabled.
    2743     @disablables        The list of features that can be disabled.
    2744     %withargs           All data given through --with-THING options.
    2745     %unified_info       All information that was computed from the build.info
    2746                         files.
    2747 
    2748 =head1 OPTIONS
    2749 
    2750 =over 4
    2751 
    2752 =item B<--help>
    2753 
    2754 Print a brief help message and exit.
    2755 
    2756 =item B<--man>
    2757 
    2758 Print the manual page and exit.
    2759 
    2760 =item B<--dump> | B<-d>
    2761 
    2762 Print all relevant configuration data.  This is equivalent to B<--command-line>
    2763 B<--options> B<--target> B<--environment> B<--make-variables>
    2764 B<--build-parameters>.
    2765 
    2766 =item B<--command-line> | B<-c>
    2767 
    2768 Print the current configuration command line.
    2769 
    2770 =item B<--options> | B<-o>
    2771 
    2772 Print the features, both enabled and disabled, and display defined macro and
    2773 skipped directories where applicable.
    2774 
    2775 =item B<--target> | B<-t>
    2776 
    2777 Print the config attributes for this config target.
    2778 
    2779 =item B<--environment> | B<-e>
    2780 
    2781 Print the environment variables and their values at the time of configuration.
    2782 
    2783 =item B<--make-variables> | B<-m>
    2784 
    2785 Print the main make variables generated in the current configuration
    2786 
    2787 =item B<--build-parameters> | B<-b>
    2788 
    2789 Print the build parameters, i.e. build file and build file templates.
    2790 
    2791 =item B<--reconfigure> | B<--reconf> | B<-r>
    2792 
    2793 Redo the configuration.
    2794 
    2795 =item B<--verbose> | B<-v>
    2796 
    2797 Verbose output.
    2798 
    2799 =back
    2800 
    2801 =cut
    2802 
    2803 EOF
    2804 close(OUT);
     2829my $configdata_outname = 'configdata.pm';
     2830print "Creating $configdata_outname\n";
     2831open CONFIGDATA, ">$configdata_outname.new"
     2832    or die "Trying to create $configdata_outname.new: $!";
     2833my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir);
     2834my $configdata_tmpl =
     2835    OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname);
     2836$configdata_tmpl->fill_in(
     2837    FILENAME => $configdata_tmplname,
     2838    OUTPUT => \*CONFIGDATA,
     2839    HASH => { %template_vars,
     2840              autowarntext => [
     2841                  'WARNING: do not edit!',
     2842                  "Generated by Configure from $configdata_tmplname",
     2843              ] }
     2844) or die $Text::Template::ERROR;
     2845close CONFIGDATA;
     2846rename "$configdata_outname.new", $configdata_outname;
    28052847if ($builder_platform eq 'unix') {
    28062848    my $mode = (0755 & ~umask);
     
    28092851}
    28102852
    2811 my %builders = (
    2812     unified => sub {
    2813         print 'Creating ',$target{build_file},"\n";
    2814         run_dofile(catfile($blddir, $target{build_file}),
    2815                    @{$config{build_file_templates}});
    2816     },
    2817     );
    2818 
    2819 $builders{$builder}->($builder_platform, @builder_opts);
     2853print "Running $configdata_outname\n";
     2854my $perlcmd = (quotify("maybeshell", $config{PERL}))[0];
     2855my $cmd = "$perlcmd $configdata_outname";
     2856#print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
     2857system($cmd);
     2858exit 1 if $? != 0;
    28202859
    28212860$SIG{__DIE__} = $orig_death_handler;
     
    28252864The library could not be configured for supporting multi-threaded
    28262865applications as the compiler options required on this system are not known.
    2827 See file INSTALL for details if you need multi-threading.
     2866See file INSTALL.md for details if you need multi-threading.
    28282867EOF
    28292868
     
    28372876EOF
    28382877
    2839 print <<"EOF";
    2840 
    2841 **********************************************************************
    2842 ***                                                                ***
    2843 ***   OpenSSL has been successfully configured                     ***
    2844 ***                                                                ***
    2845 ***   If you encounter a problem while building, please open an    ***
    2846 ***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
    2847 ***   and include the output from the following command:           ***
    2848 ***                                                                ***
    2849 ***       perl configdata.pm --dump                                ***
    2850 ***                                                                ***
    2851 ***   (If you are new to OpenSSL, you might want to consult the    ***
    2852 ***   'Troubleshooting' section in the INSTALL file first)         ***
    2853 ***                                                                ***
    2854 **********************************************************************
    2855 EOF
     2878print $banner;
    28562879
    28572880exit(0);
     
    28702893
    28712894Failure!  $build_file wasn't produced.
    2872 Please read INSTALL and associated NOTES files.  You may also have to look over
    2873 your available compiler tool chain or change your configuration.
     2895Please read INSTALL.md and associated NOTES-* files.  You may also have to
     2896look over your available compiler tool chain or change your configuration.
    28742897
    28752898_____
     
    28862909# Thus, whenever there's mention of a returned value, it's about that
    28872910# intended value.
    2888 
    2889 # Helper function to implement conditional inheritance depending on the
    2890 # value of $disabled{asm}.  Used in inherit_from values as follows:
    2891 #
    2892 #      inherit_from => [ "template", asm("asm_tmpl") ]
    2893 #
    2894 sub asm {
    2895     my @x = @_;
    2896     sub {
    2897         $disabled{asm} ? () : @x;
    2898     }
    2899 }
    29002911
    29012912# Helper function to implement conditional value variants, with a default
     
    32163227                print STDERR $i . " ";
    32173228                }
    3218         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
    32193229        exit(1);
    32203230        }
    3221 
    3222 sub run_dofile
    3223 {
    3224     my $out = shift;
    3225     my @templates = @_;
    3226 
    3227     unlink $out || warn "Can't remove $out, $!"
    3228         if -f $out;
    3229     foreach (@templates) {
    3230         die "Can't open $_, $!" unless -f $_;
    3231     }
    3232     my $perlcmd = (quotify("maybeshell", $config{PERL}))[0];
    3233     my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
    3234     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
    3235     system($cmd);
    3236     exit 1 if $? != 0;
    3237     rename("$out.new", $out) || die "Can't rename $out.new, $!";
    3238 }
    32393231
    32403232sub compiler_predefined {
     
    33193311        "cc",
    33203312        "cflags",
    3321         "unistd",
    33223313        "ld",
    33233314        "lflags",
     
    33253316        "ex_libs",
    33263317        "bn_ops",
    3327         "apps_aux_src",
    3328         "cpuid_asm_src",
    3329         "uplink_aux_src",
    3330         "bn_asm_src",
    3331         "ec_asm_src",
    3332         "des_asm_src",
    3333         "aes_asm_src",
    3334         "bf_asm_src",
    3335         "md5_asm_src",
    3336         "cast_asm_src",
    3337         "sha1_asm_src",
    3338         "rc4_asm_src",
    3339         "rmd160_asm_src",
    3340         "rc5_asm_src",
    3341         "wp_asm_src",
    3342         "cmll_asm_src",
    3343         "modes_asm_src",
    3344         "padlock_asm_src",
    3345         "chacha_asm_src",
     3318        "enable",
     3319        "disable",
    33463320        "poly1035_asm_src",
    33473321        "thread_scheme",
     
    35753549
    35763550# tokenize($line)
     3551# tokenize($line,$separator)
    35773552# $line is a line of text to split up into tokens
    3578 # returns a list of tokens
     3553# $separator [optional] is a regular expression that separates the tokens,
     3554# the default being spaces.  Do not use quotes of any kind as separators,
     3555# that will give undefined results.
     3556# Returns a list of tokens.
    35793557#
    3580 # Tokens are divided by spaces.  If the tokens include spaces, they
    3581 # have to be quoted with single or double quotes.  Double quotes
    3582 # inside a double quoted token must be escaped.  Escaping is done
     3558# Tokens are divided by separator (spaces by default).  If the tokens include
     3559# the separators, they have to be quoted with single or double quotes.
     3560# Double quotes inside a double quoted token must be escaped.  Escaping is done
    35833561# with backslash.
    35843562# Basically, the same quoting rules apply for " and ' as in any
     
    35863564sub tokenize {
    35873565    my $line = my $debug_line = shift;
     3566    my $separator = shift // qr|\s+|;
    35883567    my @result = ();
    35893568
    3590     while ($line =~ s|^\s+||, $line ne "") {
     3569    if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
     3570        print STDERR "DEBUG[tokenize]: \$separator = $separator\n";
     3571    }
     3572
     3573    while ($line =~ s|^${separator}||, $line ne "") {
    35913574        my $token = "";
    3592         while ($line ne "" && $line !~ m|^\s|) {
    3593             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
    3594                 $token .= $1;
    3595                 $line = $';
    3596             } elsif ($line =~ m/^'([^']*)'/) {
    3597                 $token .= $1;
    3598                 $line = $';
    3599             } elsif ($line =~ m/^(\S+)/) {
    3600                 $token .= $1;
    3601                 $line = $';
    3602             }
     3575    again:
     3576        $line =~ m/^(.*?)(${separator}|"|'|$)/;
     3577        $token .= $1;
     3578        $line = $2.$';
     3579
     3580        if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
     3581            $token .= $1;
     3582            $line = $';
     3583            goto again;
     3584        } elsif ($line =~ m/^'([^']*)'/) {
     3585            $token .= $1;
     3586            $line = $';
     3587            goto again;
    36033588        }
    36043589        push @result, $token;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette