X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=Configure;h=b66e2513f5dfdad7b7ff8c517d4b688a4dcf8f19;hp=b30b57f209b69fa28247caf31d1c29ffb11c23ab;hb=643d91fea409b0f010ce990f8f0fac234ae058bc;hpb=a66234bc86a959e628e2010687c6fdf0fdbfdac3 diff --git a/Configure b/Configure index b30b57f209..b66e2513f5 100755 --- a/Configure +++ b/Configure @@ -1,6 +1,6 @@ #! /usr/bin/env perl # -*- mode: perl; -*- -# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2017 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 @@ -9,12 +9,15 @@ ## Configure -- OpenSSL source tree configuration script -require 5.10.0; +use 5.10.0; use strict; +use Config; +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. @@ -59,13 +62,29 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # 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- build without specified algorithm (rsa, idea, rc5, ...) # - + 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 @@ -85,47 +104,51 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lx # past these. # DEBUG_UNUSED enables __owur (warn unused result) checks. +# -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. + 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" + . " -Wextra" + . " -Wno-unused-parameter" + . " -Wno-missing-field-initializers" + . " -Wswitch" . " -Wsign-compare" . " -Wmissing-prototypes" . " -Wshadow" . " -Wformat" . " -Wtype-limits" + . " -Wundef" . " -Werror" ; # These are used in addition to $gcc_devteam_warn when the compiler is clang. # TODO(openssl-team): fix problems and investigate if (at least) the # following warnings can also be enabled: -# -Wswitch-enum # -Wcast-align -# -Wunreachable-code +# -Wunreachable-code -- no, too ugly/compiler-specific # -Wlanguage-extension-token -- no, we use asm() # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc # -Wextended-offsetof -- no, needed in CMS ASN1 code my $clang_devteam_warn = "" - . " -Qunused-arguments" - . " -Wextra" - . " -Wno-unused-parameter" - . " -Wno-missing-field-initializers" + . " -Wswitch-default" + . " -Wno-parentheses-equality" . " -Wno-language-extension-token" . " -Wno-extended-offsetof" . " -Wconditional-uninitialized" . " -Wincompatible-pointer-types-discards-qualifiers" . " -Wmissing-variable-declarations" + . " -Wno-unknown-warning-option" ; # This adds backtrace information to the memory leak info. Is only used @@ -184,6 +207,37 @@ 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) { + die "reconfiguring with other arguments present isn't supported" + if scalar @argvcopy > 1; + 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)); + $config{perlenv} = $configdata::config{perlenv} // {}; + + print "Reconfiguring with: ", join(" ",@argvcopy), "\n"; + foreach (sort keys %{$config{perlenv}}) { + print " $_ = $config{perlenv}->{$_}\n"; + } + } 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"; @@ -215,13 +269,13 @@ foreach (sort glob($pattern)) { &read_config($_); } -if (defined $ENV{$local_config_envname}) { +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'); + $pattern = catfile(env($local_config_envname), '*.conf'); } foreach (sort glob($pattern)) { @@ -229,36 +283,31 @@ if (defined $ENV{$local_config_envname}) { } } - -print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n"; - $config{prefix}=""; $config{openssldir}=""; $config{processor}=""; $config{libdir}=""; $config{cross_compile_prefix}=""; -$config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/"; -my $nofipscanistercheck=0; -$config{baseaddr}="0xFB00000"; my $auto_threads=1; # enable threads automatically? true by default my $default_ranlib; -$config{fips}=0; # Top level directories to build -$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools", "fuzz" ]; +$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ]; # crypto/ subdirectories to build $config{sdirs} = [ "objects", - "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", - "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes", + "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3", + "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes", "bn", "ec", "rsa", "dsa", "dh", "dso", "engine", "buffer", "bio", "stack", "lhash", "rand", "err", "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", - "cms", "ts", "srp", "cmac", "ct", "async", "kdf" + "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store" ]; +# test/ subdirectories to build +$config{tdirs} = [ "ossl_shim" ]; # Known TLS and DTLS protocols -my @tls = qw(ssl3 tls1 tls1_1 tls1_2); +my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3); my @dtls = qw(dtls1 dtls1_2); # Explicitly known options that are possible to disable. They can @@ -267,6 +316,7 @@ my @dtls = qw(dtls1 dtls1_2); my @disablables = ( "afalgeng", + "aria", "asan", "asm", "async", @@ -286,6 +336,7 @@ my @disablables = ( "ct", "deprecated", "des", + "devcryptoeng", "dgram", "dh", "dsa", @@ -300,6 +351,7 @@ my @disablables = ( "egd", "engine", "err", + "external-tests", "filenames", "fuzz-libfuzzer", "fuzz-afl", @@ -330,6 +382,9 @@ my @disablables = ( "sctp", "seed", "shared", + "siphash", + "sm3", + "sm4", "sock", "srp", "srtp", @@ -338,11 +393,13 @@ my @disablables = ( "ssl-trace", "static-engine", "stdio", + "tests", "threads", "tls", + "tls13downgrade", "ts", "ubsan", - "ui", + "ui-console", "unit-test", "whirlpool", "weak-ssl-ciphers", @@ -352,13 +409,14 @@ my @disablables = ( foreach my $proto ((@tls, @dtls)) { push(@disablables, $proto); - push(@disablables, "$proto-method"); + push(@disablables, "$proto-method") unless $proto eq "tls1_3"; } my %deprecated_disablables = ( "ssl2" => undef, "buf-freelists" => undef, - "ripemd" => "rmd160" + "ripemd" => "rmd160", + "ui" => "ui-console", ); # All of the following is disabled by default (RC5 was enabled before 0.9.8): @@ -367,8 +425,10 @@ our %disabled = ( # "what" => "comment" "asan" => "default", "crypto-mdebug" => "default", "crypto-mdebug-backtrace" => "default", + "devcryptoeng" => "default", "ec_nistp_64_gcc_128" => "default", "egd" => "default", + "external-tests" => "default", "fuzz-libfuzzer" => "default", "fuzz-afl" => "default", "heartbeats" => "default", @@ -380,6 +440,9 @@ our %disabled = ( # "what" => "comment" "ssl3" => "default", "ssl3-method" => "default", "ubsan" => "default", + #TODO(TLS1.3): Temporarily disabled while this is a WIP + "tls1_3" => "default", + "tls13downgrade" => "default", "unit-test" => "default", "weak-ssl-ciphers" => "default", "zlib" => "default", @@ -400,29 +463,12 @@ my @disable_cascades = ( "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" ], @@ -432,14 +478,16 @@ my @disable_cascades = ( # Without position independent code, there can be no shared libraries or DSOs "pic" => [ "shared" ], "shared" => [ "dynamic-engine" ], - "engine" => [ "afalgeng" ], + "engine" => [ "afalgeng", "devcryptoeng" ], # no-autoalginit is only useful when building non-shared "autoalginit" => [ "shared", "apps" ], - "stdio" => [ "apps", "capieng" ], + "stdio" => [ "apps", "capieng", "egd" ], "apps" => [ "tests" ], - "comp" => [ "zlib" ], + "tests" => [ "external-tests" ], + "comp" => [ "zlib" ], + "ec" => [ "tls1_3" ], sub { !$disabled{"unit-test"} } => [ "heartbeats" ], sub { !$disabled{"msan"} } => [ "asm" ], @@ -483,62 +531,22 @@ my $target=""; $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{CC} = $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, ") { - 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) +# If you change this, update apps/version.c +my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom); +my @seed_sources = (); +while (@argvcopy) { + $_ = shift @argvcopy; + + # Support env variable assignments among the options + if (m|^(\w+)=(.+)?$|) + { + $config{perlenv}->{$1} = $2; + next; + } + # 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. @@ -656,7 +664,7 @@ foreach (@argvcopy) { $config{processor}=386; } elsif (/^fips$/) { - $config{fips}=1; + die "FIPS mode not supported\n"; } elsif (/^rsaref$/) { @@ -666,8 +674,7 @@ foreach (@argvcopy) } elsif (/^nofipscanistercheck$/) { - $config{fips} = 1; - $nofipscanistercheck = 1; + die "FIPS mode not supported\n"; } elsif (/^[-+]/) { @@ -705,14 +712,15 @@ foreach (@argvcopy) { $withargs{fuzzer_include}=$1; } - elsif (/^--with-fipslibdir=(.*)$/) - { - $config{fipslibdir}="$1/"; - } - elsif (/^--with-baseaddr=(.*)$/) + elsif (/^--with-rand-seed=(.*)$/) { - $config{baseaddr}="$1"; - } + foreach my $x (split(m|,|, $1)) + { + die "Unknown --with-rand-seed choice $x\n" + if ! grep { $x eq $_ } @known_seed_sources; + push @seed_sources, $x; + } + } elsif (/^--cross-compile-prefix=(.*)$/) { $config{cross_compile_prefix}=$1; @@ -725,9 +733,22 @@ foreach (@argvcopy) { $libs.=$_." "; } + elsif (/^-framework$/) + { + $libs.=$_." ".shift(@argvcopy)." "; + } + 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"; @@ -749,7 +770,7 @@ foreach (@argvcopy) } unless ($_ eq $target || /^no-/ || /^disable-/) { - # "no-..." follows later after implied disactivations + # "no-..." follows later after implied deactivations # have been derived. (Don't take this too seriously, # we really only write OPTIONS to the Makefile out of # nostalgia.) @@ -776,14 +797,23 @@ foreach (@argvcopy) } } -if ($config{fips}) - { - delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/); - } -else - { - @{$config{dirs}} = grep !/^fips$/, @{$config{dirs}}; - } +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 (scalar(@seed_sources) == 0) { + print "Using implicit seed configuration\n"; + push @seed_sources, 'os'; +} +die "Cannot seed with none and anything else" + if scalar(grep { $_ eq 'none' } @seed_sources) > 0 + && scalar(@seed_sources) > 1; +push @{$config{openssl_other_defines}}, + map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" } + @seed_sources; my @tocheckfor = (keys %disabled); while (@tocheckfor) { @@ -800,7 +830,9 @@ while (@tocheckfor) { @tocheckfor = (keys %new_tocheckfor); } +our $die = sub { die @_; }; if ($target eq "TABLE") { + local $die = sub { warn @_; }; foreach (sort keys %table) { print_table_entry($_, "TABLE"); } @@ -815,6 +847,7 @@ if ($target eq "LIST") { } if ($target eq "HASH") { + local $die = sub { warn @_; }; print "%table = (\n"; foreach (sort keys %table) { print_table_entry($_, "HASH"); @@ -822,11 +855,91 @@ if ($target eq "HASH") { exit 0; } +print "Configuring OpenSSL version $config{version} ($config{version_num})\n"; +print "for $target\n"; + # Backward compatibility? if ($target =~ m/^CygWin32(-.*)$/) { $target = "Cygwin".$1; } +# Support for legacy targets having a name starting with 'debug-' +my ($d, $t) = $target =~ m/^(debug-)?(.*)$/; +if ($d) { + $config{build_type} = "debug"; + + # If we do not find debug-foo in the table, the target is set to foo. + if (!$table{$target}) { + $target = $t; + } +} +$config{target} = $target; +my %target = resolve_config($target); + +&usage if (!%target || $target{template}); + +%target = ( %{$table{DEFAULTS}}, %target ); + +# Make the flags to build DSOs the same as for shared libraries unless they +# are already defined +$target{dso_cflags} = $target{shared_cflag} unless defined $target{dso_cflags}; +$target{dso_cxxflags} = $target{shared_cxxflag} unless defined $target{dso_cxxflags}; +$target{dso_lflags} = $target{shared_ldflag} unless defined $target{dso_lflags}; +{ + my $shared_info_pl = + catfile(dirname($0), "Configurations", "shared-info.pl"); + my %shared_info = read_eval_file($shared_info_pl); + push @{$target{_conf_fname_int}}, $shared_info_pl; + my $si = $target{shared_target}; + while (ref $si ne "HASH") { + last if ! defined $si; + if (ref $si eq "CODE") { + $si = $si->(); + } else { + $si = $shared_info{$si}; + } + } + + # Some of the 'shared_target' values don't have any entried in + # %shared_info. That's perfectly fine, AS LONG AS the build file + # template knows how to handle this. That is currently the case for + # Windows and VMS. + if (defined $si) { + # Just as above, copy certain shared_* attributes to the corresponding + # dso_ attribute unless the latter is already defined + $si->{dso_cflags} = $si->{shared_cflag} unless defined $si->{dso_cflags}; + $si->{dso_cxxflags} = $si->{shared_cxxflag} unless defined $si->{dso_cxxflags}; + $si->{dso_lflags} = $si->{shared_ldflag} unless defined $si->{dso_lflags}; + foreach (sort keys %$si) { + $target{$_} = defined $target{$_} + ? add($si->{$_})->($target{$_}) + : $si->{$_}; + } + } +} + +my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}}); +$config{conf_files} = [ sort keys %conf_files ]; + +foreach my $feature (@{$target{disable}}) { + if (exists $deprecated_disablables{$feature}) { + warn "***** config $target disables deprecated feature $feature\n"; + } elsif (!grep { $feature eq $_ } @disablables) { + die "***** config $target disables unknown feature $feature\n"; + } + $disabled{$feature} = 'config'; +} +foreach my $feature (@{$target{enable}}) { + if ("default" eq ($disabled{$_} // "")) { + if (exists $deprecated_disablables{$feature}) { + warn "***** config $target enables deprecated feature $feature\n"; + } elsif (!grep { $feature eq $_ } @disablables) { + die "***** config $target enables unknown feature $feature\n"; + } + delete $disabled{$_}; + } +} + foreach (sort (keys %disabled)) { $config{options} .= " no-$_"; @@ -856,96 +969,87 @@ foreach (sort (keys %disabled)) @{$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"; + push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT"; + print " OPENSSL_NO_$WHAT"; - # 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)"; + if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; } } } print "\n"; } -print "Configuring for $target\n"; - -# Support for legacy targets having a name starting with 'debug-' -my ($d, $t) = $target =~ m/^(debug-)?(.*)$/; -if ($d) { - $config{build_type} = "debug"; - - # If we do not find debug-foo in the table, the target is set to foo. - if (!$table{$target}) { - $target = $t; - } -} -$config{target} = $target; -my %target = resolve_config($target); - -&usage if (!%target || $target{template}); - -%target = ( %{$table{DEFAULTS}}, %target ); - +$target{cxxflags}=$target{cflags} unless defined $target{cxxflags}; $target{exe_extension}=""; $target{exe_extension}=".exe" if ($config{target} eq "DJGPP" || $config{target} =~ /^(?:Cygwin|mingw)/); $target{exe_extension}=".pm" if ($config{target} =~ /vos/); ($target{shared_extension_simple}=$target{shared_extension}) - =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||; + =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||; $target{dso_extension}=$target{shared_extension_simple}; ($target{shared_import_extension}=$target{shared_extension_simple}.".a") if ($config{target} =~ /^(?:Cygwin|mingw)/); -$config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'} +$config{cross_compile_prefix} = env('CROSS_COMPILE') 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{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} || + env('HASHBANGPERL') || env('PERL') || "/usr/bin/env perl"; +$target{cc} = env('CC') || $target{cc} || "cc"; +$target{cxx} = env('CXX') || $target{cxx} || "c++"; +$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{ar} = env('AR') || $target{ar} || "ar"; +$target{nm} = env('NM') || $target{nm} || "nm"; $target{rc} = - $ENV{'RC'} || $ENV{'WINDRES'} || $target{rc} || "windres"; + env('RC') || env('WINDRES') || $target{rc} || "windres"; -# Cache the C compiler command for reconfiguration +# 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{cxx} = $target{cxx}; +$config{build_file} = $target{build_file}; # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_ # or release_ attributes. # Do it in such a way that no spurious space is appended (hence the grep). $config{defines} = []; $config{cflags} = ""; +$config{cxxflags} = ""; $config{ex_libs} = ""; $config{shared_ldflag} = ""; @@ -956,6 +1060,25 @@ $target{build_scheme} = [ $target{build_scheme} ] 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) @@ -999,15 +1122,6 @@ if (!$disabled{dso} && $target{dso_scheme} ne "") $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne ""); -if ($disabled{asm}) - { - if ($config{fips}) - { - @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}}; - @{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}}; - } - } - # If threads aren't disabled, check how possible they are unless ($disabled{threads}) { if ($auto_threads) { @@ -1048,8 +1162,7 @@ if (defined($disabled{"deprecated"})) { if ($target{shared_target} eq "") { $no_shared_warn = 1 - if ((!$disabled{shared} || !$disabled{"dynamic-engine"}) - && !$config{fips}); + if (!$disabled{shared} || !$disabled{"dynamic-engine"}); $disabled{shared} = "no-shared-target"; $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} = "no-shared-target"; @@ -1063,10 +1176,6 @@ if ($disabled{"dynamic-engine"}) { $config{dynamic_engines} = 1; } -unless ($disabled{"fuzz-libfuzzer"}) { - $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls "; -} - unless ($disabled{asan}) { $config{cflags} .= "-fsanitize=address "; } @@ -1092,8 +1201,11 @@ unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} # This saves the build files from having to check if ($disabled{pic}) { - $target{shared_cflag} = $target{shared_ldflag} = - $target{shared_rcflag} = ""; + foreach (qw(shared_cflag shared_cxxflag shared_ldflag + dso_cflags dso_cxxflags dso_lflags)) + { + $target{$_} = ""; + } } else { @@ -1117,15 +1229,14 @@ unless ($disabled{asm}) { push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/); push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/); - if ($config{fips}) { - push @{$config{openssl_other_defines}}, "OPENSSL_FIPS"; - } - if ($target{sha1_asm_src}) { push @{$config{defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/); 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"; } @@ -1157,38 +1268,35 @@ unless ($disabled{asm}) { 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 ( ) { - # Find the version number and save the major. - m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|; - my $compiler_major = $1; +my %predefined = compiler_predefined($target{cc}); + +# Check for makedepend capabilities. +if (!$disabled{makedepend}) { + if ($config{target} =~ /^(VC|vms)-/) { + # For VC- and vms- targets, there's nothing more to do here. The + # functionality is hard coded in the corresponding build files for + # cl (Windows) and CC/DECC (VMS). + } elsif ($predefined{__GNUC__} >= 3) { # 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--); + $config{makedepprog} = "\$(CROSS_COMPILE)$target{cc}"; + } else { + # In all other cases, we look for 'makedepend', and disable the + # capability if not found. + $config{makedepprog} = which('makedepend'); + $disabled{makedepend} = "unavailable" unless $config{makedepprog}; } - close(PIPE); - - $config{makedepprog} = which('makedepend') unless $config{makedepprog}; - $disabled{makedepend} = "unavailable" unless $config{makedepprog}; } - # Deal with bn_ops ################################################### $config{bn_ll} =0; @@ -1226,16 +1334,23 @@ if (defined($config{api})) { push @{$config{defines}}, $apiflag; } +if (defined($predefined{__clang__}) && !$disabled{asm}) { + $config{cflags} .= " -Qunused-arguments"; +} + if ($strict_warnings) { my $wopt; - die "ERROR --strict-warnings requires gcc or clang" - unless $ecc eq 'gcc' || $ecc eq 'clang'; + my $gccver = $predefined{__GNUC__} // -1; + + die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike" + unless $gccver >= 4; + $gcc_devteam_warn .= " -Wmisleading-indentation" if $gccver >= 6; 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) { @@ -1256,7 +1371,7 @@ unless ($disabled{"crypto-mdebug-backtrace"}) } } -if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; } +if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; $config{cxxflags}="$config{cxxflags}$user_cflags";} else { $no_user_cflags=1; } if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; } else { $no_user_defines=1; } @@ -1292,32 +1407,6 @@ 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; - - 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"); use with_fallback qw(Text::Template); sub cleandir { @@ -1353,6 +1442,47 @@ if ($builder eq "unified") { 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" ] @@ -1366,9 +1496,14 @@ if ($builder eq "unified") { push @build_infos, [ catdir("engines", $_), "build.info" ] if (-f catfile($srcdir, "engines", $_, "build.info")); } + foreach (@{$config{tdirs}}) { + push @build_infos, [ catdir("test", $_), "build.info" ] + if (-f catfile($srcdir, "test", $_, "build.info")); + } $config{build_infos} = [ ]; + my %ordinals = (); foreach (@build_infos) { my $sourced = catdir($srcdir, $_->[0]); my $buildd = catdir($blddir, $_->[0]); @@ -1390,7 +1525,6 @@ if ($builder eq "unified") { my @intermediates = (); my @rawlines = (); - my %ordinals = (); my %sources = (); my %shared_sources = (); my %includes = (); @@ -1400,8 +1534,10 @@ if ($builder eq "unified") { my %generate = (); 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, @@ -1532,7 +1668,7 @@ if ($builder eq "unified") { || $target_kind eq $target{build_file}."(".$builder_platform.")"); } }, - qr/^(?:#.*|\s*)$/ => sub { }, + qr/^\s*(?:#.*)?$/ => sub { }, "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }, "BEFORE" => sub { if ($buildinfo_debug) { @@ -1662,33 +1798,24 @@ EOF } # Additionally, we set up sharednames for libraries that don't - # have any, as themselves. - foreach (keys %{$unified_info{libraries}}) { + # have any, as themselves. Only for libraries that aren't + # explicitly static. + foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) { if (!defined $unified_info{sharednames}->{$_}) { $unified_info{sharednames}->{$_} = $_ } } - } - foreach (keys %ordinals) { - my $dest = $_; - my $ddest = cleanfile($buildd, $_, $blddir); - if ($unified_info{rename}->{$ddest}) { - $ddest = $unified_info{rename}->{$ddest}; - } - foreach (@{$ordinals{$dest}}) { - my %known_ordinals = - ( - crypto => - cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir), - ssl => - cleanfile($sourced, catfile("util", "libssl.num"), $blddir) - ); - my $o = $known_ordinals{$_}; - die "Ordinals for $ddest defined more than once\n" - if $unified_info{ordinals}->{$ddest}; - $unified_info{ordinals}->{$ddest} = [ $_, $o ]; + # Check that we haven't defined any library as both shared and + # explicitly static. That is forbidden. + my @doubles = (); + foreach (grep /\.a$/, keys %{$unified_info{libraries}}) { + (my $l = $_) =~ s/\.a$//; + push @doubles, $l if defined $unified_info{sharednames}->{$l}; } + die "these libraries are both explicitly static and shared:\n ", + join(" ", @doubles), "\n" + if @doubles; } foreach (keys %sources) { @@ -1705,9 +1832,11 @@ EOF if (! -f $s) { $s = cleanfile($buildd, $_, $blddir); } - # We recognise C and asm files - if ($s =~ /\.[csS]\b$/) { - (my $o = $_) =~ s/\.[csS]\b$/.o/; + # We recognise C++, C and asm files + if ($s =~ /\.(cc|cpp|c|s|S)$/) { + my $o = $_; + $o =~ s/\.[csS]$/.o/; # C and assembler + $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ $o = cleanfile($buildd, $o, $blddir); $unified_info{sources}->{$ddest}->{$o} = 1; $unified_info{sources}->{$o}->{$s} = 1; @@ -1731,12 +1860,27 @@ EOF if (! -f $s) { $s = cleanfile($buildd, $_, $blddir); } - # We recognise C and asm files - if ($s =~ /\.[csS]\b$/) { - (my $o = $_) =~ s/\.[csS]\b$/.o/; + + if ($s =~ /\.(cc|cpp|c|s|S)$/) { + # We recognise C++, C and asm files + my $o = $_; + $o =~ s/\.[csS]$/.o/; # C and assembler + $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ $o = cleanfile($buildd, $o, $blddir); $unified_info{shared_sources}->{$ddest}->{$o} = 1; $unified_info{sources}->{$o}->{$s} = 1; + } elsif ($s =~ /\.rc$/) { + # We also recognise resource files + my $o = $_; + $o =~ s/\.rc$/.res/; # Resource configuration + my $o = cleanfile($buildd, $o, $blddir); + $unified_info{shared_sources}->{$ddest}->{$o} = 1; + $unified_info{sources}->{$o}->{$s} = 1; + } elsif ($s =~ /\.(def|map|opt)$/) { + # We also recognise .def / .map / .opt files + # We know they are generated files + my $def = cleanfile($buildd, $s, $blddir); + $unified_info{shared_sources}->{$ddest}->{$def} = 1; } else { die "unrecognised source file type for shared library: $s\n"; } @@ -1784,9 +1928,16 @@ EOF $d = cleanfile($buildd, $_, $blddir); } # Take note if the file to depend on is being renamed + # Take extra care with files ending with .a, they should + # be treated without that extension, and the extension + # should be added back after treatment. + $d =~ /(\.a)?$/; + my $e = $1 // ""; + $d = $`; if ($unified_info{rename}->{$d}) { $d = $unified_info{rename}->{$d}; } + $d .= $e; $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 @@ -1821,6 +1972,14 @@ EOF } } + my $ordinals_text = join(', ', sort keys %ordinals); + warn <<"EOF" if $ordinals_text; + +WARNING: ORDINALS were specified for $ordinals_text +They are ignored and should be replaced with a combination of GENERATE, +DEPEND and SHARED_SOURCE. +EOF + ### Make unified_info a bit more efficient # One level structures foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) { @@ -1856,7 +2015,9 @@ EOF foreach (grep /_(asm|aux)_src$/, keys %target) { my $src = $_; (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/; - ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g; + $target{$obj} = $target{$src}; + $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler + $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++ } # Write down our configuration where it fits ######################### @@ -1880,6 +2041,22 @@ foreach (sort keys %config) { print OUT " ", $_, " => [ ", join(", ", map { quotify("perl", $_) } @{$config{$_}}), " ],\n"; + } elsif (ref($config{$_}) eq "HASH") { + print OUT " ", $_, " => {"; + if (scalar keys %{$config{$_}} > 0) { + print OUT "\n"; + foreach my $key (sort keys %{$config{$_}}) { + print OUT " ", + join(" => ", + quotify("perl", $key), + defined $config{$_}->{$key} + ? quotify("perl", $config{$_}->{$key}) + : "undef"); + print OUT ",\n"; + } + print OUT " "; + } + print OUT "},\n"; } else { print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n" } @@ -1984,62 +2161,32 @@ EOF print OUT "1;\n"; close(OUT); - +print "\n"; +print "PROCESSOR =$config{processor}\n" if $config{processor}; +print "PERL =$config{perl}\n"; +print "PERLVERSION =$Config{version} for $Config{archname}\n"; +print "HASHBANGPERL =$config{hashbangperl}\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 "CXX =$config{cross_compile_prefix}$target{cxx}\n" + if defined $target{cxx}; +print "CXXFLAG =$target{cxxflags} $config{cxxflags}\n" + if defined $target{cxx}; print "DEFINES =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n"; -print "LFLAG =$target{lflags}\n"; -print "PLIB_LFLAG =$target{plib_lflags}\n"; +#print "RANLIB =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ? +# "$config{cross_compile_prefix}ranlib" : +# "$target{ranlib}", "\n"; print "EX_LIBS =$target{ex_libs} $config{ex_libs}\n"; -print "APPS_OBJ =$target{apps_obj}\n"; -print "CPUID_OBJ =$target{cpuid_obj}\n"; -print "UPLINK_OBJ =$target{uplink_obj}\n"; -print "BN_ASM =$target{bn_obj}\n"; -print "EC_ASM =$target{ec_obj}\n"; -print "DES_ENC =$target{des_obj}\n"; -print "AES_ENC =$target{aes_obj}\n"; -print "BF_ENC =$target{bf_obj}\n"; -print "CAST_ENC =$target{cast_obj}\n"; -print "RC4_ENC =$target{rc4_obj}\n"; -print "RC5_ENC =$target{rc5_obj}\n"; -print "MD5_OBJ_ASM =$target{md5_obj}\n"; -print "SHA1_OBJ_ASM =$target{sha1_obj}\n"; -print "RMD160_OBJ_ASM=$target{rmd160_obj}\n"; -print "CMLL_ENC =$target{cmll_obj}\n"; -print "MODES_OBJ =$target{modes_obj}\n"; -print "PADLOCK_OBJ =$target{padlock_obj}\n"; -print "CHACHA_ENC =$target{chacha_obj}\n"; -print "POLY1305_OBJ =$target{poly1305_obj}\n"; -print "BLAKE2_OBJ =$target{blake2_obj}\n"; -print "PROCESSOR =$config{processor}\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 "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l}; -print "SIXTY_FOUR_BIT mode\n" if $config{b64}; -print "THIRTY_TWO_BIT mode\n" if $config{b32}; -print "BN_LLONG mode\n" if $config{bn_ll}; -print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int; my %builders = ( unified => sub { run_dofile(catfile($blddir, $target{build_file}), - $config{build_file_template}, - catfile($srcdir, "Configurations", "common.tmpl")); + @{$config{build_file_templates}}); }, ); $builders{$builder}->($builder_platform, @builder_opts); -print <<"EOF"; - -Configured for $target. -EOF - print <<"EOF" if ($disabled{threads} eq "unavailable"); The library could not be configured for supporting multi-threaded @@ -2193,24 +2340,38 @@ sub add { sub { _add($separator, @_, @x) }; } +sub read_eval_file { + my $fname = shift; + my $content; + my @result; + + open F, "< $fname" or die "Can't open '$fname': $!\n"; + { + undef local $/; + $content = ; + } + close F; + { + local $@; + + @result = ( eval $content ); + warn $@ if $@; + } + return wantarray ? @result : $result[0]; +} + # configuration reader, evaluates the input file as a perl script and expects # it to fill %targets with target configurations. Those are then added to # %table. sub read_config { my $fname = shift; - open(CONFFILE, "< $fname") - or die "Can't open configuration file '$fname'!\n"; - my $x = $/; - undef $/; - my $content = ; - $/ = $x; - close(CONFFILE); - my %targets = (); + my %targets; + { - local %table = %::table; # Protect %table from tampering + # Protect certain tables from tampering + local %table = (); - eval $content; - warn $@ if $@; + %targets = read_eval_file($fname); } # For each target, check that it's configured with a hash table. @@ -2222,7 +2383,9 @@ sub read_config { warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n"; } delete $targets{$_}; - } + } else { + $targets{$_}->{_conf_fname_int} = add([ $fname ]); + } } %table = (%table, %targets); @@ -2391,13 +2554,40 @@ sub run_dofile 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 compiler_predefined { + state %predefined; + my $default_compiler = shift; + + return () if $^O eq 'VMS'; + + die 'compiler_predefines called without a default compiler' + unless $default_compiler; + + if (! $predefined{$default_compiler}) { + my $cc = "$config{cross_compile_prefix}$default_compiler"; + + $predefined{$default_compiler} = {}; + + # collect compiler pre-defines from gcc or gcc-alike... + open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |"); + while (my $l = ) { + $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last; + $predefined{$default_compiler}->{$1} = $2 // ''; + } + close(PIPE); + } + + return %{$predefined{$default_compiler}}; +} + sub which { my ($name)=@_; @@ -2419,6 +2609,19 @@ sub which } } +sub env +{ + my $name = shift; + + # Note that if $ENV{$name} doesn't exist or is undefined, + # $config{perlenv}->{$name} will be created with the value + # undef. This is intentional. + + $config{perlenv}->{$name} = $ENV{$name} + if ! exists $config{perlenv}->{$name}; + return $config{perlenv}->{$name}; +} + # Configuration printer ############################################## sub print_table_entry @@ -2438,41 +2641,53 @@ 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", ); @@ -2515,7 +2730,7 @@ sub isabsolute { # 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|[:\[]|; @@ -2551,6 +2766,14 @@ sub quotify { 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 =