#! /usr/bin/env perl
# -*- mode: perl; -*-
-# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
## Configure -- OpenSSL source tree configuration script
-require 5.10.0;
+use 5.10.0;
use strict;
+use FindBin;
+use lib "$FindBin::Bin/util/perl";
use File::Basename;
use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
use File::Path qw/mkpath/;
+use OpenSSL::Glob;
# see INSTALL for instructions.
+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-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
# Options:
# 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.
# sctp include SCTP support
-# 386 generate 80386 code
# enable-weak-ssl-ciphers
-# Enable weak ciphers that are disabled by default. This currently
-# only includes RC4 based ciphers.
-# no-sse2 disables IA-32 SSE2 code, above option implies no-sse2
+# Enable weak ciphers that are disabled by default.
+# 386 generate 80386 code in assembly modules
+# no-sse2 disables IA-32 SSE2 code in assembly modules, the above
+# mentioned '386' option implies this one
# no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
# -<xxx> +<xxx> compiler options are passed through
+# -static while -static is also a pass-through compiler option (and
+# as such is limited to environments where it's actually
+# meaningful), it triggers a number configuration options,
+# namely no-dso, no-pic, no-shared and no-threads. It is
+# argued that the only reason to produce statically linked
+# binaries (and in context it means executables linked with
+# -static flag, and not just executables linked with static
+# libcrypto.a) is to eliminate dependency on specific run-time,
+# a.k.a. libc version. The mentioned config options are meant
+# to achieve just that. Unfortunately on Linux it's impossible
+# to eliminate the dependency completely for openssl executable
+# because of getaddrinfo and gethostbyname calls, which can
+# invoke dynamically loadable library facility anyway to meet
+# the lookup requests. For this reason on Linux statically
+# linked openssl executable has rather debugging value than
+# production quality.
#
# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
# provided to stack calls. Generates unique stack functions for
# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
# Following are set automatically by this script
#
-# MD5_ASM use some extra md5 assember,
-# SHA1_ASM use some extra sha1 assember, must define L_ENDIAN for x86
-# RMD160_ASM use some extra ripemd160 assember,
+# MD5_ASM use some extra md5 assembler,
+# SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86
+# RMD160_ASM use some extra ripemd160 assembler,
# SHA256_ASM sha256_block is implemented in assembler
# SHA512_ASM sha512_block is implemented in assembler
-# AES_ASM ASE_[en|de]crypt is implemented in assembler
+# AES_ASM AES_[en|de]crypt is implemented in assembler
# Minimum warning options... any contributions to OpenSSL should at least get
# past these.
# DEBUG_UNUSED enables __owur (warn unused result) checks.
my $gcc_devteam_warn = "-DDEBUG_UNUSED"
# -DPEDANTIC complements -pedantic and is meant to mask code that
- # is not strictly standard-compliant and/or implementation-specifc,
+ # is not strictly standard-compliant and/or implementation-specific,
# e.g. inline assembly, disregards to alignment requirements, such
# that -pedantic would complain about. Incidentally -DPEDANTIC has
# to be used even in sanitized builds, because sanitizer too is
# but 'long long' type.
. " -DPEDANTIC -pedantic -Wno-long-long"
. " -Wall"
+ . " -Wextra"
+ . " -Wno-unused-parameter"
+ . " -Wno-missing-field-initializers"
. " -Wsign-compare"
. " -Wmissing-prototypes"
. " -Wshadow"
. " -Wformat"
. " -Wtype-limits"
+ . " -Wundef"
. " -Werror"
;
# -Wextended-offsetof -- no, needed in CMS ASN1 code
my $clang_devteam_warn = ""
. " -Qunused-arguments"
- . " -Wextra"
- . " -Wno-unused-parameter"
- . " -Wno-missing-field-initializers"
. " -Wno-language-extension-token"
. " -Wno-extended-offsetof"
. " -Wconditional-uninitialized"
our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
#
-# API compability name to version number mapping.
+# API compatibility name to version number mapping.
#
my $maxapi = "1.1.0"; # API for "no-deprecated" builds
my $apitable = {
# resolve_config(target)
#
-# Resolves all the late evalutations, inheritances and so on for the
+# Resolves all the late evaluations, inheritances and so on for the
# chosen target and any target it inherits from.
sub resolve_config;
my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
+my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
+
$config{sourcedir} = abs2rel($srcdir);
$config{builddir} = abs2rel($blddir);
+# Collect reconfiguration information if needed
+my @argvcopy=@ARGV;
+
+if (grep /^reconf(igure)?$/, @argvcopy) {
+ if (-f "./configdata.pm") {
+ my $file = "./configdata.pm";
+ unless (my $return = do $file) {
+ die "couldn't parse $file: $@" if $@;
+ die "couldn't do $file: $!" unless defined $return;
+ die "couldn't run $file" unless $return;
+ }
+
+ @argvcopy = defined($configdata::config{perlargv}) ?
+ @{$configdata::config{perlargv}} : ();
+ die "Incorrect data to reconfigure, please do a normal configuration\n"
+ if (grep(/^reconf/,@argvcopy));
+ $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
+ if defined($configdata::config{cross_compile_prefix});
+ $ENV{CC} = $configdata::config{cc}
+ if defined($configdata::config{cc});
+ $ENV{BUILDFILE} = $configdata::config{build_file}
+ if defined($configdata::config{build_file});
+ $ENV{$local_config_envname} = $configdata::config{local_config_dir}
+ if defined($configdata::config{local_config_dir});
+
+ print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
+ print " CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
+ if $ENV{CROSS_COMPILE};
+ print " CC = ",$ENV{CC},"\n" if $ENV{CC};
+ print " BUILDFILE = ",$ENV{BUILDFILE},"\n" if $ENV{BUILDFILE};
+ print " $local_config_envname = ",$ENV{$local_config_envname},"\n"
+ if $ENV{$local_config_envname};
+ } else {
+ die "Insufficient data to reconfigure, please do a normal configuration\n";
+ }
+}
+
+$config{perlargv} = [ @argvcopy ];
+
# Collect version numbers
$config{version} = "unknown";
$config{version_num} = "unknown";
# Collect target configurations
my $pattern = catfile(dirname($0), "Configurations", "*.conf");
-foreach (sort glob($pattern) ) {
+foreach (sort glob($pattern)) {
&read_config($_);
}
+if (defined $ENV{$local_config_envname}) {
+ if ($^O eq 'VMS') {
+ # VMS environment variables are logical names,
+ # which can be used as is
+ $pattern = $local_config_envname . ':' . '*.conf';
+ } else {
+ $pattern = catfile($ENV{$local_config_envname}, '*.conf');
+ }
+
+ foreach (sort glob($pattern)) {
+ &read_config($_);
+ }
+}
-print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n";
+
+print "Configuring OpenSSL version $config{version} ($config{version_num})\n";
$config{prefix}="";
$config{openssldir}="";
$config{fips}=0;
# Top level directories to build
-$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools" ];
+$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
# crypto/ subdirectories to build
$config{sdirs} = [
"objects",
my @tls = qw(ssl3 tls1 tls1_1 tls1_2);
my @dtls = qw(dtls1 dtls1_2);
-# Explicitelly known options that are possible to disable. They can
+# Explicitly known options that are possible to disable. They can
# be regexps, and will be used like this: /^no-${option}$/
# For developers: keep it sorted alphabetically
my @disablables = (
"afalgeng",
+ "asan",
"asm",
"async",
"autoalginit",
"engine",
"err",
"filenames",
+ "fuzz-libfuzzer",
+ "fuzz-afl",
"gost",
"heartbeats",
"hw(-.+)?",
"md2",
"md4",
"mdc2",
+ "msan",
"multiblock",
"nextprotoneg",
"ocb",
"rc5",
"rdrand",
"rfc3779",
- "ripemd",
"rmd160",
"scrypt",
- "sct",
"sctp",
"seed",
"shared",
"threads",
"tls",
"ts",
+ "ubsan",
"ui",
"unit-test",
"whirlpool",
push(@disablables, "$proto-method");
}
-my @deprecated_disablables = (
- "ssl2",
+my %deprecated_disablables = (
+ "ssl2" => undef,
+ "buf-freelists" => undef,
+ "ripemd" => "rmd160"
);
# All of the following is disabled by default (RC5 was enabled before 0.9.8):
our %disabled = ( # "what" => "comment"
+ "asan" => "default",
+ "crypto-mdebug" => "default",
+ "crypto-mdebug-backtrace" => "default",
"ec_nistp_64_gcc_128" => "default",
"egd" => "default",
+ "fuzz-libfuzzer" => "default",
+ "fuzz-afl" => "default",
+ "heartbeats" => "default",
"md2" => "default",
+ "msan" => "default",
"rc5" => "default",
"sctp" => "default",
"ssl-trace" => "default",
"ssl3" => "default",
"ssl3-method" => "default",
+ "ubsan" => "default",
"unit-test" => "default",
"weak-ssl-ciphers" => "default",
"zlib" => "default",
"zlib-dynamic" => "default",
- "crypto-mdebug" => "default",
- "heartbeats" => "default",
);
# Note: => pair form used for aesthetics, not to truly make a hash table
"dgram" => [ "dtls", "sctp" ],
"sock" => [ "dgram" ],
"dtls" => [ @dtls ],
-
- # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
- "md5" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
- "sha" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
-
- # Additionally, SSL 3.0 requires either RSA or DSA+DH
- sub { $disabled{rsa}
- && ($disabled{dsa} || $disabled{dh}); }
- => [ "ssl" ],
-
- # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
- # or ECDSA + ECDH. (D)TLS 1.2 has this requirement as well.
- # (XXX: We don't support PSK-only builds).
- sub { $disabled{rsa}
- && ($disabled{dsa} || $disabled{dh})
- && ($disabled{ecdsa} || $disabled{ecdh}); }
- => [ "tls1", "tls1_1", "tls1_2",
- "dtls1", "dtls1_2" ],
+ sub { 0 == scalar grep { !$disabled{$_} } @dtls }
+ => [ "dtls" ],
"tls" => [ @tls ],
-
- # SRP and HEARTBEATS require TLSEXT
- "tlsext" => [ "srp", "heartbeats" ],
+ sub { 0 == scalar grep { !$disabled{$_} } @tls }
+ => [ "tls" ],
"crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
# no-autoalginit is only useful when building non-shared
"autoalginit" => [ "shared", "apps" ],
- "stdio" => [ "apps" ],
+ "stdio" => [ "apps", "capieng", "egd" ],
"apps" => [ "tests" ],
"comp" => [ "zlib" ],
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
+
+ sub { !$disabled{"msan"} } => [ "asm" ],
);
# Avoid protocol support holes. Also disable all versions below N, if version
# To remove something from %disabled, use "enable-foo".
# For symmetry, "disable-foo" is a synonym for "no-foo".
-my @generated_headers = (
- "include/openssl/opensslconf.h",
- "crypto/include/internal/bn_conf.h",
- "crypto/include/internal/dso_conf.h"
- );
-
-my @generated_by_make_headers = (
- "crypto/buildinf.h"
- );
-
-
-my $no_sse2=0;
-
&usage if ($#ARGV < 0);
my $user_cflags="";
$config{options}="";
$config{build_type} = "release";
-my @argvcopy=@ARGV;
-
-if (grep /^reconf(igure)?$/, @argvcopy) {
- if (-f "./configdata.pm") {
- my $file = "./configdata.pm";
- unless (my $return = do $file) {
- die "couldn't parse $file: $@" if $@;
- die "couldn't do $file: $!" unless defined $return;
- die "couldn't run $file" unless $return;
- }
-
- @argvcopy = defined($configdata::config{perlargv}) ?
- @{$configdata::config{perlargv}} : ();
- die "Incorrect data to reconfigure, please do a normal configuration\n"
- if (grep(/^reconf/,@argvcopy));
- $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
- if defined($configdata::config{cross_compile_prefix});
- $ENV{CROSS_COMPILE} = $configdata::config{cc}
- if defined($configdata::config{cc});
-
- print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
- print " CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
- if $ENV{CROSS_COMPILE};
- print " CC = ",$ENV{CC},"\n" if $ENV{CC};
- } elsif (open IN, "<Makefile") {
- #
- # THIS SECTION IS TEMPORARY, it helps transitioning from Makefile
- # centered information gathering the reading configdata.pm
- #
- while (<IN>) {
- s|\R$||;
- if (/^CONFIGURE_ARGS=\s*(.*)\s*/) {
- # Older form, we split the string and hope for the best
- @argvcopy = split /\s+/, $_;
- die "Incorrect data to reconfigure, please do a normal configuration\n"
- if (grep(/^reconf/,@argvcopy));
- } elsif (/^CROSS_COMPILE=\s*(.*)/) {
- $ENV{CROSS_COMPILE}=$1;
- } elsif (/^CC=\s*(?:\$\(CROSS_COMPILE\))?(.*?)$/) {
- $ENV{CC}=$1;
- }
- }
- #
- # END OF TEMPORARY SECTION
- #
- } else {
- die "Insufficient data to reconfigure, please do a normal configuration\n";
- }
-}
-
-$config{perlargv} = [ @argvcopy ];
-
my %unsupported_options = ();
my %deprecated_options = ();
-foreach (@argvcopy)
+while (@argvcopy)
{
+ $_ = shift @argvcopy;
# VMS is a case insensitive environment, and depending on settings
# out of our control, we may receive options uppercased. Let's
# downcase at least the part before any equal sign.
s /^zlib-dynamic$/enable-zlib-dynamic/;
if (/^(no|disable|enable)-(.+)$/)
- {
- my $word = $2;
- if (grep { $word =~ /^${_}$/ } @deprecated_disablables)
- {
- $deprecated_options{$_} = 1;
- next;
- }
- elsif (!grep { $word =~ /^${_}$/ } @disablables)
- {
- $unsupported_options{$_} = 1;
- next;
- }
- }
- if (/^no-(.+)$/ || /^disable-(.+)$/)
- {
+ {
+ my $word = $2;
+ if (!exists $deprecated_disablables{$word}
+ && !grep { $word =~ /^${_}$/ } @disablables)
+ {
+ $unsupported_options{$_} = 1;
+ next;
+ }
+ }
+ if (/^no-(.+)$/ || /^disable-(.+)$/)
+ {
foreach my $proto ((@tls, @dtls))
{
if ($1 eq "$proto-method")
{
$disabled{"dynamic-engine"} = "option";
}
+ elsif (exists $deprecated_disablables{$1})
+ {
+ $deprecated_options{$_} = 1;
+ if (defined $deprecated_disablables{$1})
+ {
+ $disabled{$deprecated_disablables{$1}} = "option";
+ }
+ }
else
{
$disabled{$1} = "option";
{
$withargs{zlib_include}=$1;
}
+ elsif (/^--with-fuzzer-lib=(.*)$/)
+ {
+ $withargs{fuzzer_lib}=$1;
+ }
+ elsif (/^--with-fuzzer-include=(.*)$/)
+ {
+ $withargs{fuzzer_include}=$1;
+ }
elsif (/^--with-fipslibdir=(.*)$/)
{
$config{fipslibdir}="$1/";
{
$libs.=$_." ";
}
+ elsif (/^-rpath$/ or /^-R$/)
+ # -rpath is the OSF1 rpath flag
+ # -R is the old Solaris rpath flag
+ {
+ my $rpath = shift(@argvcopy) || "";
+ $rpath .= " " if $rpath ne "";
+ $libs.=$_." ".$rpath;
+ }
+ elsif (/^-static$/)
+ {
+ $libs.=$_." ";
+ $disabled{"dso"} = "forced";
+ $disabled{"pic"} = "forced";
+ $disabled{"shared"} = "forced";
+ $disabled{"threads"} = "forced";
+ }
elsif (/^-D(.*)$/)
{
push @user_defines, $1;
unless ($_ eq $target || /^no-/ || /^disable-/)
{
# "no-..." follows later after implied disactivations
- # have been derived. (Don't take this too seroiusly,
+ # have been derived. (Don't take this too seriously,
# we really only write OPTIONS to the Makefile out of
# nostalgia.)
else
{ $config{options} .= " ".$_; }
}
+ }
- if (defined($config{api}) && !exists $apitable->{$config{api}}) {
- die "***** Unsupported api compatibility level: $config{api}\n",
- }
+if (defined($config{api}) && !exists $apitable->{$config{api}}) {
+ die "***** Unsupported api compatibility level: $config{api}\n",
+}
- if (keys %deprecated_options)
- {
- warn "***** Deprecated options: ",
- join(", ", keys %deprecated_options), "\n";
- }
- if (keys %unsupported_options)
- {
- die "***** Unsupported options: ",
- join(", ", keys %unsupported_options), "\n";
- }
+if (keys %deprecated_options)
+ {
+ warn "***** Deprecated options: ",
+ join(", ", keys %deprecated_options), "\n";
+ }
+if (keys %unsupported_options)
+ {
+ die "***** Unsupported options: ",
+ join(", ", keys %unsupported_options), "\n";
}
+if ($libs =~ /(^|\s)-Wl,-rpath,/
+ && !$disabled{shared}
+ && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
+ die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
+ "***** any of asan, msan or ubsan\n";
+}
+
if ($config{fips})
{
delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/);
@tocheckfor = (keys %new_tocheckfor);
}
+our $die = sub { die @_; };
if ($target eq "TABLE") {
+ local $die = sub { warn @_; };
foreach (sort keys %table) {
print_table_entry($_, "TABLE");
}
}
if ($target eq "HASH") {
+ local $die = sub { warn @_; };
print "%table = (\n";
foreach (sort keys %table) {
print_table_entry($_, "HASH");
elsif (/^zlib-dynamic$/)
{ }
elsif (/^sse2$/)
- { $no_sse2 = 1; }
+ { }
elsif (/^engine$/)
{
@{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
@{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
+ print " OPENSSL_NO_ENGINE (skip engines)";
}
else
{
- my ($ALGO, $algo);
- ($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
+ my ($WHAT, $what);
+
+ ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/;
+
+ # Fix up C macro end names
+ $WHAT = "RMD160" if $what eq "ripemd";
- if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/ || /^async$/
- || /^autoalginit/ || /^autoerrinit/)
+ # fix-up crypto/directory name(s)
+ $what = "ripemd" if $what eq "rmd160";
+ $what = "whrlpool" if $what eq "whirlpool";
+
+ if ($what ne "async" && $what ne "err"
+ && grep { $_ eq $what } @{$config{sdirs}})
{
- push @{$config{openssl_other_defines}}, "OPENSSL_NO_$ALGO";
- print " OPENSSL_NO_$ALGO";
+ push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT";
+ @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}};
- if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; }
+ print " OPENSSL_NO_$WHAT (skip dir)";
}
else
{
- ($ALGO,$algo) = ("RMD160","rmd160") if ($algo eq "ripemd");
-
- push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$ALGO";
- print " OPENSSL_NO_$ALGO";
-
- # fix-up crypto/directory name(s)
- $algo="whrlpool" if $algo eq "whirlpool";
- $algo="ripemd" if $algo eq "rmd160";
- @{$config{sdirs}} = grep { $_ ne $algo} @{$config{sdirs}};
-
- print " (skip dir)";
+ push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
+ print " OPENSSL_NO_$WHAT";
}
}
$target = $t;
}
}
+
+&usage if !$table{$target} || $table{$target}->{template};
+
$config{target} = $target;
my %target = resolve_config($target);
-&usage if (!%target || $target{template});
-
+my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
+$config{conf_files} = [ sort keys %conf_files ];
%target = ( %{$table{DEFAULTS}}, %target );
$target{exe_extension}="";
if $config{cross_compile_prefix} eq "";
# Allow overriding the names of some tools. USE WITH CARE
+# Note: only Unix cares about HASHBANGPERL... that explains
+# the default string.
$config{perl} = $ENV{'PERL'} || ($^O ne "VMS" ? $^X : "perl");
+$config{hashbangperl} =
+ $ENV{'HASHBANGPERL'} || $ENV{'PERL'} || "/usr/bin/env perl";
$target{cc} = $ENV{'CC'} || $target{cc} || "cc";
-$target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} || which("ranlib") || "true";
+$target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} ||
+ (which("$config{cross_compile_prefix}ranlib") ?
+ "\$(CROSS_COMPILE)ranlib" : "true");
$target{ar} = $ENV{'AR'} || $target{ar} || "ar";
$target{nm} = $ENV{'NM'} || $target{nm} || "nm";
+$target{rc} =
+ $ENV{'RC'} || $ENV{'WINDRES'} || $target{rc} || "windres";
+
+# Allow overriding the build file name
+$target{build_file} = $ENV{BUILDFILE} || $target{build_file} || "Makefile";
+
+# Cache information necessary for reconfiguration
+$config{cc} = $target{cc};
+$config{build_file} = $target{build_file};
# For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
# or release_ attributes.
my ($builder, $builder_platform, @builder_opts) =
@{$target{build_scheme}};
+foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm",
+ $builder_platform."-checker.pm")) {
+ my $checker_path = catfile($srcdir, "Configurations", $checker);
+ if (-f $checker_path) {
+ my $fn = $ENV{CONFIGURE_CHECKER_WARN}
+ ? sub { warn $@; } : sub { die $@; };
+ if (! do $checker_path) {
+ if ($@) {
+ $fn->($@);
+ } elsif ($!) {
+ $fn->($!);
+ } else {
+ $fn->("The detected tools didn't match the platform\n");
+ }
+ }
+ last;
+ }
+}
+
push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
$disabled{threads} = "unavailable";
}
} else {
- # The user chose to enable threads explicitely, let's see
+ # The user chose to enable threads explicitly, let's see
# if there's a chance that's possible
if ($target{thread_scheme} eq "(unknown)") {
# If the user asked for "threads" and we don't have internal
$config{dynamic_engines} = 1;
}
+unless ($disabled{"fuzz-libfuzzer"}) {
+ $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls ";
+}
+
+unless ($disabled{asan}) {
+ $config{cflags} .= "-fsanitize=address ";
+}
+
+unless ($disabled{ubsan}) {
+ # -DPEDANTIC or -fnosanitize=alignment may also be required on some
+ # platforms.
+ $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
+}
+
+unless ($disabled{msan}) {
+ $config{cflags} .= "-fsanitize=memory ";
+}
+
+unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
+ && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
+ $config{cflags} .= "-fno-omit-frame-pointer -g ";
+}
#
# Platform fix-ups
#
# bn-586 is the only one implementing bn_*_part_words
push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
- push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
+ push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$disabled{sse2} && $target{bn_asm_src} =~ /86/);
push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
}
+ if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
+ push @{$config{defines}}, "RC4_ASM";
+ }
if ($target{md5_asm_src}) {
push @{$config{defines}}, "MD5_ASM";
}
push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
# aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
- $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
+ $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($disabled{sse2});
push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
}
if ($target{ec_asm_src} =~ /ecp_nistz256/) {
push @{$config{defines}}, "ECP_NISTZ256_ASM";
}
+ if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
+ push @{$config{defines}}, "PADLOCK_ASM";
+ }
if ($target{poly1305_asm_src} ne "") {
push @{$config{defines}}, "POLY1305_ASM";
}
}
-my $ecc = $target{cc};
-if ($^O ne "VMS" && !$disabled{makedepend}) {
- # Is the compiler gcc or clang? $ecc is used below to see if
- # error-checking can be turned on.
- my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
- open(PIPE, "$ccpcc --version 2>&1 |");
- my $lines = 2;
- while ( <PIPE> ) {
- # Find the version number and save the major.
- m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
- my $compiler_major = $1;
- # We know that GNU C version 3 and up as well as all clang
- # versions support dependency generation
- $config{makedepprog} = $ccpcc
- if (/clang/ || (/gcc/ && $compiler_major > 3));
- $ecc = "clang" if /clang/;
- $ecc = "gcc" if /gcc/;
- last if ($config{makedepprog} || !$lines--);
+my %predefined;
+
+if ($^O ne "VMS") {
+ my $cc = "$config{cross_compile_prefix}$target{cc}";
+
+ # collect compiler pre-defines from gcc or gcc-alike...
+ open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
+ while (<PIPE>) {
+ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
+ $predefined{$1} = $2 // "";
}
close(PIPE);
- $config{makedepprog} = which('makedepend') unless $config{makedepprog};
- $disabled{makedepend} = "unavailable" unless $config{makedepprog};
+ if (!$disabled{makedepend}) {
+ # We know that GNU C version 3 and up as well as all clang
+ # versions support dependency generation, but Xcode did not
+ # handle $cc -M before clang support (but claims __GNUC__ = 3)
+ if (($predefined{__GNUC__} // -1) >= 3
+ && !($predefined{__APPLE_CC__} && !$predefined{__clang__})) {
+ $config{makedepprog} = $cc;
+ } else {
+ $config{makedepprog} = which('makedepend');
+ $disabled{makedepend} = "unavailable" unless $config{makedepprog};
+ }
+ }
}
if ($strict_warnings)
{
my $wopt;
- die "ERROR --strict-warnings requires gcc or clang"
- unless $ecc eq 'gcc' || $ecc eq 'clang';
+ die "ERROR --strict-warnings requires gcc or gcc-alike"
+ unless defined($predefined{__GNUC__});
foreach $wopt (split /\s+/, $gcc_devteam_warn)
{
$config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
}
- if ($ecc eq "clang")
+ if (defined($predefined{__clang__}))
{
foreach $wopt (split /\s+/, $clang_devteam_warn)
{
my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
if ($builder eq "unified") {
- # Store the name of the template file we will build the build file from
- # in %config. This may be useful for the build file itself.
- my $build_file_template =
- catfile($srcdir, "Configurations",
- $builder_platform."-".$target{build_file}.".tmpl");
- $build_file_template =
- catfile($srcdir, "Configurations", $target{build_file}.".tmpl")
- if (! -f $build_file_template);
- $config{build_file_template} = $build_file_template;
-
- use lib catdir(dirname(__FILE__),"util");
use with_fallback qw(Text::Template);
sub cleandir {
return $res;
}
+ # 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" );
+ my @build_file_templates = ();
+
+ # First, look in the user provided directory, if given
+ if (defined $ENV{$local_config_envname}) {
+ @build_file_templates =
+ map {
+ if ($^O eq 'VMS') {
+ # VMS environment variables are logical names,
+ # which can be used as is
+ $local_config_envname . ':' . $_;
+ } else {
+ catfile($ENV{$local_config_envname}, $_);
+ }
+ }
+ @build_file_template_names;
+ }
+ # Then, look in our standard directory
+ push @build_file_templates,
+ ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
+ @build_file_template_names );
+
+ my $build_file_template;
+ for $_ (@build_file_templates) {
+ $build_file_template = $_;
+ last if -f $build_file_template;
+
+ $build_file_template = undef;
+ }
+ if (!defined $build_file_template) {
+ die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
+ }
+ $config{build_file_templates}
+ = [ $build_file_template,
+ cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
+ $blddir) ];
+
my @build_infos = ( [ ".", "build.info" ] );
foreach (@{$config{dirs}}) {
push @build_infos, [ $_, "build.info" ]
my $f = $_->[1];
# The basic things we're trying to build
my @programs = ();
+ my @programs_install = ();
my @libraries = ();
+ my @libraries_install = ();
my @engines = ();
+ my @engines_install = ();
my @scripts = ();
+ my @scripts_install = ();
my @extra = ();
my @overrides = ();
my @intermediates = ();
my %sharednames = ();
my %generate = ();
+ # 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);
+
push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
- my $template = Text::Template->new(TYPE => 'FILE',
- SOURCE => catfile($sourced, $f));
+ my $template =
+ Text::Template->new(TYPE => 'FILE',
+ SOURCE => catfile($sourced, $f),
+ PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
die "Something went wrong with $sourced/$f: $!\n" unless $template;
my @text =
split /^/m,
$template->fill_in(HASH => { config => \%config,
target => \%target,
disabled => \%disabled,
+ withargs => \%withargs,
builddir => abs2rel($buildd, $blddir),
sourcedir => abs2rel($sourced, $blddir),
buildtop => abs2rel($blddir, $blddir),
qr/^\s*ENDIF\s*$/
=> sub { die "ENDIF out of scope" if ! @skip;
pop @skip; },
- qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
- => sub { push @programs, split(/\s+/, $1)
- if !@skip || $skip[$#skip] > 0 },
- qr/^\s*LIBS\s*=\s*(.*)\s*$/
- => sub { push @libraries, split(/\s+/, $1)
- if !@skip || $skip[$#skip] > 0 },
- qr/^\s*ENGINES\s*=\s*(.*)\s*$/
- => sub { push @engines, split(/\s+/, $1)
- if !@skip || $skip[$#skip] > 0 },
- qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
- => sub { push @scripts, split(/\s+/, $1)
- if !@skip || $skip[$#skip] > 0 },
+ qr/^\s*PROGRAMS(_NO_INST)?\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;
+ }
+ },
+ qr/^\s*LIBS(_NO_INST)?\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;
+ }
+ },
+ qr/^\s*ENGINES(_NO_INST)?\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;
+ }
+ },
+ qr/^\s*SCRIPTS(_NO_INST)?\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;
+ }
+ },
qr/^\s*EXTRA\s*=\s*(.*)\s*$/
- => sub { push @extra, split(/\s+/, $1)
+ => sub { push @extra, tokenize($1)
if !@skip || $skip[$#skip] > 0 },
qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
- => sub { push @overrides, split(/\s+/, $1)
+ => sub { push @overrides, tokenize($1)
if !@skip || $skip[$#skip] > 0 },
qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
- => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
+ => sub { push @{$ordinals{$1}}, tokenize($2)
if !@skip || $skip[$#skip] > 0 },
qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
- => sub { push @{$sources{$1}}, split(/\s+/, $2)
+ => sub { push @{$sources{$1}}, tokenize($2)
if !@skip || $skip[$#skip] > 0 },
qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
- => sub { push @{$shared_sources{$1}}, split(/\s+/, $2)
+ => sub { push @{$shared_sources{$1}}, tokenize($2)
if !@skip || $skip[$#skip] > 0 },
qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
- => sub { push @{$includes{$1}}, split(/\s+/, $2)
+ => sub { push @{$includes{$1}}, tokenize($2)
if !@skip || $skip[$#skip] > 0 },
- qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
- => sub { push @{$depends{$1}}, split(/\s+/, $2)
+ qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
+ => sub { push @{$depends{$1}}, tokenize($2)
if !@skip || $skip[$#skip] > 0 },
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}}, split(/\s+/, $2)
+ => sub { push @{$renames{$1}}, tokenize($2)
if !@skip || $skip[$#skip] > 0 },
qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
- => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
+ => sub { push @{$sharednames{$1}}, tokenize($2)
if !@skip || $skip[$#skip] > 0 },
qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
=> sub {
$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}) {
$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};
ENGINES can only be used if configured with 'dynamic-engine'.
This is usually a fault in a build.info file.
$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}) {
$unified_info{scripts}->{$script} = 1;
}
+ foreach (@scripts_install) {
+ my $script = cleanfile($buildd, $_, $blddir);
+ if ($unified_info{rename}->{$script}) {
+ $script = $unified_info{rename}->{$script};
+ }
+ $unified_info{install}->{scripts}->{$script} = 1;
+ }
+
foreach (@extra) {
my $extra = cleanfile($buildd, $_, $blddir);
$unified_info{extra}->{$extra} = 1;
# If it isn't in the source tree, we assume it's generated
# in the build tree
- if (! -f $s) {
+ if ($s eq $src_configdata || ! -f $s || $generate{$_}) {
$s = cleanfile($buildd, $_, $blddir);
}
# We recognise C and asm files
# If it isn't in the source tree, we assume it's generated
# in the build tree
- if (! -f $s) {
+ if ($s eq $src_configdata || ! -f $s || $generate{$_}) {
$s = cleanfile($buildd, $_, $blddir);
}
# We recognise C and asm files
foreach (keys %depends) {
my $dest = $_;
- my $ddest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$ddest}) {
- $ddest = $unified_info{rename}->{$ddest};
+ my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
+
+ # If the destination doesn't exist in source, it can only be
+ # a generated file in the build tree.
+ if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) {
+ $ddest = cleanfile($buildd, $_, $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
}
foreach (@{$depends{$dest}}) {
my $d = cleanfile($sourced, $_, $blddir);
# in the build tree rather than the source tree, and assume
# and that there are lines to build it in a BEGINRAW..ENDRAW
# section or in the Makefile template.
- if (! -f $d
+ if ($d eq $src_configdata
+ || ! -f $d
|| (grep { $d eq $_ }
map { cleanfile($srcdir, $_, $blddir) }
- (@generated_headers, @generated_by_make_headers))) {
+ grep { /\.h$/ } keys %{$unified_info{generate}})) {
$d = cleanfile($buildd, $_, $blddir);
}
# Take note if the file to depend on is being renamed
$d = $unified_info{rename}->{$d};
}
$unified_info{depends}->{$ddest}->{$d} = 1;
- # If we depend on a header file, let's make sure it
- # can get included
- if ($d =~ /\.h$/) {
- my $i = dirname($d);
- push @{$unified_info{includes}->{$ddest}}, $i
- unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
- }
}
}
foreach (keys %includes) {
my $dest = $_;
- my $ddest = cleanfile($buildd, $_, $blddir);
- if ($unified_info{rename}->{$ddest}) {
- $ddest = $unified_info{rename}->{$ddest};
+ my $ddest = cleanfile($sourced, $_, $blddir);
+
+ # If the destination doesn't exist in source, it can only be
+ # a generated file in the build tree.
+ if ($ddest eq $src_configdata || ! -f $ddest) {
+ $ddest = cleanfile($buildd, $_, $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
}
foreach (@{$includes{$dest}}) {
- my $i = cleandir($sourced, $_, $blddir);
- push @{$unified_info{includes}->{$ddest}}, $i
- unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
+ my $is = cleandir($sourced, $_, $blddir);
+ my $ib = cleandir($buildd, $_, $blddir);
+ push @{$unified_info{includes}->{$ddest}->{source}}, $is
+ unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
+ push @{$unified_info{includes}->{$ddest}->{build}}, $ib
+ unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
+ }
+ }
+ }
+
+ # Massage the result
+
+ # If we depend on a header file or a perl module, add an inclusion of
+ # its directory to allow smoothe inclusion
+ foreach my $dest (keys %{$unified_info{depends}}) {
+ next if $dest eq "";
+ foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
+ next unless $d =~ /\.(h|pm)$/;
+ my $i = dirname($d);
+ my $spot =
+ $d eq "configdata.pm" || defined($unified_info{generate}->{$d})
+ ? 'build' : 'source';
+ push @{$unified_info{includes}->{$dest}->{$spot}}, $i
+ unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{$spot}};
+ }
+ }
+
+ # Trickle down includes placed on libraries, engines and programs to
+ # their sources (i.e. object files)
+ foreach my $dest (keys %{$unified_info{engines}},
+ keys %{$unified_info{libraries}},
+ keys %{$unified_info{programs}}) {
+ foreach my $k (("source", "build")) {
+ next unless defined($unified_info{includes}->{$dest}->{$k});
+ my @incs = reverse @{$unified_info{includes}->{$dest}->{$k}};
+ foreach my $obj (grep /\.o$/,
+ (keys %{$unified_info{sources}->{$dest} // {}},
+ keys %{$unified_info{shared_sources}->{$dest} // {}})) {
+ foreach my $inc (@incs) {
+ unshift @{$unified_info{includes}->{$obj}->{$k}}, $inc
+ unless grep { $_ eq $inc } @{$unified_info{includes}->{$obj}->{$k}};
+ }
}
}
+ delete $unified_info{includes}->{$dest};
}
### Make unified_info a bit more efficient
$unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
}
# Two level structures
- foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) {
+ foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
foreach my $l2 (sort keys %{$unified_info{$l1}}) {
$unified_info{$l1}->{$l2} =
[ sort keys %{$unified_info{$l1}->{$l2}} ];
}
}
+ # Includes
+ foreach my $dest (sort keys %{$unified_info{includes}}) {
+ if (defined($unified_info{includes}->{$dest}->{build})) {
+ my @source_includes = ();
+ @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} )
+ if defined($unified_info{includes}->{$dest}->{source});
+ $unified_info{includes}->{$dest} =
+ [ @{$unified_info{includes}->{$dest}->{build}} ];
+ foreach my $inc (@source_includes) {
+ push @{$unified_info{includes}->{$dest}}, $inc
+ unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
+ }
+ } else {
+ $unified_info{includes}->{$dest} =
+ [ @{$unified_info{includes}->{$dest}->{source}} ];
+ }
+ }
}
# For the schemes that need it, we provide the old *_obj configs
close(OUT);
-print "CC =$target{cc}\n";
+print "CC =$config{cross_compile_prefix}$target{cc}\n";
print "CFLAG =$target{cflags} $config{cflags}\n";
print "SHARED_CFLAG =$target{shared_cflag}\n";
print "DEFINES =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
print "POLY1305_OBJ =$target{poly1305_obj}\n";
print "BLAKE2_OBJ =$target{blake2_obj}\n";
print "PROCESSOR =$config{processor}\n";
-print "RANLIB =$target{ranlib}\n";
+print "RANLIB =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
+ "$config{cross_compile_prefix}ranlib" :
+ "$target{ranlib}", "\n";
print "ARFLAGS =$target{arflags}\n";
print "PERL =$config{perl}\n";
print "\n";
print "BN_LLONG mode\n" if $config{bn_ll};
print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int;
-for (@generated_headers) {
- mkpath(catdir($blddir, dirname($_)));
- run_dofile(catfile($blddir, $_),
- catfile($srcdir, $_.".in"));
-}
-
-###
-### When the old "unixmake" scheme goes away, so does this function
-###
-sub build_Makefile {
- run_dofile("Makefile","Makefile.in");
-
- # Copy all Makefile.in to Makefile (except top-level)
- use File::Find;
- use IO::File;
- find(
- {
- preprocess => sub {
- grep(!/^\./, @_);
- },
- wanted => sub {
- return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
- my $in = IO::File->new($_, "r") or
- die sprintf "Error reading Makefile.in in %s: !$\n",
- $File::Find::dir;
- my $out = IO::File->new("Makefile", "w") or
- die sprintf "Error writing Makefile in %s: !$\n",
- $File::Find::dir;
- print $out "# Generated from $_, do not edit\n";
- while (my $line = <$in>) { print $out $line }
- $in->close() or
- die sprintf "Error reading Makefile.in in %s: !$\n",
- $File::Find::dir;
- $out->close() or
- die sprintf "Error writing Makefile in %s: !$\n",
- $File::Find::dir;
- },
- },
- ".");
-}
-
my %builders = (
unified => sub {
run_dofile(catfile($blddir, $target{build_file}),
- $config{build_file_template},
- catfile($srcdir, "Configurations", "common.tmpl"));
- },
- unixmake => sub {
- build_Makefile();
-
- run_dofile("util/domd", "util/domd.in");
- chmod 0755, "util/domd";
+ @{$config{build_file_templates}});
},
);
$builders{$builder}->($builder_platform, @builder_opts);
+$SIG{__DIE__} = $orig_death_handler;
+
print <<"EOF";
Configured for $target.
you have tried with a current version of OpenSSL).
EOF
-print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
-
-WARNING: there are indications that another build was made in the source
-directory. This build may have picked up artifacts from that build, the
-safest course of action is to clean the source directory and redo this
-configuration.
-EOF
-
exit(0);
######################################################################
# Helpers and utility functions
#
+# Death handler, to print a helpful message in case of failure #######
+#
+sub death_handler {
+ die @_ if $^S; # To prevent the added message in eval blocks
+ my $build_file = $target{build_file} // "build file";
+ my @message = ( <<"_____", @_ );
+
+Failure! $build_file wasn't produced.
+Please read INSTALL and associated NOTES files. You may also have to look over
+your available compiler tool chain or change your configuration.
+
+_____
+
+ # Dying is terminal, so it's ok to reset the signal handler here.
+ $SIG{__DIE__} = $orig_death_handler;
+ die @message;
+}
+
# Configuration file reading #########################################
# Note: All of the helper functions are for lazy evaluation. They all
close(CONFFILE);
my %targets = ();
{
- local %table = %::table; # Protect %table from tampering
+ # Protect certain tables from tampering
+ local %table = %::table;
eval $content;
warn $@ if $@;
}
+ my %preexisting = ();
+ foreach (sort keys %targets) {
+ $preexisting{$_} = 1 if $table{$_};
+ }
+ die <<"EOF",
+The following config targets from $fname
+shadow pre-existing config targets with the same name:
+EOF
+ map { " $_\n" } sort keys %preexisting
+ if %preexisting;
+
# For each target, check that it's configured with a hash table.
foreach (keys %targets) {
warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
}
delete $targets{$_};
- }
+ } else {
+ $targets{$_}->{_conf_fname_int} = add([ $fname ]);
+ }
}
%table = (%table, %targets);
}
-# configuration resolver. Will only resolve all the lazy evalutation
-# codeblocks for the chozen target and all those it inherits from,
+# configuration resolver. Will only resolve all the lazy evaluation
+# codeblocks for the chosen target and all those it inherits from,
# recursively
sub resolve_config {
my $target = shift;
# - If a value is a coderef, it will be executed with the list of
# inherited values as arguments.
# - If the corresponding key doesn't have a value at all or is the
- # emoty string, the inherited value list will be run through the
+ # empty string, the inherited value list will be run through the
# default combiner (below), and the result becomes this target's
# value.
# - Otherwise, this target's value is assumed to be a string that
foreach (@templates) {
die "Can't open $_, $!" unless -f $_;
}
- my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
+ my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
+ my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
#print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
system($cmd);
exit 1 if $? != 0;
rename("$out.new", $out) || die "Can't rename $out.new, $!";
}
+sub which
+{
+ my ($name)=@_;
+
+ if (eval { require IPC::Cmd; 1; }) {
+ IPC::Cmd->import();
+ return scalar IPC::Cmd::can_run($name);
+ } else {
+ # if there is $directories component in splitpath,
+ # then it's not something to test with $PATH...
+ return $name if (File::Spec->splitpath($name))[1];
+
+ foreach (File::Spec->path()) {
+ my $fullpath = catfile($_, "$name$target{exe_extension}");
+ if (-f $fullpath and -x $fullpath) {
+ return $fullpath;
+ }
+ }
+ }
+}
+
# Configuration printer ##############################################
sub print_table_entry
"unistd",
"ld",
"lflags",
+ "loutflag",
"plib_lflags",
"ex_libs",
"bn_ops",
- "cpuid_obj",
- "bn_obj",
- "ec_obj",
- "des_obj",
- "aes_obj",
- "bf_obj",
- "md5_obj",
- "sha1_obj",
- "cast_obj",
- "rc4_obj",
- "rmd160_obj",
- "rc5_obj",
- "wp_obj",
- "cmll_obj",
- "modes_obj",
- "padlock_obj",
+ "apps_aux_src",
+ "cpuid_asm_src",
+ "uplink_aux_src",
+ "bn_asm_src",
+ "ec_asm_src",
+ "des_asm_src",
+ "aes_asm_src",
+ "bf_asm_src",
+ "md5_asm_src",
+ "cast_asm_src",
+ "sha1_asm_src",
+ "rc4_asm_src",
+ "rmd160_asm_src",
+ "rc5_asm_src",
+ "wp_asm_src",
+ "cmll_asm_src",
+ "modes_asm_src",
+ "padlock_asm_src",
+ "chacha_asm_src",
+ "poly1035_asm_src",
"thread_scheme",
"perlasm_scheme",
"dso_scheme",
"shared_target",
"shared_cflag",
+ "shared_defines",
"shared_ldflag",
"shared_rcflag",
"shared_extension",
- "shared_extension_simple",
- "shared_import_extension",
"dso_extension",
"obj_extension",
"exe_extension",
"ranlib",
"ar",
"arflags",
+ "aroutflag",
+ "rc",
+ "rcflags",
+ "rcoutflag",
+ "mt",
+ "mtflags",
+ "mtinflag",
+ "mtoutflag",
"multilib",
"build_scheme",
);
# On non-platforms, we just use file_name_is_absolute().
return file_name_is_absolute($file) unless $^O eq "VMS";
- # If the file spec includes a device or a directpry spec,
+ # If the file spec includes a device or a directory spec,
# file_name_is_absolute() is perfectly safe.
return file_name_is_absolute($file) if $file =~ m|[:\[]|;
return realpath($dir);
}
-sub which
- {
- my($name)=@_;
- my $path;
- foreach $path (split /:/, $ENV{PATH})
- {
- my $fullpath = "$path/$name$target{exe_extension}";
- if (-f $fullpath and -x $fullpath)
- {
- return $fullpath
- unless ($name eq "perl" and
- system("$fullpath -e " . '\'exit($]<5.0);\''));
- }
- }
- }
-
sub quotify {
my %processors = (
perl => sub { my $x = shift;
$x =~ s/([\\\$\@"])/\\$1/g;
return '"'.$x.'"'; },
+ maybeshell => sub { my $x = shift;
+ (my $y = $x) =~ s/([\\\"])/\\$1/g;
+ if ($x ne $y || $x =~ m|\s|) {
+ return '"'.$y.'"';
+ } else {
+ return $x;
+ }
+ },
);
my $for = shift;
my $processor =
}
}
}
+
+# tokenize($line)
+# $line is a line of text to split up into tokens
+# 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
+# with backslash.
+# Basically, the same quoting rules apply for " and ' as in any
+# Unix shell.
+sub tokenize {
+ my $line = my $debug_line = shift;
+ my @result = ();
+
+ while ($line =~ s|^\s+||, $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 = $';
+ }
+ }
+ push @result, $token;
+ }
+
+ if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
+ print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
+ print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
+ }
+ return @result;
+}