#! /usr/bin/env perl
# -*- mode: perl; -*-
-# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2021 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
# 386 generate 80386 code in assembly modules
# no-sse2 disables IA-32 SSE2 code in assembly modules, the above
# mentioned '386' option implies this one
-# no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
+# no-<cipher> build without specified algorithm (dsa, idea, rc5, ...)
# -<xxx> +<xxx> All options which are unknown to the 'Configure' script are
# /<xxx> passed through to the compiler. Unix-style options beginning
# with a '-' or '+' are recognized, as well as Windows-style
# The numbering used changes from 3.0 and on because we updated
# (solidified) our version numbering scheme at that point.
- # From 3.0 and on, we internalise the given version number in dedcimal
+ # From 3.0 and on, we internalise the given version number in decimal
# as MAJOR * 10000 + MINOR * 100 + 0
"3.0.0" => 30000,
"3.0" => 30000,
# Unified build supports separate build dir
my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
+
+# File::Spec::Unix doesn't detect case insensitivity, so we make sure to
+# check if the source and build directory are really the same, and make
+# them so. This avoids all kinds of confusion later on.
+# We must check @File::Spec::ISA rather than using File::Spec->isa() to
+# know if File::Spec ended up loading File::Spec::Unix.
+$srcdir = $blddir
+ if (grep(/::Unix$/, @File::Spec::ISA)
+ && samedir($srcdir, $blddir));
+
my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
-$config{sourcedir} = abs2rel($srcdir);
-$config{builddir} = abs2rel($blddir);
+$config{sourcedir} = abs2rel($srcdir, $blddir);
+$config{builddir} = abs2rel($blddir, $blddir);
+# echo -n 'holy hand grenade of antioch' | openssl sha256
+$config{FIPSKEY} =
+ 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
# Collect reconfiguration information if needed
my @argvcopy=@ARGV;
# 'unshift' adds at the front of the list (i.e. in reverse input order).
foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh',
'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2',
- 'rc2', 'rc4', 'rc5', 'ripemd', 'rsa', 'seed', 'sha',
+ 'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha',
'sm2', 'sm3', 'sm4') ) {
unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_);
}
my %version = ();
collect_information(
- collect_from_file(catfile($srcdir,'VERSION')),
+ collect_from_file(catfile($srcdir,'VERSION.dat')),
qr/\s*(\w+)\s*=\s*(.*?)\s*$/ =>
sub {
# Only define it if there is a value at all
}
},
"OTHERWISE" =>
- sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION" },
+ sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" },
);
$config{major} = $version{MAJOR} // 'unknown';
$config{version} = "$config{major}.$config{minor}.$config{patch}";
$config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
-die "erroneous version information in VERSION: ",
+die "erroneous version information in VERSION.dat: ",
"$config{version}, $config{shlib_version}\n"
unless (defined $version{MAJOR}
&& defined $version{MINOR}
"bf",
"blake2",
"buildtest-c++",
+ "bulk",
+ "cached-fetch",
"camellia",
"capieng",
"cast",
"external-tests",
"filenames",
"fips",
+ "fips-securitychecks",
"fuzz-libfuzzer",
"fuzz-afl",
"gost",
# 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",
+ "blake2", "bf", "camellia", "cast", "chacha",
+ "cmac", "cms", "cmp", "comp", "ct",
+ "des", "dgram", "dh", "dsa",
+ "ec", "engine",
+ "filenames",
+ "idea", "ktls",
+ "md4", "multiblock", "nextprotoneg",
+ "ocsp", "ocb", "poly1305", "psk",
+ "rc2", "rc4", "rmd160",
+ "seed", "siphash", "siv",
+ "sm3", "sm4", "srp",
+ "srtp", "ssl3-method",
+ "ts", "ui-console", "whirlpool",
+ "fips-securitychecks" ],
sub { $config{processor} eq "386" }
=> [ "sse2" ],
"ssl" => [ "ssl3" ],
"ssl3-method" => [ "ssl3" ],
"zlib" => [ "zlib-dynamic" ],
"des" => [ "mdc2" ],
- "ec" => [ "ecdsa", "ecdh", "sm2", "gost" ],
- sub { $disabled{"ec"} && $disabled{"dh"} }
- => [ "tls1_3" ],
+ "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ],
"dgram" => [ "dtls", "sctp" ],
"sock" => [ "dgram" ],
"dtls" => [ @dtls ],
# or modules.
"pic" => [ "shared", "module" ],
- "module" => [ "fips" ],
+ "module" => [ "fips", "dso" ],
- "engine" => [ grep /eng$/, @disablables ],
+ "engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ],
"hw" => [ "padlockeng" ],
# no-autoalginit is only useful when building non-shared
sub { !$disabled{"msan"} } => [ "asm" ],
- sub { $disabled{cmac}; } => [ "siv" ],
- "legacy" => [ "md2" ],
+ "cmac" => [ "siv" ],
+ "legacy" => [ "md2" ],
"cmp" => [ "crmf" ],
- # Padlock engine uses low-level AES APIs which are deprecated
- sub { $disabled{"deprecated-3.0"} }
- => [ "padlockeng" ]
+ "deprecated-3.0" => [ "engine", "srp" ]
);
# Avoid protocol support holes. Also disable all versions below N, if version
push @seed_sources, $x;
}
}
+ elsif (/^--fips-key=(.*)$/)
+ {
+ $user{FIPSKEY}=lc($1);
+ die "Non-hex character in FIPS key\n"
+ if $user{FIPSKEY} =~ /[^a-f0-9]/;
+ die "FIPS key must have even number of characters\n"
+ if length $1 & 1;
+ die "FIPS key too long (64 bytes max)\n"
+ if length $1 > 64;
+ }
elsif (/^--cross-compile-prefix=(.*)$/)
{
$user{CROSS_COMPILE}=$1;
}
my $no_shared_warn=0;
-if ($target{shared_target} eq "")
+if (($target{shared_target} // '') eq "")
{
$no_shared_warn = 1
if (!$disabled{shared} || !$disabled{"dynamic-engine"});
$config{build_infos} = [ ];
+ # We want to detect configdata.pm in the source tree, so we
+ # don't use it if the build tree is different.
+ my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir);
+
+ # Any source file that we recognise is placed in this hash table, with
+ # the list of its intended destinations as value. When everything has
+ # been collected, there's a routine that checks that these source files
+ # exist, or if they are generated, that the generator exists.
+ my %check_exist = ();
+ my %check_generate = ();
+
my %ordinals = ();
while (@build_dirs) {
my @curd = @{shift @build_dirs};
my $ac = 1;
my $ak = $a;
my $av = 1;
- if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|) {
+ if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) {
$ac = ! $1;
- $ak = $1;
- $av = $2;
+ $ak = $2;
+ $av = $3;
}
foreach my $g (@goals) {
if ($ac) {
}
};
- # 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);
-
-
if ($buildinfo_debug) {
print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n";
}
}
# We recognise C++, C and asm files
if ($s =~ /\.(cc|cpp|c|s|S)$/) {
+ push @{$check_exist{$s}}, $ddest;
my $o = $_;
$o =~ s/\.[csS]$/.o/; # C and assembler
$o =~ s/\.(cc|cpp)$/_cc.o/; # C++
$unified_info{sources}->{$o}->{$s} = -1;
} elsif ($s =~ /\.rc$/) {
# We also recognise resource files
+ push @{$check_exist{$s}}, $ddest;
my $o = $_;
$o =~ s/\.rc$/.res/; # Resource configuration
- my $o = cleanfile($buildd, $o, $blddir);
+ $o = cleanfile($buildd, $o, $blddir);
$unified_info{sources}->{$ddest}->{$o} = -1;
$unified_info{sources}->{$o}->{$s} = -1;
} else {
+ push @{$check_exist{$s}}, $ddest;
$unified_info{sources}->{$ddest}->{$s} = 1;
}
}
if ($s =~ /\.(cc|cpp|c|s|S)$/) {
# We recognise C++, C and asm files
+ push @{$check_exist{$s}}, $ddest;
my $o = $_;
$o =~ s/\.[csS]$/.o/; # C and assembler
$o =~ s/\.(cc|cpp)$/_cc.o/; # C++
$unified_info{sources}->{$o}->{$s} = -1;
} elsif ($s =~ /\.rc$/) {
# We also recognise resource files
+ push @{$check_exist{$s}}, $ddest;
my $o = $_;
$o =~ s/\.rc$/.res/; # Resource configuration
- my $o = cleanfile($buildd, $o, $blddir);
+ $o = cleanfile($buildd, $o, $blddir);
$unified_info{shared_sources}->{$ddest}->{$o} = -1;
$unified_info{sources}->{$o}->{$s} = -1;
} elsif ($s =~ /\.ld$/) {
# We also recognise linker scripts (or corresponding)
# We know they are generated files
+ push @{$check_exist{$s}}, $ddest;
my $ld = cleanfile($buildd, $_, $blddir);
$unified_info{shared_sources}->{$ddest}->{$ld} = 1;
} else {
if ($generate{$gen}) {
$generator[0] = cleanfile($buildd, $gen, $blddir);
}
+ $check_generate{$ddest}->{$generator[0]}++;
$unified_info{generate}->{$ddest} = [ @generator ];
}
DEPEND and SHARED_SOURCE.
EOF
+ # Check that each generated file is only generated once
+ my $ambiguous_generation = 0;
+ foreach (sort keys %check_generate) {
+ my @generators = sort keys %{$check_generate{$_}};
+ my $generators_txt = join(', ', @generators);
+ if (scalar @generators > 1) {
+ warn "$_ is GENERATEd by more than one generator ($generators_txt)\n";
+ $ambiguous_generation++;
+ }
+ if ($check_generate{$_}->{$generators[0]} > 1) {
+ warn "INFO: $_ has more than one GENERATE declaration (same generator)\n"
+ }
+ }
+ die "There are ambiguous source file generations\n"
+ if $ambiguous_generation > 0;
+
+ # All given source files should exist, or if generated, their
+ # generator should exist. This loop ensures this is true.
+ my $missing = 0;
+ foreach my $orig (sort keys %check_exist) {
+ foreach my $dest (@{$check_exist{$orig}}) {
+ if ($orig ne $src_configdata) {
+ if ($orig =~ /\.a$/) {
+ # Static library names may be used as sources, so we
+ # need to detect those and give them special treatment.
+ unless (grep { $_ eq $orig }
+ keys %{$unified_info{libraries}}) {
+ warn "$orig is given as source for $dest, but no such library is built\n";
+ $missing++;
+ }
+ } else {
+ # A source may be generated, and its generator may be
+ # generated as well. We therefore loop to dig out the
+ # first generator.
+ my $gen = $orig;
+
+ while (my @next = keys %{$check_generate{$gen}}) {
+ $gen = $next[0];
+ }
+
+ if (! -f $gen) {
+ if ($gen ne $orig) {
+ $missing++;
+ warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n";
+ } else {
+ $missing++;
+ warn "$orig is given as source for $dest, but is missing\n";
+ }
+ }
+ }
+ }
+ }
+ }
+ die "There are files missing\n" if $missing > 0;
# Go through the sources of all libraries and check that the same basename
# doesn't appear more than once. Some static library archivers depend on
my @message = ( <<"_____", @_ );
Failure! $build_file wasn't produced.
-Please read INSTALL.md and associated NOTES files. You may also have to
+Please read INSTALL.md and associated NOTES-* files. You may also have to
look over your available compiler tool chain or change your configuration.
_____
}
print STDERR $i . " ";
}
- print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
exit(1);
}
"loutflag",
"ex_libs",
"bn_ops",
+ "enable",
+ "disable",
"poly1035_asm_src",
"thread_scheme",
"perlasm_scheme",
return realpath($dir);
}
+# Check if all paths are one and the same, using stat. They must both exist
+# We need this for the cases when File::Spec doesn't detect case insensitivity
+# (File::Spec::Unix assumes case sensitivity)
+sub samedir {
+ die "samedir expects two arguments\n" unless scalar @_ == 2;
+
+ my @stat0 = stat($_[0]); # First argument
+ my @stat1 = stat($_[1]); # Second argument
+
+ die "Couldn't stat $_[0]" unless @stat0;
+ die "Couldn't stat $_[1]" unless @stat1;
+
+ # Compare device number
+ return 0 unless ($stat0[0] == $stat1[0]);
+ # Compare "inode". The perl manual recommends comparing as
+ # string rather than as number.
+ return 0 unless ($stat0[1] eq $stat1[1]);
+
+ return 1; # All the same
+}
+
sub quotify {
my %processors = (
perl => sub { my $x = shift;