#! /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 if $^O ne "VMS", 'File::Glob' => qw/glob/;
+use OpenSSL::Glob;
# see INSTALL for instructions.
# library and will be loaded in run-time by the OpenSSL library.
# sctp include SCTP support
# enable-weak-ssl-ciphers
-# Enable weak ciphers that are disabled by default. This currently
-# only includes RC4 based ciphers.
+# 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
# 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"
"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", "capieng" ],
+ "stdio" => [ "apps", "capieng", "egd" ],
"apps" => [ "tests" ],
"comp" => [ "zlib" ],
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
# To remove something from %disabled, use "enable-foo".
# For symmetry, "disable-foo" is a synonym for "no-foo".
-my $no_sse2=0;
-
&usage if ($#ARGV < 0);
my $user_cflags="";
elsif (/^zlib-dynamic$/)
{ }
elsif (/^sse2$/)
- { $no_sse2 = 1; }
+ { }
elsif (/^engine$/)
{
@{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
{
push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
print " OPENSSL_NO_$WHAT";
-
- if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; }
}
}
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)
# 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}}, "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/);
}
}
}
-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") {
- use lib catdir(dirname(__FILE__),"util");
use with_fallback qw(Text::Template);
sub cleandir {
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,
# 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
# If the destination doesn't exist in source, it can only be
# a generated file in the build tree.
- if ($ddest ne "" && ! -f $ddest) {
+ if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) {
$ddest = cleanfile($buildd, $_, $blddir);
if ($unified_info{rename}->{$ddest}) {
$ddest = $unified_info{rename}->{$ddest};
# 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) }
grep { /\.h$/ } keys %{$unified_info{generate}})) {
$d = $unified_info{rename}->{$d};
}
$unified_info{depends}->{$ddest}->{$d} = 1;
- # 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}->{source}}, $i
- unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}};
- }
}
}
# If the destination doesn't exist in source, it can only be
# a generated file in the build tree.
- if (! -f $ddest) {
+ if ($ddest eq $src_configdata || ! -f $ddest) {
$ddest = cleanfile($buildd, $_, $blddir);
if ($unified_info{rename}->{$ddest}) {
$ddest = $unified_info{rename}->{$ddest};
}
}
+ # 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
# One level structures
foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
# Includes
foreach my $dest (sort keys %{$unified_info{includes}}) {
if (defined($unified_info{includes}->{$dest}->{build})) {
- my @source_includes =
- ( @{$unified_info{includes}->{$dest}->{source}} );
+ 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) {
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);
######################################################################
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) {
# 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|[:\[]|;