#! /usr/bin/env perl
# -*- mode: perl; -*-
-# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
my $orig_death_handler = $SIG{__DIE__};
$SIG{__DIE__} = \&death_handler;
-my $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";
+my $usage="Usage: Configure [no-<feature> ...] [enable-<feature> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
my $banner = <<"EOF";
# (Default: PREFIX/ssl)
# --banner=".." Output specified text instead of default completion banner
#
+# -w Don't wait after showing a Configure warning
+#
# --cross-compile-prefix Add specified prefix to binutils components.
#
# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0
# Generic OpenSSL-style methods relating to this support
# are always compiled but return NULL if the hardware
# support isn't compiled.
+#
+# enable-demos Enable the building of the example code in the demos directory
+# enable-h3demo Enable the http3 demo, which currently only links to the
+# external nghttp3 library on unix platforms
# no-hw do not compile support for any crypto hardware.
# [no-]threads [don't] try to create a library that is suitable for
# multithreaded applications (default is "threads" if we
# know how to do it)
+# [no-]thread-pool
+# [don't] allow thread pool functionality
+# [no-]default-thread-pool
+# [don't] allow default thread pool functionality
# [no-]shared [don't] try to create shared libraries when supported.
# [no-]pic [don't] try to build position independent code when supported.
# If disabled, it also disables shared and dynamic-engine.
# no-egd do not compile support for the entropy-gathering daemon APIs
# [no-]zlib [don't] compile support for zlib compression.
# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
-# library and will be loaded in run-time by the OpenSSL library.
+# library and will be loaded at run-time by the OpenSSL library.
# sctp include SCTP support
+# no-quic disable QUIC support
# no-uplink Don't build support for UPLINK interface.
# enable-weak-ssl-ciphers
# Enable weak ciphers that are disabled by default.
-Wsign-compare
-Wshadow
-Wformat
- -Wtype-limits
+ -Wno-type-limits
+ -Wno-tautological-constant-out-of-range-compare
-Wundef
-Werror
-Wmissing-prototypes
-Wno-parentheses-equality
-Wno-language-extension-token
-Wno-extended-offsetof
+ -Wno-missing-braces
-Wconditional-uninitialized
-Wincompatible-pointer-types-discards-qualifiers
-Wmissing-variable-declarations
}
}
+# Fail if no configuration is apparent
+if (!%table) {
+ print "Failed to find any os/compiler configurations. Please make sure the Configurations directory is included.\n";
+ &usage;
+}
+
# Save away perl command information
$config{perl_cmd} = $^X;
$config{perl_version} = $Config{version};
my @disablables = (
"acvp-tests",
"afalgeng",
+ "apps",
+ "argon2",
"aria",
"asan",
"asm",
"async",
+ "atexit",
"autoalginit",
"autoerrinit",
"autoload-config",
"bf",
"blake2",
+ "brotli",
+ "brotli-dynamic",
"buildtest-c++",
"bulk",
"cached-fetch",
"camellia",
"capieng",
+ "winstore",
"cast",
"chacha",
"cmac",
"comp",
"crypto-mdebug",
"ct",
+ "default-thread-pool",
+ "demos",
+ "h3demo",
"deprecated",
"des",
"devcryptoeng",
"dgram",
"dh",
+ "docs",
"dsa",
"dso",
"dtls",
"ec_nistp_64_gcc_128",
"ecdh",
"ecdsa",
+ "ecx",
"egd",
"engine",
"err",
"fuzz-afl",
"fuzz-libfuzzer",
"gost",
+ "http",
"idea",
"ktls",
"legacy",
"poly1305",
"posix-io",
"psk",
+ "quic",
+ "unstable-qlog",
"rc2",
"rc4",
"rc5",
"siphash",
"siv",
"sm2",
+ "sm2-precomp",
"sm3",
"sm4",
"sock",
"static-engine",
"stdio",
"tests",
+ "tfo",
+ "thread-pool",
"threads",
"tls",
"trace",
"whirlpool",
"zlib",
"zlib-dynamic",
+ "zstd",
+ "zstd-dynamic",
);
foreach my $proto ((@tls, @dtls))
{
our %disabled = ( # "what" => "comment"
"fips" => "default",
- "acvp-tests" => "default",
"asan" => "default",
+ "brotli" => "default",
+ "brotli-dynamic" => "default",
"buildtest-c++" => "default",
"crypto-mdebug" => "default",
"crypto-mdebug-backtrace" => "default",
+ "demos" => "default",
+ "h3demo" => "default",
"devcryptoeng" => "default",
"ec_nistp_64_gcc_128" => "default",
"egd" => "default",
"msan" => "default",
"rc5" => "default",
"sctp" => "default",
- "ssl-trace" => "default",
"ssl3" => "default",
"ssl3-method" => "default",
+ "tfo" => "default",
"trace" => "default",
"ubsan" => "default",
"unit-test" => "default",
"weak-ssl-ciphers" => "default",
"zlib" => "default",
"zlib-dynamic" => "default",
+ "zstd" => "default",
+ "zstd-dynamic" => "default",
);
# Note: => pair form used for aesthetics, not to truly make a hash table
my @disable_cascades = (
# "what" => [ "cascade", ... ]
"bulk" => [ "shared", "dso",
- "aria", "async", "autoload-config",
+ "aria", "async", "atexit", "autoload-config",
"blake2", "bf", "camellia", "cast", "chacha",
"cmac", "cms", "cmp", "comp", "ct",
"des", "dgram", "dh", "dsa",
"rc2", "rc4", "rmd160",
"seed", "siphash", "siv",
"sm3", "sm4", "srp",
- "srtp", "ssl3-method",
+ "srtp", "ssl3-method", "ssl-trace",
+ "tfo",
"ts", "ui-console", "whirlpool",
"fips-securitychecks" ],
sub { $config{processor} eq "386" }
"ssl" => [ "ssl3" ],
"ssl3-method" => [ "ssl3" ],
"zlib" => [ "zlib-dynamic" ],
+ "brotli" => [ "brotli-dynamic" ],
+ "zstd" => [ "zstd-dynamic" ],
"des" => [ "mdc2" ],
- "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ],
- "dgram" => [ "dtls", "sctp" ],
- "sock" => [ "dgram" ],
+ "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost", "ecx" ],
+ "dgram" => [ "dtls", "quic", "sctp" ],
+ "sock" => [ "dgram", "tfo" ],
"dtls" => [ @dtls ],
sub { 0 == scalar grep { !$disabled{$_} } @dtls }
=> [ "dtls" ],
"tls" => [ @tls ],
sub { 0 == scalar grep { !$disabled{$_} } @tls }
=> [ "tls" ],
+ "tls1_3" => [ "quic" ],
+ "quic" => [ "unstable-qlog" ],
"crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
- # If no modules, then no dynamic engines either
- "module" => [ "dynamic-engine" ],
+ "module" => [ "dynamic-engine", "fips" ],
# Without shared libraries, dynamic engines aren't possible.
# This is due to them having to link with libcrypto and register features
# using the ENGINE functionality, and since that relies on global tables,
- # those *have* to be exacty the same as the ones accessed from the app,
+ # those *have* to be exactly the same as the ones accessed from the app,
# which cannot be guaranteed if shared libraries aren't present.
# (note that even with shared libraries, both the app and dynamic engines
# must be linked with the same library)
# or modules.
"pic" => [ "shared", "module" ],
- "module" => [ "fips", "dso" ],
-
"engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ],
+ "dynamic-engine" => [ "loadereng" ],
"hw" => [ "padlockeng" ],
# no-autoalginit is only useful when building non-shared
"stdio" => [ "apps", "capieng", "egd" ],
"apps" => [ "tests" ],
"tests" => [ "external-tests" ],
- "comp" => [ "zlib" ],
+ "comp" => [ "zlib", "brotli", "zstd" ],
"sm3" => [ "sm2" ],
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
"cmp" => [ "crmf" ],
- "fips" => [ "fips-securitychecks" ],
+ "fips" => [ "fips-securitychecks", "acvp-tests" ],
+
+ "threads" => [ "thread-pool" ],
+ "thread-pool" => [ "default-thread-pool" ],
- "deprecated-3.0" => [ "engine", "srp" ]
+ "blake2" => [ "argon2" ],
+
+ "deprecated-3.0" => [ "engine", "srp" ],
+
+ "http" => [ "ocsp" ]
);
# Avoid protocol support holes. Also disable all versions below N, if version
# input, as opposed to the VAR=string option that override the corresponding
# config target attributes
my %useradd = (
+ ASFLAGS => [],
CPPDEFINES => [],
CPPINCLUDES => [],
CPPFLAGS => [],
{
delete $disabled{"zlib"};
}
+ elsif ($1 eq "brotli-dynamic")
+ {
+ delete $disabled{"brotli"};
+ }
+ elsif ($1 eq "zstd-dynamic")
+ {
+ delete $disabled{"zstd"};
+ }
my $algo = $1;
delete $disabled{$algo};
{
$guess_opts{verbose} = 1;
}
- elsif (/^-w$/) # From older 'config'
+ elsif (/^-w$/)
{
$guess_opts{nowait} = 1;
}
if (/^--prefix=(.*)$/)
{
$config{prefix}=$1;
- die "Directory given with --prefix MUST be absolute\n"
- unless file_name_is_absolute($config{prefix});
}
elsif (/^--api=(.*)$/)
{
{
$withargs{zlib_include}=$1;
}
+ elsif (/^--with-brotli-lib=(.*)$/)
+ {
+ $withargs{brotli_lib}=$1;
+ }
+ elsif (/^--with-brotli-include=(.*)$/)
+ {
+ $withargs{brotli_include}=$1;
+ }
+ elsif (/^--with-zstd-lib=(.*)$/)
+ {
+ $withargs{zstd_lib}=$1;
+ }
+ elsif (/^--with-zstd-include=(.*)$/)
+ {
+ $withargs{zstd_include}=$1;
+ }
elsif (/^--with-fuzzer-lib=(.*)$/)
{
$withargs{fuzzer_lib}=$1;
# At this point, we can forget everything about %user and %useradd,
# because it's now all been merged into the corresponding $config entry
+if ($config{prefix} && !$config{CROSS_COMPILE}) {
+ die "Directory given with --prefix MUST be absolute\n"
+ unless file_name_is_absolute($config{prefix});
+}
+
if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) {
disable('static', 'pic', 'threads');
}
my ($builder, $builder_platform, @builder_opts) =
@{$target{build_scheme}};
-foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm",
+foreach my $checker (($builder_platform."-".$config{build_file}."-checker.pm",
$builder_platform."-checker.pm")) {
my $checker_path = catfile($srcdir, "Configurations", $checker);
if (-f $checker_path) {
}
if ($target =~ /linux.*-mips/ && !$disabled{asm}
- && !grep { $_ !~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) {
+ && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) {
# minimally required architecture flags for assembly modules
my $value;
$value = '-mips2' if ($target =~ /mips32/);
push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
}
+if ($disabled{"unstable-qlog"}) {
+ $disabled{"qlog"} = 1;
+}
+
my $no_shared_warn=0;
if (($target{shared_target} // '') eq "")
{
}
unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) {
- # -DPEDANTIC or -fnosanitize=alignment may also be required on some
- # platforms.
- push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all";
+ push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC";
}
unless ($disabled{msan} || defined $detected_sanitizers{msan}) {
unless ($disabled{asm}) {
# big endian systems can use ELFv2 ABI
- if ($target eq "linux-ppc64") {
+ if ($target eq "linux-ppc64" || $target eq "BSD-ppc64") {
$target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2);
}
}
unless ($disabled{afalgeng}) {
$config{afalgeng}="";
if (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
- my $minver = 4*10000 + 1*100 + 0;
- if ($config{CROSS_COMPILE} eq "") {
- my $verstr = `uname -r`;
- my ($ma, $mi1, $mi2) = split("\\.", $verstr);
- ($mi2) = $mi2 =~ /(\d+)/;
- my $ver = $ma*10000 + $mi1*100 + $mi2;
- if ($ver < $minver) {
- disable('too-old-kernel', 'afalgeng');
- } else {
- push @{$config{engdirs}}, "afalg";
- }
- } else {
- disable('cross-compiling', 'afalgeng');
- }
+ push @{$config{engdirs}}, "afalg";
} else {
disable('not-linux', 'afalgeng');
}
unless ($disabled{ktls}) {
$config{ktls}="";
+ my $cc = $config{CROSS_COMPILE}.$config{CC};
if ($target =~ m/^linux/) {
- my $usr = "/usr/$config{cross_compile_prefix}";
- chop($usr);
- if ($config{cross_compile_prefix} eq "") {
- $usr = "/usr";
- }
- my $minver = (4 << 16) + (13 << 8) + 0;
- my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`);
-
- if ($verstr[2] < $minver) {
+ system("printf '#include <sys/types.h>\n#include <linux/tls.h>' | $cc -E - >/dev/null 2>&1");
+ if ($? != 0) {
disable('too-old-kernel', 'ktls');
}
} elsif ($target =~ m/^BSD/) {
- my $cc = $config{CROSS_COMPILE}.$config{CC};
system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1");
if ($? != 0) {
disable('too-old-freebsd', 'ktls');
}
}
+unless ($disabled{winstore}) {
+ unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) {
+ disable('not-windows', 'winstore');
+ }
+}
+
push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
# Get the extra flags used when building shared libraries and modules. We
my %disabled_info = (); # For configdata.pm
foreach my $what (sort keys %disabled) {
# There are deprecated disablables that translate to themselves.
- # They cause disabling cascades, but should otherwise not regiter.
+ # They cause disabling cascades, but should otherwise not register.
next if $deprecated_disablables{$what};
# The generated $disabled{"deprecated-x.y"} entries are special
# and treated properly elsewhere
if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
'module', 'pic', 'dynamic-engine', 'makedepend',
- 'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) {
+ 'sse2', 'legacy' )) {
(my $WHAT = uc $what) =~ s|-|_|g;
my $skipdir = $what;
my $base = shift;
my $dir = shift;
my $relativeto = shift || ".";
+ my $no_mkpath = shift // 0;
$dir = catdir($base,$dir) unless isabsolute($dir);
# Make sure the directories we're building in exists
- mkpath($dir);
+ mkpath($dir) unless $no_mkpath;
my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
#print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
my $base = shift;
my $file = shift;
my $relativeto = shift || ".";
+ my $no_mkpath = shift // 0;
$file = catfile($base,$file) unless isabsolute($file);
my $f = basename($file);
# Make sure the directories we're building in exists
- mkpath($d);
+ mkpath($d) unless $no_mkpath;
my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
#print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
# Store the name of the template file we will build the build file from
# in %config. This may be useful for the build file itself.
my @build_file_template_names =
- ( $builder_platform."-".$target{build_file}.".tmpl",
- $target{build_file}.".tmpl" );
+ ( $builder_platform."-".$config{build_file}.".tmpl",
+ $config{build_file}.".tmpl" );
my @build_file_templates = ();
# First, look in the user provided directory, if given
}
# Then, look in our standard directory
push @build_file_templates,
- ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
+ ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir, 1) }
@build_file_template_names );
my $build_file_template;
}
$config{build_file_templates}
= [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"),
- $blddir),
+ $blddir, 1),
$build_file_template ];
my @build_dirs = ( [ ] ); # current directory
# We want to detect configdata.pm in the source tree, so we
# don't use it if the build tree is different.
- my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir);
+ my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir, 1);
# Any source file that we recognise is placed in this hash table, with
# the list of its intended destinations as value. When everything has
my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/;
my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/;
my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/;
- my $value_re = qr/\s*(?P<VALUE>.*?)\s*/;
+ my $value_re = qr/(?P<VALUE>.*?)/;
collect_information(
collect_from_array([ @text ],
qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
qr/^\s* ENDIF \s*$/x
=> sub { die "ENDIF out of scope" if ! @skip;
pop @skip; },
- qr/^\s* ${variable_re} \s* = ${value_re} $/x
+ qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x
=> sub {
if (!@skip || $skip[$#skip] > 0) {
$variables{$+{VARIABLE}} = $expand_variables->($+{VALUE});
}
},
- qr/^\s* SUBDIRS \s* = ${value_re} $/x
+ qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x
=> sub {
if (!@skip || $skip[$#skip] > 0) {
foreach (tokenize($expand_variables->($+{VALUE}))) {
}
}
},
- qr/^\s* PROGRAMS ${attribs_re} \s* = ${value_re} $/x
+ qr/^\s* PROGRAMS ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\@programs, undef,
\$attributes{programs}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* LIBS ${attribs_re} \s* = ${value_re} $/x
+ qr/^\s* LIBS ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\@libraries, undef,
\$attributes{libraries}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* MODULES ${attribs_re} \s* = ${value_re} $/x
+ qr/^\s* MODULES ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\@modules, undef,
\$attributes{modules}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* SCRIPTS ${attribs_re} \s* = ${value_re} $/x
+ qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\@scripts, undef,
\$attributes{scripts}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* IMAGEDOCS ${index_re} = ${value_re} $/x
+ qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}),
undef, undef,
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* HTMLDOCS ${index_re} = ${value_re} $/x
+ qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}),
undef, undef,
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* MANDOCS ${index_re} = ${value_re} $/x
+ qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}),
undef, undef,
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* SOURCE ${index_re} ${attribs_re} = ${value_re} $/x
+ qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%sources, $expand_variables->($+{INDEX}),
\$attributes{sources}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} = ${value_re} $/x
+ qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}),
\$attributes{sources}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* INCLUDE ${index_re} = ${value_re} $/x
+ qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%includes, $expand_variables->($+{INDEX}),
undef, undef,
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* DEFINE ${index_re} = ${value_re} $/x
+ qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%defines, $expand_variables->($+{INDEX}),
undef, undef,
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* DEPEND ${index_re} ${attribs_re} = ${value_re} $/x
+ qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%depends, $expand_variables->($+{INDEX}),
\$attributes{depends}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
- qr/^\s* GENERATE ${index_re} = ${value_re} $/x
+ qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%generate, $expand_variables->($+{INDEX}),
- undef, undef, $expand_variables->($+{VALUE}))
+ \$attributes{generate}, $+{ATTRIBS},
+ $expand_variables->($+{VALUE}))
if !@skip || $skip[$#skip] > 0; },
qr/^\s* (?:\#.*)? $/x => sub { },
"OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
my $dest = $_;
my $ddest = cleanfile($buildd, $_, $blddir);
foreach (@{$sources{$dest}}) {
- my $s = cleanfile($sourced, $_, $blddir);
+ my $s = cleanfile($sourced, $_, $blddir, 1);
# If it's generated or we simply don't find it in the source
# tree, we assume it's in the build tree.
my $dest = $_;
my $ddest = cleanfile($buildd, $_, $blddir);
foreach (@{$shared_sources{$dest}}) {
- my $s = cleanfile($sourced, $_, $blddir);
+ my $s = cleanfile($sourced, $_, $blddir, 1);
# If it's generated or we simply don't find it in the source
# tree, we assume it's in the build tree.
if scalar @{$generate{$_}} > 1;
my @generator = split /\s+/, $generate{$dest}->[0];
my $gen = $generator[0];
- $generator[0] = cleanfile($sourced, $gen, $blddir);
+ $generator[0] = cleanfile($sourced, $gen, $blddir, 1);
# If the generator is itself generated, it's in the build tree
if ($generate{$gen} || ! -f $generator[0]) {
$check_generate{$ddest}->{$generator[0]}++;
$unified_info{generate}->{$ddest} = [ @generator ];
+ # Fix up associated attributes
+ $unified_info{attributes}->{generate}->{$ddest} =
+ $attributes{generate}->{$dest}->{$gen}
+ if defined $attributes{generate}->{$dest}->{$gen};
}
foreach (keys %depends) {
} elsif ($dest eq '') {
$ddest = '';
} else {
- $ddest = cleanfile($sourced, $_, $blddir);
+ $ddest = cleanfile($sourced, $dest, $blddir, 1);
# If the destination doesn't exist in source, it can only be
# a generated file in the build tree.
if ($ddest eq $src_configdata || ! -f $ddest) {
- $ddest = cleanfile($buildd, $_, $blddir);
+ $ddest = cleanfile($buildd, $dest, $blddir);
}
}
- foreach (@{$depends{$dest}}) {
- my $d = cleanfile($sourced, $_, $blddir);
- my $d2 = cleanfile($buildd, $_, $blddir);
+ foreach my $f (@{$depends{$dest}}) {
+ # If the dependency destination is generated, dependencies
+ # may have an extra syntax to separate the intended inclusion
+ # directory from the module to be loaded: a | instead of a
+ # / as directory separator.
+ # Do note that this has to be handled in the build file
+ # template as well.
+ # $i = inclusion path in source directory
+ # $i2 = inclusion path in build directory
+ # $m = module path (within the inclusion path)
+ # $i = full module path in source directory
+ # $i2 = full module path in build directory
+ my $i; my $i2; my $m; my $d; my $d2;
+ if ($unified_info{generate}->{$ddest}
+ && $f =~ m/^(.*?)\|(.*)$/) {
+ $i = $1;
+ $m = $2;
+ # We must be very careful to modify $i last
+ $d = cleanfile($sourced, "$i/$m", $blddir, 1);
+ $d2 = cleanfile($buildd, "$i/$m", $blddir);
+ $i2 = cleandir($buildd, $i, $blddir);
+ $i = cleandir($sourced, $i, $blddir, 1);
+ } else {
+ $d = cleanfile($sourced, $f, $blddir, 1);
+ $d2 = cleanfile($buildd, $f, $blddir);
+ }
# If we know it's generated, or assume it is because we can't
# find it in the source tree, we set file we depend on to be
keys %{$unified_info{generate}})
|| ! -f $d) {
$d = $d2;
+ $i = $i2;
+ }
+ if ($i) {
+ # Put together the computed inclusion dir with the
+ # original module name. Do note that we conserve the
+ # Unixly path syntax for the module path.
+ $d = "$i|$m";
}
$unified_info{depends}->{$ddest}->{$d} = 1;
# Fix up associated attributes
$unified_info{attributes}->{depends}->{$ddest}->{$d} =
- $attributes{depends}->{$dest}->{$_}
- if defined $attributes{depends}->{$dest}->{$_};
+ $attributes{depends}->{$dest}->{$f}
+ if defined $attributes{depends}->{$dest}->{$f};
}
}
foreach (keys %includes) {
my $dest = $_;
- my $ddest = cleanfile($sourced, $_, $blddir);
+ my $ddest = cleanfile($sourced, $_, $blddir, 1);
# If the destination doesn't exist in source, it can only be
# a generated file in the build tree.
$ddest = cleanfile($buildd, $_, $blddir);
}
foreach (@{$includes{$dest}}) {
- my $is = cleandir($sourced, $_, $blddir);
+ my $is = cleandir($sourced, $_, $blddir, 1);
my $ib = cleandir($buildd, $_, $blddir);
push @{$unified_info{includes}->{$ddest}->{source}}, $is
unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
my $ddest;
if ($dest ne "") {
- $ddest = cleanfile($sourced, $dest, $blddir);
+ $ddest = cleanfile($sourced, $dest, $blddir, 1);
# If the destination doesn't exist in source, it can only
# be a generated file in the build tree.
next if $dest eq "";
foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
next unless $d =~ /\.(h|pm)$/;
- my $i = dirname($d);
+ # Take into account when a dependency uses the inclusion|module
+ # syntax
+ my $i = $d =~ m/\|/ ? $` : dirname($d);
my $spot =
$d eq "configdata.pm" || defined($unified_info{generate}->{$d})
? 'build' : 'source';
keys %{$unified_info{htmldocs} // {}}),
(map { @{$unified_info{mandocs}->{$_} // []} }
keys %{$unified_info{mandocs} // {}}) ] );
- foreach my $type (keys %loopinfo) {
+ foreach my $type (sort keys %loopinfo) {
foreach my $product (@{$loopinfo{$type}}) {
my %dirs = ();
my $pd = dirname($product);
push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
if $d ne $pd;
}
- foreach (keys %dirs) {
+ foreach (sort keys %dirs) {
push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
$product;
}
user_crossable => \@user_crossable,
);
my $configdata_outname = 'configdata.pm';
-print "Creating $configdata_outname\n";
open CONFIGDATA, ">$configdata_outname.new"
or die "Trying to create $configdata_outname.new: $!";
-my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir);
+my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir, 1);
my $configdata_tmpl =
OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname);
$configdata_tmpl->fill_in(
] }
) or die $Text::Template::ERROR;
close CONFIGDATA;
+
rename "$configdata_outname.new", $configdata_outname;
if ($builder_platform eq 'unix') {
my $mode = (0755 & ~umask);
chmod $mode, 'configdata.pm'
or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!);
}
+print "Created $configdata_outname\n";
print "Running $configdata_outname\n";
my $perlcmd = (quotify("maybeshell", $config{PERL}))[0];
#
sub death_handler {
die @_ if $^S; # To prevent the added message in eval blocks
- my $build_file = $target{build_file} // "build file";
+ my $build_file = $config{build_file} // "build file";
my @message = ( <<"_____", @_ );
Failure! $build_file wasn't produced.
}
}
- foreach (sort keys %all_keys) {
- my $previous = $combined_inheritance{$_};
+ foreach my $key (sort keys %all_keys) {
+ my $previous = $combined_inheritance{$key};
# Current target doesn't have a value for the current key?
# Assign it the default combiner, the rest of this loop body
# will handle it just like any other coderef.
- if (!exists $table{$target}->{$_}) {
- $table{$target}->{$_} = $default_combiner;
+ if (!exists $table{$target}->{$key}) {
+ $table{$target}->{$key} = $default_combiner;
}
- $table{$target}->{$_} = process_values($table{$target}->{$_},
- $combined_inheritance{$_},
- $target, $_);
- unless(defined($table{$target}->{$_})) {
- delete $table{$target}->{$_};
+ $table{$target}->{$key} = process_values($table{$target}->{$key},
+ $combined_inheritance{$key},
+ $target, $key);
+ unless(defined($table{$target}->{$key})) {
+ delete $table{$target}->{$key};
}
# if ($extra_checks &&
-# $previous && !($add_called || $previous ~~ $table{$target}->{$_})) {
-# warn "$_ got replaced in $target\n";
+# $previous && !($add_called || $previous ~~ $table{$target}->{$key})) {
+# warn "$key got replaced in $target\n";
# }
}