# -*- mode: perl; -*-
# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# 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
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
use FindBin;
use lib "$FindBin::Bin/util/perl";
use File::Basename;
-use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
+use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs splitdir/;
use File::Path qw/mkpath/;
use OpenSSL::Glob;
#
# --cross-compile-prefix Add specified prefix to binutils components.
#
-# --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for
-# interfaces deprecated as of the specified OpenSSL version.
+# --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0.0 / 3.
+# Do not compile support for interfaces deprecated as of the
+# specified OpenSSL version.
#
# no-hw-xxx do not compile support for specific crypto hardware.
# Generic OpenSSL-style methods relating to this support
# -Wlanguage-extension-token -- no, we use asm()
# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
# -Wextended-offsetof -- no, needed in CMS ASN1 code
+# -Wunused-function -- no, it forces header use of safestack et al
+# DEFINE macros
my $clang_devteam_warn = ""
. " -Wswitch-default"
. " -Wno-parentheses-equality"
. " -Wincompatible-pointer-types-discards-qualifiers"
. " -Wmissing-variable-declarations"
. " -Wno-unknown-warning-option"
+ . " -Wno-unused-function"
;
# This adds backtrace information to the memory leak info. Is only used
#
# API compatibility name to version number mapping.
#
-my $maxapi = "1.1.0"; # API for "no-deprecated" builds
+my $maxapi = "3.0.0"; # API for "no-deprecated" builds
my $apitable = {
- "1.1.0" => "0x10100000L",
- "1.0.0" => "0x10000000L",
- "0.9.8" => "0x00908000L",
+ "3.0.0" => 3,
+ "1.1.1" => 2,
+ "1.1.0" => 2,
+ "1.0.2" => 1,
+ "1.0.1" => 1,
+ "1.0.0" => 1,
+ "0.9.8" => 0,
};
our %table = ();
$config{perlargv} = [ @argvcopy ];
# Collect version numbers
-$config{version} = "unknown";
-$config{version_num} = "unknown";
-$config{shlib_version_number} = "unknown";
-$config{shlib_version_history} = "unknown";
+$config{major} = "unknown";
+$config{minor} = "unknown";
+$config{patch} = "unknown";
+$config{prerelease} = "";
+$config{build_metadata} = "";
+$config{shlib_version} = "unknown";
collect_information(
collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
- qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
- qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 },
- qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 },
- qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 }
+ qr/#\s+define\s+OPENSSL_VERSION_MAJOR\s+(\d+)/ =>
+ sub { $config{major} = $1; },
+ qr/#\s+define\s+OPENSSL_VERSION_MINOR\s+(\d+)/ =>
+ sub { $config{minor} = $1; },
+ qr/#\s+define\s+OPENSSL_VERSION_PATCH\s+(\d+)/ =>
+ sub { $config{patch} = $1; },
+ qr/#\s+define\s+OPENSSL_VERSION_PRE_RELEASE\s+"((?:\\.|[^"])*)"/ =>
+ sub { $config{prerelease} = $1; },
+ qr/#\s+define\s+OPENSSL_VERSION_BUILD_METADATA\s+"((?:\\.|[^"])*)"/ =>
+ sub { $config{build_metadata} = $1; },
+ qr/#\s+define\s+OPENSSL_SHLIB_VERSION\s+([\d\.]+)/ =>
+ sub { $config{shlib_version} = $1; },
);
-if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
-
-($config{major}, $config{minor})
- = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
-($config{shlib_major}, $config{shlib_minor})
- = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
die "erroneous version information in opensslv.h: ",
- "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
- if ($config{major} eq "" || $config{minor} eq ""
- || $config{shlib_major} eq "" || $config{shlib_minor} eq "");
+ "$config{major}.$config{minor}.$config{patch}, $config{shlib_version}\n"
+ if ($config{major} eq "unknown"
+ || $config{minor} eq "unknown"
+ || $config{patch} eq "unknown"
+ || $config{shlib_version} eq "unknown");
+
+$config{version} = "$config{major}.$config{minor}.$config{patch}";
+$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
# Collect target configurations
my $auto_threads=1; # enable threads automatically? true by default
my $default_ranlib;
-# Top level directories to build
-$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
-# crypto/ subdirectories to build
-$config{sdirs} = [
- "objects",
- "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3",
- "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes",
- "bn", "ec", "rsa", "dsa", "dh", "sm2", "dso", "engine",
- "buffer", "bio", "stack", "lhash", "rand", "err",
- "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
- "cms", "ts", "srp", "gmac", "cmac", "ct", "async", "kdf", "store"
- ];
-# test/ subdirectories to build
-$config{tdirs} = [ "ossl_shim" ];
-
# Known TLS and DTLS protocols
my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
my @dtls = qw(dtls1 dtls1_2);
# For developers: keep it sorted alphabetically
my @disablables = (
+ "ktls",
"afalgeng",
"aria",
"asan",
"msan",
"multiblock",
"nextprotoneg",
+ "pinshared",
"ocb",
"ocsp",
"pic",
"seed",
"shared",
"siphash",
+ "siv",
"sm2",
"sm3",
"sm4",
"weak-ssl-ciphers" => "default",
"zlib" => "default",
"zlib-dynamic" => "default",
+ "ktls" => "default",
);
# Note: => pair form used for aesthetics, not to truly make a hash table
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
sub { !$disabled{"msan"} } => [ "asm" ],
+
+ sub { $disabled{cmac}; } => [ "siv" ],
);
# Avoid protocol support holes. Also disable all versions below N, if version
$config{ex_libs} = [ env('__CNF_LDLIBS') || () ];
$config{openssl_api_defines}=[];
-$config{openssl_algorithm_defines}=[];
-$config{openssl_thread_defines}=[];
$config{openssl_sys_defines}=[];
-$config{openssl_other_defines}=[];
+$config{openssl_feature_defines}=[];
$config{options}="";
$config{build_type} = "release";
my $target="";
}
elsif (/^--strict-warnings$/)
{
- $strict_warnings = 1;
+ # Pretend that our strict flags is a C flag, and replace it
+ # with the proper flags later on
+ push @{$useradd{CFLAGS}}, '--ossl-strict-warnings';
+ push @{$useradd{CXXFLAGS}}, '--ossl-strict-warnings';
+ $strict_warnings=1;
}
elsif (/^--debug$/)
{
exit 0;
}
-print "Configuring OpenSSL version $config{version} ($config{version_num}) ";
-print "for $target\n";
+print "Configuring OpenSSL version $config{full_version} ";
+print "for target $target\n";
if (scalar(@seed_sources) == 0) {
print "Using os-specific seed configuration\n";
_____
}
-push @{$config{openssl_other_defines}},
+push @{$config{openssl_feature_defines}},
map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
@seed_sources;
$disabled{$feature} = 'config';
}
foreach my $feature (@{$target{enable}}) {
- if ("default" eq ($disabled{$_} // "")) {
+ if ("default" eq ($disabled{$feature} // "")) {
if (exists $deprecated_disablables{$feature}) {
warn "***** config $target enables deprecated feature $feature\n";
} elsif (!grep { $feature eq $_ } @disablables) {
die "***** config $target enables unknown feature $feature\n";
}
- delete $disabled{$_};
+ delete $disabled{$feature};
}
}
$target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX};
$target{cxxflags}//=$target{cflags} if $target{CXX};
-$target{exe_extension}="";
-$target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
- || $config{target} =~ /^(?:Cygwin|mingw)/);
+$target{exe_extension}=".exe" if ($config{target} eq "DJGPP");
$target{exe_extension}=".pm" if ($config{target} =~ /vos/);
-$target{def_extension}=".ld";
-$target{def_extension}=".def" if $config{target} =~ /^mingw|VC-/;
-$target{def_extension}=".opt" if $config{target} =~ /^vms/;
-($target{shared_extension_simple}=$target{shared_extension})
- =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||
- unless defined($target{shared_extension_simple});
-$target{dso_extension}//=$target{shared_extension_simple};
-($target{shared_import_extension}=$target{shared_extension_simple}.".a")
- if ($config{target} =~ /^(?:Cygwin|mingw)/);
# Fill %config with values from %user, and in case those are undefined or
# empty, use values from %target (acting as a default).
# Allow overriding the build file name
$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
+######################################################################
+# Build up information for skipping certain directories depending on disabled
+# features, as well as setting up macros for disabled features.
+
+# This is a tentative database of directories to skip. Some entries may not
+# correspond to anything real, but that's ok, they will simply be ignored.
+# The actual processing of these entries is done in the build.info lookup
+# loop further down.
+#
+# The key is a Unix formated path in the source tree, the value is an index
+# into %disabled_info, so any existing path gets added to a corresponding
+# 'skipped' entry in there with the list of skipped directories.
+my %skipdir = ();
my %disabled_info = (); # For configdata.pm
foreach my $what (sort keys %disabled) {
$config{options} .= " no-$what";
'dynamic-engine', 'makedepend',
'zlib-dynamic', 'zlib', 'sse2' )) {
(my $WHAT = uc $what) =~ s|-|_|g;
-
- # Fix up C macro end names
- $WHAT = "RMD160" if $what eq "ripemd";
+ my $skipdir = $what;
# fix-up crypto/directory name(s)
- $what = "ripemd" if $what eq "rmd160";
- $what = "whrlpool" if $what eq "whirlpool";
+ $skipdir = "ripemd" if $what eq "rmd160";
+ $skipdir = "whrlpool" if $what eq "whirlpool";
my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT";
+ push @{$config{openssl_feature_defines}}, $macro;
- if ((grep { $what eq $_ } @{$config{sdirs}})
- && $what ne 'async' && $what ne 'err') {
- @{$config{sdirs}} = grep { $what ne $_} @{$config{sdirs}};
- $disabled_info{$what}->{skipped} = [ catdir('crypto', $what) ];
-
- if ($what ne 'engine') {
- push @{$config{openssl_algorithm_defines}}, $macro;
- } else {
- @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
- push @{$disabled_info{engine}->{skipped}}, catdir('engines');
- push @{$config{openssl_other_defines}}, $macro;
- }
- } else {
- push @{$config{openssl_other_defines}}, $macro;
- }
-
+ $skipdir{engines} = $what if $what eq 'engine';
+ $skipdir{"crypto/$skipdir"} = $what
+ unless $what eq 'async' || $what eq 'err';
}
}
# If threads still aren't disabled, add a C macro to ensure the source
# code knows about it. Any other flag is taken care of by the configs.
unless($disabled{threads}) {
- push @{$config{openssl_thread_defines}}, "OPENSSL_THREADS";
+ push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
}
# With "deprecated" disable all deprecated features.
}
if ($disabled{"dynamic-engine"}) {
- push @{$config{openssl_other_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
+ push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
$config{dynamic_engines} = 0;
} else {
- push @{$config{openssl_other_defines}}, "OPENSSL_NO_STATIC_ENGINE";
+ push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE";
$config{dynamic_engines} = 1;
}
push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
push @{$config{lib_defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
+ push @{$config{lib_defines}}, "BN_DIV3W" if ($target{bn_asm_src} =~ /-div3w/);
if ($target{sha1_asm_src}) {
push @{$config{lib_defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
$config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
@{$config{cxxflags}} ] if $config{CXX};
-if (defined($config{api})) {
- $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
- my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
- push @{$config{defines}}, $apiflag;
-}
+$config{openssl_api_defines} = [
+ "OPENSSL_MIN_API=".($apitable->{$config{api} // ""} // -1)
+];
+my @strict_warnings_collection=();
if ($strict_warnings)
{
my $wopt;
die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
unless $gccver >= 4;
- foreach $wopt (split /\s+/, $gcc_devteam_warn)
- {
- push @{$config{cflags}}, $wopt
- unless grep { $_ eq $wopt } @{$config{cflags}};
- push @{$config{cxxflags}}, $wopt
- if ($config{CXX}
- && !grep { $_ eq $wopt } @{$config{cxxflags}});
- }
- if (defined($predefined{__clang__}))
- {
- foreach $wopt (split /\s+/, $clang_devteam_warn)
- {
- push @{$config{cflags}}, $wopt
- unless grep { $_ eq $wopt } @{$config{cflags}};
- push @{$config{cxxflags}}, $wopt
- if ($config{CXX}
- && !grep { $_ eq $wopt } @{$config{cxxflags}});
- }
- }
+ push @strict_warnings_collection, (split /\s+/, $gcc_devteam_warn);
+ push @strict_warnings_collection, (split /\s+/, $clang_devteam_warn)
+ if (defined($predefined{__clang__}));
}
+foreach (qw(CFLAGS CXXFLAGS))
+ {
+ $useradd{$_} = [ map { $_ eq '--ossl-strict-warnings'
+ ? @strict_warnings_collection
+ : ( $_ ) }
+ @{$useradd{$_}} ];
+ }
unless ($disabled{"crypto-mdebug-backtrace"})
{
}
}
-push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
+push @{$config{openssl_feature_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
+
+unless ($disabled{ktls}) {
+ $config{ktls}="";
+ 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) {
+ $disabled{ktls} = "too-old-kernel";
+ }
+ } else {
+ $disabled{ktls} = "not-linux";
+ }
+}
+
+push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
# Finish up %config by appending things the user gave us on the command line
# apart from "make variables"
cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
$blddir) ];
- my @build_infos = ( [ ".", "build.info" ] );
- foreach (@{$config{dirs}}) {
- push @build_infos, [ $_, "build.info" ]
- if (-f catfile($srcdir, $_, "build.info"));
- }
- foreach (@{$config{sdirs}}) {
- push @build_infos, [ catdir("crypto", $_), "build.info" ]
- if (-f catfile($srcdir, "crypto", $_, "build.info"));
- }
- foreach (@{$config{engdirs}}) {
- push @build_infos, [ catdir("engines", $_), "build.info" ]
- if (-f catfile($srcdir, "engines", $_, "build.info"));
- }
- foreach (@{$config{tdirs}}) {
- push @build_infos, [ catdir("test", $_), "build.info" ]
- if (-f catfile($srcdir, "test", $_, "build.info"));
- }
+ my @build_dirs = ( [ ] ); # current directory
$config{build_infos} = [ ];
my %ordinals = ();
- foreach (@build_infos) {
- my $sourced = catdir($srcdir, $_->[0]);
- my $buildd = catdir($blddir, $_->[0]);
+ while (@build_dirs) {
+ my @curd = @{shift @build_dirs};
+ my $sourced = catdir($srcdir, @curd);
+ my $buildd = catdir($blddir, @curd);
+
+ my $unixdir = join('/', @curd);
+ if (exists $skipdir{$unixdir}) {
+ my $what = $skipdir{$unixdir};
+ push @{$disabled_info{$what}->{skipped}}, catdir(@curd);
+ next;
+ }
mkpath($buildd);
- my $f = $_->[1];
+ my $f = 'build.info';
# The basic things we're trying to build
my @programs = ();
- my @programs_install = ();
my @libraries = ();
- my @libraries_install = ();
- my @engines = ();
- my @engines_install = ();
+ my @modules = ();
my @scripts = ();
- my @scripts_install = ();
- my @extra = ();
- my @overrides = ();
- my @intermediates = ();
- my @rawlines = ();
+ my %attributes = ();
my %sources = ();
my %shared_sources = ();
my %includes = ();
my %defines = ();
my %depends = ();
- my %renames = ();
- my %sharednames = ();
my %generate = ();
# We want to detect configdata.pm in the source tree, so we
qr/^\s*ENDIF\s*$/
=> sub { die "ENDIF out of scope" if ! @skip;
pop @skip; },
- qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
+ qr/^\s*SUBDIRS\s*=\s*(.*)\s*$/
=> sub {
if (!@skip || $skip[$#skip] > 0) {
- my $install = $1;
- my @x = tokenize($2);
- push @programs, @x;
- push @programs_install, @x unless $install;
+ foreach (tokenize($1)) {
+ push @build_dirs, [ @curd, splitdir($_, 1) ];
+ }
}
},
- qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
+ qr/^\s*PROGRAMS(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
=> sub {
if (!@skip || $skip[$#skip] > 0) {
- my $install = $1;
- my @x = tokenize($2);
- push @libraries, @x;
- push @libraries_install, @x unless $install;
+ my @a = tokenize($1, qr|\s*,\s*|);
+ my @p = tokenize($2);
+ push @programs, @p;
+ foreach my $a (@a) {
+ my $ak = $a;
+ my $av = 1;
+ if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
+ $ak = $1;
+ $av = $2;
+ }
+ foreach my $p (@p) {
+ $attributes{$p}->{$ak} = $av;
+ }
+ }
}
},
- qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
+ qr/^\s*LIBS(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
=> sub {
if (!@skip || $skip[$#skip] > 0) {
- my $install = $1;
- my @x = tokenize($2);
- push @engines, @x;
- push @engines_install, @x unless $install;
+ my @a = tokenize($1, qr|\s*,\s*|);
+ my @l = tokenize($2);
+ push @libraries, @l;
+ foreach my $a (@a) {
+ my $ak = $a;
+ my $av = 1;
+ if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
+ $ak = $1;
+ $av = $2;
+ }
+ foreach my $l (@l) {
+ $attributes{$l}->{$ak} = $av;
+ }
+ }
}
},
- qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
+ qr/^\s*MODULES(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
=> sub {
if (!@skip || $skip[$#skip] > 0) {
- my $install = $1;
- my @x = tokenize($2);
- push @scripts, @x;
- push @scripts_install, @x unless $install;
+ my @a = tokenize($1, qr|\s*,\s*|);
+ my @m = tokenize($2);
+ push @modules, @m;
+ foreach my $a (@a) {
+ my $ak = $a;
+ my $av = 1;
+ if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
+ $ak = $1;
+ $av = $2;
+ }
+ foreach my $m (@m) {
+ $attributes{$m}->{$ak} = $av;
+ }
+ }
+ }
+ },
+ qr/^\s*SCRIPTS(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
+ => sub {
+ if (!@skip || $skip[$#skip] > 0) {
+ my @a = tokenize($1, qr|\s*,\s*|);
+ my @s = tokenize($2);
+ push @scripts, @s;
+ foreach my $a (@a) {
+ my $ak = $a;
+ my $av = 1;
+ if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
+ $ak = $1;
+ $av = $2;
+ }
+ foreach my $s (@s) {
+ $attributes{$s}->{$ak} = $av;
+ }
+ }
}
},
- qr/^\s*EXTRA\s*=\s*(.*)\s*$/
- => sub { push @extra, tokenize($1)
- if !@skip || $skip[$#skip] > 0 },
- qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
- => sub { push @overrides, tokenize($1)
- if !@skip || $skip[$#skip] > 0 },
qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
=> sub { push @{$ordinals{$1}}, tokenize($2)
qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
=> sub { push @{$generate{$1}}, $2
if !@skip || $skip[$#skip] > 0 },
- qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
- => sub { push @{$renames{$1}}, tokenize($2)
- if !@skip || $skip[$#skip] > 0 },
- qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
- => sub { push @{$sharednames{$1}}, tokenize($2)
- if !@skip || $skip[$#skip] > 0 },
- qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
- => sub {
- my $lineiterator = shift;
- my $target_kind = $1;
- while (defined $lineiterator->()) {
- s|\R$||;
- if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
- die "ENDRAW doesn't match BEGINRAW"
- if $1 ne $target_kind;
- last;
- }
- next if @skip && $skip[$#skip] <= 0;
- push @rawlines, $_
- if ($target_kind eq $target{build_file}
- || $target_kind eq $target{build_file}."(".$builder_platform.")");
- }
- },
qr/^\s*(?:#.*)?$/ => sub { },
"OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
"BEFORE" => sub {
);
die "runaway IF?" if (@skip);
- foreach (keys %renames) {
- die "$_ renamed to more than one thing: "
- ,join(" ", @{$renames{$_}}),"\n"
- if scalar @{$renames{$_}} > 1;
- my $dest = cleanfile($buildd, $_, $blddir);
- my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
- die "$dest renamed to more than one thing: "
- ,$unified_info{rename}->{$dest}, $to
- unless !defined($unified_info{rename}->{$dest})
- or $unified_info{rename}->{$dest} eq $to;
- $unified_info{rename}->{$dest} = $to;
- }
-
- foreach (@programs) {
- my $program = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$program}) {
- $program = $unified_info{rename}->{$program};
- }
- $unified_info{programs}->{$program} = 1;
- }
-
- foreach (@programs_install) {
- my $program = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$program}) {
- $program = $unified_info{rename}->{$program};
- }
- $unified_info{install}->{programs}->{$program} = 1;
- }
-
- foreach (@libraries) {
- my $library = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$library}) {
- $library = $unified_info{rename}->{$library};
- }
- $unified_info{libraries}->{$library} = 1;
- }
-
- foreach (@libraries_install) {
- my $library = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$library}) {
- $library = $unified_info{rename}->{$library};
- }
- $unified_info{install}->{libraries}->{$library} = 1;
- }
-
- die <<"EOF" if scalar @engines and !$config{dynamic_engines};
+ if (grep { defined $attributes{$_}->{engine} } keys %attributes
+ and !$config{dynamic_engines}) {
+ die <<"EOF"
ENGINES can only be used if configured with 'dynamic-engine'.
This is usually a fault in a build.info file.
EOF
- foreach (@engines) {
- my $library = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$library}) {
- $library = $unified_info{rename}->{$library};
- }
- $unified_info{engines}->{$library} = 1;
- }
-
- foreach (@engines_install) {
- my $library = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$library}) {
- $library = $unified_info{rename}->{$library};
- }
- $unified_info{install}->{engines}->{$library} = 1;
- }
-
- foreach (@scripts) {
- my $script = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$script}) {
- $script = $unified_info{rename}->{$script};
- }
- $unified_info{scripts}->{$script} = 1;
}
- foreach (@scripts_install) {
- my $script = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$script}) {
- $script = $unified_info{rename}->{$script};
+ foreach (keys %attributes) {
+ my $dest = $_;
+ my $ddest = cleanfile($buildd, $_, $blddir);
+ foreach (keys %{$attributes{$dest} // {}}) {
+ $unified_info{attributes}->{$ddest}->{$_} =
+ $attributes{$dest}->{$_};
}
- $unified_info{install}->{scripts}->{$script} = 1;
- }
-
- foreach (@extra) {
- my $extra = cleanfile($buildd, $_, $blddir);
- $unified_info{extra}->{$extra} = 1;
- }
-
- foreach (@overrides) {
- my $override = cleanfile($buildd, $_, $blddir);
- $unified_info{overrides}->{$override} = 1;
}
- push @{$unified_info{rawlines}}, @rawlines;
-
- unless ($disabled{shared}) {
- # Check sharednames.
- foreach (keys %sharednames) {
- my $dest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$dest}) {
- $dest = $unified_info{rename}->{$dest};
- }
- die "shared_name for $dest with multiple values: "
- ,join(" ", @{$sharednames{$_}}),"\n"
- if scalar @{$sharednames{$_}} > 1;
- my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
- die "shared_name found for a library $dest that isn't defined\n"
- unless $unified_info{libraries}->{$dest};
- die "shared_name for $dest with multiple values: "
- ,$unified_info{sharednames}->{$dest}, ", ", $to
- unless !defined($unified_info{sharednames}->{$dest})
- or $unified_info{sharednames}->{$dest} eq $to;
- $unified_info{sharednames}->{$dest} = $to;
- }
-
- # Additionally, we set up sharednames for libraries that don't
- # have any, as themselves. Only for libraries that aren't
- # explicitly static.
- foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) {
- if (!defined $unified_info{sharednames}->{$_}) {
- $unified_info{sharednames}->{$_} = $_
+ {
+ my %infos = ( programs => [ @programs ],
+ libraries => [ @libraries ],
+ modules => [ @modules ],
+ scripts => [ @scripts ] );
+ foreach my $k (keys %infos) {
+ foreach (@{$infos{$k}}) {
+ my $item = cleanfile($buildd, $_, $blddir);
+ $unified_info{$k}->{$item} = 1;
}
}
+ }
- # Check that we haven't defined any library as both shared and
- # explicitly static. That is forbidden.
- my @doubles = ();
- foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
- (my $l = $_) =~ s/\.a$//;
- push @doubles, $l if defined $unified_info{sharednames}->{$l};
- }
- die "these libraries are both explicitly static and shared:\n ",
- join(" ", @doubles), "\n"
- if @doubles;
+ # Check that we haven't defined any library as both shared and
+ # explicitly static. That is forbidden.
+ my @doubles = ();
+ foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
+ (my $l = $_) =~ s/\.a$//;
+ push @doubles, $l if defined $unified_info{libraries}->{$l};
}
+ die "these libraries are both explicitly static and shared:\n ",
+ join(" ", @doubles), "\n"
+ if @doubles;
foreach (keys %sources) {
my $dest = $_;
my $ddest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$ddest}) {
- $ddest = $unified_info{rename}->{$ddest};
- }
foreach (@{$sources{$dest}}) {
my $s = cleanfile($sourced, $_, $blddir);
foreach (keys %shared_sources) {
my $dest = $_;
my $ddest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$ddest}) {
- $ddest = $unified_info{rename}->{$ddest};
- }
foreach (@{$shared_sources{$dest}}) {
my $s = cleanfile($sourced, $_, $blddir);
foreach (keys %generate) {
my $dest = $_;
my $ddest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$ddest}) {
- $ddest = $unified_info{rename}->{$ddest};
- }
die "more than one generator for $dest: "
,join(" ", @{$generate{$_}}),"\n"
if scalar @{$generate{$_}} > 1;
# a generated file in the build tree.
if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) {
$ddest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$ddest}) {
- $ddest = $unified_info{rename}->{$ddest};
- }
}
foreach (@{$depends{$dest}}) {
my $d = cleanfile($sourced, $_, $blddir);
# should be added back after treatment.
$d =~ /(\.a)?$/;
my $e = $1 // "";
- $d = $`;
- if ($unified_info{rename}->{$d}) {
- $d = $unified_info{rename}->{$d};
- }
- $d .= $e;
+ $d = $`.$e;
$unified_info{depends}->{$ddest}->{$d} = 1;
}
}
# a generated file in the build tree.
if ($ddest eq $src_configdata || ! -f $ddest) {
$ddest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$ddest}) {
- $ddest = $unified_info{rename}->{$ddest};
- }
}
foreach (@{$includes{$dest}}) {
my $is = cleandir($sourced, $_, $blddir);
if defined($unified_info{$_});
delete $unified_info{$_};
}
- foreach my $prodtype (('programs', 'libraries', 'engines', 'scripts')) {
+ foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) {
# $intent serves multi purposes:
# - give a prefix for the new object files names
# - in the case of libraries, rearrange the object files so static
src => [ 'sources',
'shared_sources' ],
dst => 'shared_sources' } },
- engines => { dso => { src => [ 'sources',
+ modules => { dso => { src => [ 'sources',
'shared_sources' ],
dst => 'shared_sources' } },
scripts => { script => { src => [ 'sources' ],
dst => 'sources' } }
} -> {$prodtype};
foreach my $kind (keys %$intent) {
+ next if ($intent->{$kind}->{dst} eq 'shared_sources'
+ && $disabled{shared});
+
my @src = @{$intent->{$kind}->{src}};
my $dst = $intent->{$kind}->{dst};
my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ };
### Make unified_info a bit more efficient
# One level structures
- foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
+ foreach (("programs", "libraries", "modules", "scripts")) {
$unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
}
# Two level structures
- foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
+ foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) {
foreach my $l2 (sort keys %{$unified_info{$l1}}) {
my @items =
sort
# they end up in where applicable. Then, add build rules for those
# directories
my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ],
- "dso" => [ @{$unified_info{engines}} ],
+ "dso" => [ @{$unified_info{modules}} ],
"bin" => [ @{$unified_info{programs}} ],
"script" => [ @{$unified_info{scripts}} ] );
foreach my $type (keys %loopinfo) {
}
# tokenize($line)
+# tokenize($line,$separator)
# $line is a line of text to split up into tokens
-# returns a list of tokens
+# $separator [optional] is a regular expression that separates the tokens,
+# the default being spaces. Do not use quotes of any kind as separators,
+# that will give undefined results.
+# Returns a list of tokens.
#
-# Tokens are divided by spaces. If the tokens include spaces, they
-# have to be quoted with single or double quotes. Double quotes
-# inside a double quoted token must be escaped. Escaping is done
+# Tokens are divided by separator (spaces by default). If the tokens include
+# the separators, they have to be quoted with single or double quotes.
+# Double quotes inside a double quoted token must be escaped. Escaping is done
# with backslash.
# Basically, the same quoting rules apply for " and ' as in any
# Unix shell.
sub tokenize {
my $line = my $debug_line = shift;
+ my $separator = shift // qr|\s+|;
my @result = ();
- while ($line =~ s|^\s+||, $line ne "") {
+ if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
+ print STDERR "DEBUG[tokenize]: \$separator = $separator\n";
+ }
+
+ while ($line =~ s|^${separator}||, $line ne "") {
my $token = "";
- while ($line ne "" && $line !~ m|^\s|) {
- if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
- $token .= $1;
- $line = $';
- } elsif ($line =~ m/^'([^']*)'/) {
- $token .= $1;
- $line = $';
- } elsif ($line =~ m/^(\S+)/) {
- $token .= $1;
- $line = $';
- }
+ again:
+ $line =~ m/^(.*?)(${separator}|"|'|$)/;
+ $token .= $1;
+ $line = $2.$';
+
+ if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
+ $token .= $1;
+ $line = $';
+ goto again;
+ } elsif ($line =~ m/^'([^']*)'/) {
+ $token .= $1;
+ $line = $';
+ goto again;
}
push @result, $token;
}
if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
- print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
- print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
+ print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
+ print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
}
return @result;
}