#! /usr/bin/env perl
# -*- mode: perl; -*-
+# Copyright 2016 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
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
## Configure -- OpenSSL source tree configuration script
use File::Basename;
use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
use File::Path qw/mkpath/;
+use if $^O ne "VMS", 'File::Glob' => qw/glob/;
# see INSTALL for instructions.
# 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.
-my $gcc_devteam_warn = "-DPEDANTIC -DREF_DEBUG -DDEBUG_UNUSED -DBIO_DEBUG"
- . " -pedantic"
+# 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-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
+ # supposed to and does take notice of non-standard behaviour. Then
+ # -pedantic with pre-C9x compiler would also complain about 'long
+ # long' not being supported. As 64-bit algorithms are common now,
+ # it grew impossible to resolve this without sizeable additional
+ # code, so we just tell compiler to be pedantic about everything
+ # but 'long long' type.
+ . " -DPEDANTIC -pedantic -Wno-long-long"
. " -Wall"
- . " -Wno-long-long"
. " -Wsign-compare"
. " -Wmissing-prototypes"
. " -Wshadow"
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 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";
$config{fips}=0;
# Top level directories to build
-$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools" ];
+$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "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 = (
- "aes",
"afalgeng",
+ "asan",
"asm",
"async",
"autoalginit",
"engine",
"err",
"filenames",
+ "fuzz-libfuzzer",
+ "fuzz-afl",
+ "gost",
"heartbeats",
- "hmac",
"hw(-.+)?",
"idea",
"makedepend",
"md2",
"md4",
- "md5",
"mdc2",
- "md[-_]ghost94",
"multiblock",
"nextprotoneg",
"ocb",
"rc5",
"rdrand",
"rfc3779",
- "rijndael", # Old AES name
- "ripemd",
"rmd160",
- "rsa",
"scrypt",
- "sct",
"sctp",
"seed",
- "sha",
"shared",
"sock",
"srp",
"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",
"ec_nistp_64_gcc_128" => "default",
"egd" => "default",
+ "fuzz-libfuzzer" => "default",
+ "fuzz-afl" => "default",
"md2" => "default",
"rc5" => "default",
"sctp" => "default",
- "shared" => "default",
"ssl-trace" => "default",
"ssl3" => "default",
"ssl3-method" => "default",
- "static-engine" => "default",
+ "ubsan" => "default",
"unit-test" => "default",
"weak-ssl-ciphers" => "default",
"zlib" => "default",
"zlib-dynamic" => "default",
"crypto-mdebug" => "default",
+ "crypto-mdebug-backtrace" => "default",
"heartbeats" => "default",
);
"ssl" => [ "ssl3" ],
"ssl3-method" => [ "ssl3" ],
"zlib" => [ "zlib-dynamic" ],
- "rijndael" => [ "aes" ],
"des" => [ "mdc2" ],
"ec" => [ "ecdsa", "ecdh" ],
- "dgram" => [ "dtls" ],
+ "dgram" => [ "dtls", "sctp" ],
+ "sock" => [ "dgram" ],
"dtls" => [ @dtls ],
# SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
"pic" => [ "shared" ],
"shared" => [ "dynamic-engine" ],
"engine" => [ "afalgeng" ],
+
+ # no-autoalginit is only useful when building non-shared
+ "autoalginit" => [ "shared", "apps" ],
+
+ "stdio" => [ "apps" ],
+ "apps" => [ "tests" ],
+ "comp" => [ "zlib" ],
+ sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
);
# 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);
$config{options}="";
$config{build_type} = "release";
-my $classic = 0;
-
my @argvcopy=@ARGV;
if (grep /^reconf(igure)?$/, @argvcopy) {
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{$proto} = "option(dtls)";
}
+ $disabled{"dtls"} = "option(dtls)";
}
elsif ($1 eq "ssl")
{
{
$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";
}
elsif (/^[-+]/)
{
- if (/^--classic$/)
- {
- $classic=1;
- }
- elsif (/^--prefix=(.*)$/)
+ if (/^--prefix=(.*)$/)
{
$config{prefix}=$1;
die "Directory given with --prefix MUST be absolute\n"
}
elsif (/^--with-zlib-include=(.*)$/)
{
- $withargs{zlib_include}="-I$1";
+ $withargs{zlib_include}=$1;
+ }
+ elsif (/^--with-fuzzer-lib=(.*)$/)
+ {
+ $withargs{fuzzer_lib}=$1;
+ }
+ elsif (/^--with-fuzzer-include=(.*)$/)
+ {
+ $withargs{fuzzer_include}=$1;
}
elsif (/^--with-fipslibdir=(.*)$/)
{
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.)
while (@cascade_copy) {
my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
- map {
+ foreach(grep { !defined($disabled{$_}) } @$descendents) {
$new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
- } grep { !defined($disabled{$_}) } @$descendents;
+ }
}
}
@tocheckfor = (keys %new_tocheckfor);
$target{exe_extension}="";
$target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
|| $config{target} =~ /^(?:Cygwin|mingw)/);
-$target{exe_extension}=".nlm" if ($config{target} =~ /netware/);
$target{exe_extension}=".pm" if ($config{target} =~ /vos/);
($target{shared_extension_simple}=$target{shared_extension})
if $config{cross_compile_prefix} eq "";
# Allow overriding the names of some tools. USE WITH CARE
-$config{perl} = $ENV{'PERL'} || which("perl5") || which("perl") || "perl";
+# 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";
# For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
# or release_ attributes.
$target{build_scheme} = [ $target{build_scheme} ]
if ref($target{build_scheme}) ne "ARRAY";
-###### TO BE REMOVED WHEN CLASSIC BUILD IS REMOVED
-######
-###### If the user has chosen --classic, we give it to them.
-###### If they try that with an out-of-source config, we complain.
-if ($target{build_scheme}->[0] eq "unified" && $classic) {
- die "Can't perform a classic build out of source tree\n"
- if $srcdir ne $blddir;
-
- $target{build_scheme} = { unix => [ "unixmake" ],
- windows => [ "mk1mf", $target{build_scheme}->[2] ],
- VMS => undef } -> {$target{build_scheme}->[1]};
-
- die "Classic mode unavailable on this platform\n"
- unless defined($target{build_scheme});
-}
-
my ($builder, $builder_platform, @builder_opts) =
@{$target{build_scheme}};
+push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
+
if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
{
$config{cflags} .= " -mno-cygwin";
$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{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
+ && $disabled{asan} && $disabled{ubsan}) {
+ $config{cflags} .= "-fno-omit-frame-pointer -g ";
+}
#
# Platform fix-ups
#
} else {
push @{$config{engdirs}}, "afalg";
}
+ } else {
+ $disabled{afalgeng} = "cross-compiling";
}
} else {
$disabled{afalgeng} = "not-linux";
# If we use the unified build, collect information from build.info files
my %unified_info = ();
+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);
+ my $build_file_template;
+
+ for my $filename (( $builder_platform."-".$target{build_file}.".tmpl",
+ $target{build_file}.".tmpl" )) {
+ if (defined $ENV{$local_config_envname}) {
+ if ($^O eq 'VMS') {
+ # VMS environment variables are logical names,
+ # which can be used as is
+ $build_file_template = $local_config_envname . ':' . $filename;
+ } else {
+ $build_file_template = catfile($ENV{$local_config_envname},
+ $filename);
+ }
+ }
+
+ last if -f $build_file_template;
+
+ $build_file_template = catfile($srcdir, "Configurations", $filename);
+
+ last if -f $build_file_template;
+ }
$config{build_file_template} = $build_file_template;
use lib catdir(dirname(__FILE__),"util");
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 %ordinals = ();
my %sources = ();
+ my %shared_sources = ();
my %includes = ();
my %depends = ();
my %renames = ();
$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}}, 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 {
}
},
qr/^(?:#.*|\s*)$/ => sub { },
- "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
+ "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
+ "BEFORE" => sub {
+ if ($buildinfo_debug) {
+ print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
+ print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
+ }
+ },
+ "AFTER" => sub {
+ if ($buildinfo_debug) {
+ print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
+ }
+ },
);
die "runaway IF?" if (@skip);
$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;
}
}
+ 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);
+
+ # If it isn't in the source tree, we assume it's generated
+ # in the build tree
+ if (! -f $s) {
+ $s = cleanfile($buildd, $_, $blddir);
+ }
+ # We recognise C and asm files
+ if ($s =~ /\.[csS]\b$/) {
+ (my $o = $_) =~ s/\.[csS]\b$/.o/;
+ $o = cleanfile($buildd, $o, $blddir);
+ $unified_info{shared_sources}->{$ddest}->{$o} = 1;
+ $unified_info{sources}->{$o}->{$s} = 1;
+ } else {
+ die "unrecognised source file type for shared library: $s\n";
+ }
+ }
+ }
+
foreach (keys %generate) {
my $dest = $_;
my $ddest = cleanfile($buildd, $_, $blddir);
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 "" && ! -f $ddest) {
+ $ddest = cleanfile($buildd, $_, $blddir);
+ if ($unified_info{rename}->{$ddest}) {
+ $ddest = $unified_info{rename}->{$ddest};
+ }
}
foreach (@{$depends{$dest}}) {
my $d = cleanfile($sourced, $_, $blddir);
# and that there are lines to build it in a BEGINRAW..ENDRAW
# section or in the Makefile template.
if (! -f $d
- || !(grep { $d eq $_ }
- map { cleanfile($srcdir, $_, $blddir) }
- (@generated_headers, @generated_by_make_headers))) {
+ || (grep { $d eq $_ }
+ map { cleanfile($srcdir, $_, $blddir) }
+ 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$/) {
+ # If we depend on a header file or a perl module, let's make
+ # sure it can get included
+ if ($dest ne "" && $d =~ /\.(h|pm)$/) {
my $i = dirname($d);
- push @{$unified_info{includes}->{$ddest}}, $i
- unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
+ push @{$unified_info{includes}->{$ddest}->{source}}, $i
+ unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}};
}
}
}
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 (! -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}};
}
}
}
$unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
}
# Two level structures
- foreach my $l1 (("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 =
+ ( @{$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
use Exporter;
#use vars qw(\@ISA \@EXPORT);
our \@ISA = qw(Exporter);
-our \@EXPORT = qw(\%config \%target %disabled %withargs %unified_info);
+our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
EOF
print OUT "our %config = (\n";
print OUT <<"EOF";
);
+EOF
+print OUT "our \@disablables = (\n";
+foreach (@disablables) {
+ print OUT " ", quotify("perl", $_), ",\n";
+}
+print OUT <<"EOF";
+);
+
EOF
print OUT "our \%disabled = (\n";
foreach (sort keys %disabled) {
close(OUT);
-print "IsMK1MF =", ($builder eq "mk1mf" ? "yes" : "no"), "\n";
-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";
- },
- mk1mf => sub {
- my $platform = shift;
- # The only reason we do this is to have something to build MINFO from
- build_Makefile();
-
- # create the ms/version32.rc file if needed
- if ($platform ne "netware") {
- my ($v1, $v2, $v3, $v4);
- if ($config{version_num} =~ /^0x([0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{1})L$/i) {
- $v1=hex $1;
- $v2=hex $2;
- $v3=hex $3;
- $v4=hex $4;
- }
- open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
- print OUT <<"EOF";
-#include <winver.h>
-
-LANGUAGE 0x09,0x01
-
-1 VERSIONINFO
- FILEVERSION $v1,$v2,$v3,$v4
- PRODUCTVERSION $v1,$v2,$v3,$v4
- FILEFLAGSMASK 0x3fL
-#ifdef _DEBUG
- FILEFLAGS 0x01L
-#else
- FILEFLAGS 0x00L
-#endif
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- // Required:
- VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
- VALUE "FileDescription", "OpenSSL Shared Library\\0"
- VALUE "FileVersion", "$config{version}\\0"
-#if defined(CRYPTO)
- VALUE "InternalName", "libcrypto32\\0"
- VALUE "OriginalFilename", "libcrypto32.dll\\0"
-#elif defined(SSL)
- VALUE "InternalName", "libssl32\\0"
- VALUE "OriginalFilename", "libssl32.dll\\0"
-#endif
- VALUE "ProductName", "The OpenSSL Toolkit\\0"
- VALUE "ProductVersion", "$config{version}\\0"
- // Optional:
- //VALUE "Comments", "\\0"
- VALUE "LegalCopyright", "Copyright © 1998-2015 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
- //VALUE "LegalTrademarks", "\\0"
- //VALUE "PrivateBuild", "\\0"
- //VALUE "SpecialBuild", "\\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 0x4b0
- END
-END
-EOF
- close(OUT);
- }
- },
);
$builders{$builder}->($builder_platform, @builder_opts);
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);
######################################################################
# Configuration file reading #########################################
+# Note: All of the helper functions are for lazy evaluation. They all
+# return a CODE ref, which will return the intended value when evaluated.
+# Thus, whenever there's mention of a returned value, it's about that
+# intended value.
+
# Helper function to implement conditional inheritance depending on the
# value of $disabled{asm}. Used in inherit_from values as follows:
#
}
}
+# Helper function to implement conditional value variants, with a default
+# plus additional values based on the value of $config{build_type}.
+# Arguments are given in hash table form:
+#
+# picker(default => "Basic string: ",
+# debug => "debug",
+# release => "release")
+#
+# When configuring with --debug, the resulting string will be
+# "Basic string: debug", and when not, it will be "Basic string: release"
+#
+# This can be used to create variants of sets of flags according to the
+# build type:
+#
+# cflags => picker(default => "-Wall",
+# debug => "-g -O0",
+# release => "-O3")
+#
+sub picker {
+ my %opts = @_;
+ return sub { add($opts{default} || (),
+ $opts{$config{build_type}} || ())->(); }
+}
+
+# Helper function to combine several values of different types into one.
+# This is useful if you want to combine a string with the result of a
+# lazy function, such as:
+#
+# cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
+#
+sub combine {
+ my @stuff = @_;
+ return sub { add(@stuff)->(); }
+}
+
+# Helper function to implement conditional values depending on the value
+# of $disabled{threads}. Can be used as follows:
+#
+# cflags => combine("-Wall", threads("-pthread"))
+#
+sub threads {
+ my @flags = @_;
+ return sub { add($disabled{threads} ? () : @flags)->(); }
+}
+
+
+
our $add_called = 0;
# Helper function to implement adding values to already existing configuration
# values. It handles elements that are ARRAYs, CODEs and scalars
}
-# 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;
# the config that had it.
delete $inherited_config{template};
- map {
+ foreach (keys %inherited_config) {
if (!$combined_inheritance{$_}) {
$combined_inheritance{$_} = [];
}
push @{$combined_inheritance{$_}}, $inherited_config{$_};
- } keys %inherited_config;
+ }
}
}
# - 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 $cmd = "$config{perl} \"-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
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;
my $processor =
defined($processors{$for}) ? $processors{$for} : sub { shift; };
- map { $processor->($_); } @_;
+ return map { $processor->($_); } @_;
}
# collect_from_file($filename, $line_concat_cond_re, $line_concat)
while(defined($_ = $lineiterator->())) {
s|\R$||;
my $found = 0;
+ if ($collectors{"BEFORE"}) {
+ $collectors{"BEFORE"}->($_);
+ }
foreach my $re (keys %collectors) {
- if ($re ne "OTHERWISE" && /$re/) {
+ if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
$collectors{$re}->($lineiterator);
$found = 1;
};
$collectors{"OTHERWISE"}->($lineiterator, $_)
unless $found || !defined $collectors{"OTHERWISE"};
}
+ if ($collectors{"AFTER"}) {
+ $collectors{"AFTER"}->($_);
+ }
+ }
+}
+
+# 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;
}