#! /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
## 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.
# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
# library and will be loaded in run-time by the OpenSSL library.
# sctp include SCTP support
-# 386 generate 80386 code
# enable-weak-ssl-ciphers
-# Enable weak ciphers that are disabled by default. This currently
-# only includes RC4 based ciphers.
-# no-sse2 disables IA-32 SSE2 code, above option implies no-sse2
+# Enable weak ciphers that are disabled by default.
+# 386 generate 80386 code in assembly modules
+# no-sse2 disables IA-32 SSE2 code in assembly modules, the above
+# mentioned '386' option implies this one
# no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
# -<xxx> +<xxx> compiler options are passed through
+# -static while -static is also a pass-through compiler option (and
+# as such is limited to environments where it's actually
+# meaningful), it triggers a number configuration options,
+# namely no-dso, no-pic, no-shared and no-threads. It is
+# argued that the only reason to produce statically linked
+# binaries (and in context it means executables linked with
+# -static flag, and not just executables linked with static
+# libcrypto.a) is to eliminate dependency on specific run-time,
+# a.k.a. libc version. The mentioned config options are meant
+# to achieve just that. Unfortunately on Linux it's impossible
+# to eliminate the dependency completely for openssl executable
+# because of getaddrinfo and gethostbyname calls, which can
+# invoke dynamically loadable library facility anyway to meet
+# the lookup requests. For this reason on Linux statically
+# linked openssl executable has rather debugging value than
+# production quality.
#
# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
# provided to stack calls. Generates unique stack functions for
# 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
$config{sourcedir} = abs2rel($srcdir);
$config{builddir} = abs2rel($blddir);
+# Collect reconfiguration information if needed
+my @argvcopy=@ARGV;
+
+if (grep /^reconf(igure)?$/, @argvcopy) {
+ if (-f "./configdata.pm") {
+ my $file = "./configdata.pm";
+ unless (my $return = do $file) {
+ die "couldn't parse $file: $@" if $@;
+ die "couldn't do $file: $!" unless defined $return;
+ die "couldn't run $file" unless $return;
+ }
+
+ @argvcopy = defined($configdata::config{perlargv}) ?
+ @{$configdata::config{perlargv}} : ();
+ die "Incorrect data to reconfigure, please do a normal configuration\n"
+ if (grep(/^reconf/,@argvcopy));
+ $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";
&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)) {
}
}
-
-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
my @disablables = (
"afalgeng",
+ "aria",
"asan",
"asm",
"async",
"ct",
"deprecated",
"des",
+ "devcryptoeng",
"dgram",
"dh",
"dsa",
"egd",
"engine",
"err",
+ "external-tests",
"filenames",
"fuzz-libfuzzer",
"fuzz-afl",
"sctp",
"seed",
"shared",
+ "siphash",
+ "sm3",
+ "sm4",
"sock",
"srp",
"srtp",
"ssl-trace",
"static-engine",
"stdio",
+ "tests",
"threads",
"tls",
+ "tls13downgrade",
"ts",
"ubsan",
- "ui",
+ "ui-console",
"unit-test",
"whirlpool",
"weak-ssl-ciphers",
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):
our %disabled = ( # "what" => "comment"
+ "aria" => "default",
"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",
"md2" => "default",
"msan" => "default",
"rc5" => "default",
"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",
"zlib-dynamic" => "default",
- "crypto-mdebug" => "default",
- "crypto-mdebug-backtrace" => "default",
- "heartbeats" => "default",
);
# Note: => pair form used for aesthetics, not to truly make a hash table
"dgram" => [ "dtls", "sctp" ],
"sock" => [ "dgram" ],
"dtls" => [ @dtls ],
-
- # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
- "md5" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
- "sha" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
-
- # Additionally, SSL 3.0 requires either RSA or DSA+DH
- sub { $disabled{rsa}
- && ($disabled{dsa} || $disabled{dh}); }
- => [ "ssl" ],
-
- # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
- # or ECDSA + ECDH. (D)TLS 1.2 has this requirement as well.
- # (XXX: We don't support PSK-only builds).
- sub { $disabled{rsa}
- && ($disabled{dsa} || $disabled{dh})
- && ($disabled{ecdsa} || $disabled{ecdh}); }
- => [ "tls1", "tls1_1", "tls1_2",
- "dtls1", "dtls1_2" ],
+ sub { 0 == scalar grep { !$disabled{$_} } @dtls }
+ => [ "dtls" ],
"tls" => [ @tls ],
-
- # SRP and HEARTBEATS require TLSEXT
- "tlsext" => [ "srp", "heartbeats" ],
+ sub { 0 == scalar grep { !$disabled{$_} } @tls }
+ => [ "tls" ],
"crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
# 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" ],
$config{options}="";
$config{build_type} = "release";
-my @argvcopy=@ARGV;
-
-if (grep /^reconf(igure)?$/, @argvcopy) {
- if (-f "./configdata.pm") {
- my $file = "./configdata.pm";
- unless (my $return = do $file) {
- die "couldn't parse $file: $@" if $@;
- die "couldn't do $file: $!" unless defined $return;
- die "couldn't run $file" unless $return;
- }
-
- @argvcopy = defined($configdata::config{perlargv}) ?
- @{$configdata::config{perlargv}} : ();
- die "Incorrect data to reconfigure, please do a normal configuration\n"
- if (grep(/^reconf/,@argvcopy));
- $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
- if defined($configdata::config{cross_compile_prefix});
- $ENV{CROSS_COMPILE} = $configdata::config{cc}
- if defined($configdata::config{cc});
-
- print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
- print " CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
- if $ENV{CROSS_COMPILE};
- print " CC = ",$ENV{CC},"\n" if $ENV{CC};
- } elsif (open IN, "<Makefile") {
- #
- # THIS SECTION IS TEMPORARY, it helps transitioning from Makefile
- # centered information gathering the reading configdata.pm
- #
- while (<IN>) {
- s|\R$||;
- if (/^CONFIGURE_ARGS=\s*(.*)\s*/) {
- # Older form, we split the string and hope for the best
- @argvcopy = split /\s+/, $_;
- die "Incorrect data to reconfigure, please do a normal configuration\n"
- if (grep(/^reconf/,@argvcopy));
- } elsif (/^CROSS_COMPILE=\s*(.*)/) {
- $ENV{CROSS_COMPILE}=$1;
- } elsif (/^CC=\s*(?:\$\(CROSS_COMPILE\))?(.*?)$/) {
- $ENV{CC}=$1;
- }
- }
- #
- # END OF TEMPORARY SECTION
- #
- } else {
- die "Insufficient data to reconfigure, please do a normal configuration\n";
- }
-}
-
-$config{perlargv} = [ @argvcopy ];
-
my %unsupported_options = ();
my %deprecated_options = ();
-foreach (@argvcopy)
+# 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.
{ $config{processor}=386; }
elsif (/^fips$/)
{
- $config{fips}=1;
+ die "FIPS mode not supported\n";
}
elsif (/^rsaref$/)
{
}
elsif (/^nofipscanistercheck$/)
{
- $config{fips} = 1;
- $nofipscanistercheck = 1;
+ die "FIPS mode not supported\n";
}
elsif (/^[-+]/)
{
{
$withargs{fuzzer_include}=$1;
}
- elsif (/^--with-fipslibdir=(.*)$/)
+ elsif (/^--with-rand-seed=(.*)$/)
{
- $config{fipslibdir}="$1/";
- }
- elsif (/^--with-baseaddr=(.*)$/)
- {
- $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;
{
$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";
+ }
elsif (/^-D(.*)$/)
{
push @user_defines, $1;
}
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.)
}
}
-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) {
@tocheckfor = (keys %new_tocheckfor);
}
+our $die = sub { die @_; };
if ($target eq "TABLE") {
+ local $die = sub { warn @_; };
foreach (sort keys %table) {
print_table_entry($_, "TABLE");
}
}
if ($target eq "HASH") {
+ local $die = sub { warn @_; };
print "%table = (\n";
foreach (sort keys %table) {
print_table_entry($_, "HASH");
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});
+
+my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
+$config{conf_files} = [ sort keys %conf_files ];
+%target = ( %{$table{DEFAULTS}}, %target );
+
+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-$_";
@{$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]/;
- if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/ || /^async$/
- || /^autoalginit/ || /^autoerrinit/)
+ # Fix up C macro end names
+ $WHAT = "RMD160" if $what eq "ripemd";
+
+ # 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_other_defines}}, "OPENSSL_NO_$WHAT";
+ print " OPENSSL_NO_$WHAT";
- push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$ALGO";
- print " OPENSSL_NO_$ALGO";
-
- # fix-up crypto/directory name(s)
- $algo="whrlpool" if $algo eq "whirlpool";
- $algo="ripemd" if $algo eq "rmd160";
- @{$config{sdirs}} = grep { $_ ne $algo} @{$config{sdirs}};
-
- print " (skip dir)";
+ 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";
+
+# 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} = "";
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)
$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) {
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";
$config{dynamic_engines} = 1;
}
-unless ($disabled{"fuzz-libfuzzer"}) {
- $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls ";
-}
-
unless ($disabled{asan}) {
$config{cflags} .= "-fsanitize=address ";
}
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";
}
if ($target{ec_asm_src} =~ /ecp_nistz256/) {
push @{$config{defines}}, "ECP_NISTZ256_ASM";
}
+ if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
+ push @{$config{defines}}, "PADLOCK_ASM";
+ }
if ($target{poly1305_asm_src} ne "") {
push @{$config{defines}}, "POLY1305_ASM";
}
}
-my $ecc = $target{cc};
-if ($^O ne "VMS" && !$disabled{makedepend}) {
- # Is the compiler gcc or clang? $ecc is used below to see if
- # error-checking can be turned on.
- my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
- open(PIPE, "$ccpcc --version 2>&1 |");
- my $lines = 2;
- while ( <PIPE> ) {
- # Find the version number and save the major.
- m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
- my $compiler_major = $1;
- # We know that GNU C version 3 and up as well as all clang
- # versions support dependency generation
- $config{makedepprog} = $ccpcc
- if (/clang/ || (/gcc/ && $compiler_major > 3));
- $ecc = "clang" if /clang/;
- $ecc = "gcc" if /gcc/;
- last if ($config{makedepprog} || !$lines--);
+my %predefined;
+
+if ($^O ne "VMS") {
+ my $cc = "$config{cross_compile_prefix}$target{cc}";
+
+ # collect compiler pre-defines from gcc or gcc-alike...
+ open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
+ while (<PIPE>) {
+ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
+ $predefined{$1} = $2 // "";
}
close(PIPE);
- $config{makedepprog} = which('makedepend') unless $config{makedepprog};
- $disabled{makedepend} = "unavailable" unless $config{makedepprog};
+ if (!$disabled{makedepend}) {
+ # We know that GNU C version 3 and up as well as all clang
+ # versions support dependency generation
+ if ($predefined{__GNUC__} >= 3) {
+ $config{makedepprog} = $cc;
+ } else {
+ $config{makedepprog} = which('makedepend');
+ $disabled{makedepend} = "unavailable" unless $config{makedepprog};
+ }
+ }
}
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)
{
}
}
-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; }
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 {
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" ]
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 %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,
|| $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) {
}
# 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}->{$_} = $_
}
}
+
+ # 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 %ordinals) {
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;
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{shared_sources}->{$ddest}->{$o} = 1;
$unified_info{sources}->{$o}->{$s} = 1;
$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
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 #########################
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"
}
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
close(CONFFILE);
my %targets = ();
{
- local %table = %::table; # Protect %table from tampering
+ # Protect certain tables from tampering
+ local %table = %::table;
eval $content;
warn $@ if $@;
warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
}
delete $targets{$_};
- }
+ } else {
+ $targets{$_}->{_conf_fname_int} = add([ $fname ]);
+ }
}
%table = (%table, %targets);
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;
}
}
+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
"unistd",
"ld",
"lflags",
+ "loutflag",
"plib_lflags",
"ex_libs",
"bn_ops",
- "cpuid_obj",
- "bn_obj",
- "ec_obj",
- "des_obj",
- "aes_obj",
- "bf_obj",
- "md5_obj",
- "sha1_obj",
- "cast_obj",
- "rc4_obj",
- "rmd160_obj",
- "rc5_obj",
- "wp_obj",
- "cmll_obj",
- "modes_obj",
- "padlock_obj",
+ "apps_aux_src",
+ "cpuid_asm_src",
+ "uplink_aux_src",
+ "bn_asm_src",
+ "ec_asm_src",
+ "des_asm_src",
+ "aes_asm_src",
+ "bf_asm_src",
+ "md5_asm_src",
+ "cast_asm_src",
+ "sha1_asm_src",
+ "rc4_asm_src",
+ "rmd160_asm_src",
+ "rc5_asm_src",
+ "wp_asm_src",
+ "cmll_asm_src",
+ "modes_asm_src",
+ "padlock_asm_src",
+ "chacha_asm_src",
+ "poly1035_asm_src",
"thread_scheme",
"perlasm_scheme",
"dso_scheme",
"shared_target",
"shared_cflag",
+ "shared_defines",
"shared_ldflag",
"shared_rcflag",
"shared_extension",
- "shared_extension_simple",
- "shared_import_extension",
"dso_extension",
"obj_extension",
"exe_extension",
"ranlib",
"ar",
"arflags",
+ "aroutflag",
+ "rc",
+ "rcflags",
+ "rcoutflag",
+ "mt",
+ "mtflags",
+ "mtinflag",
+ "mtoutflag",
"multilib",
"build_scheme",
);
# On non-platforms, we just use file_name_is_absolute().
return file_name_is_absolute($file) unless $^O eq "VMS";
- # If the file spec includes a device or a directpry spec,
+ # If the file spec includes a device or a directory spec,
# file_name_is_absolute() is perfectly safe.
return file_name_is_absolute($file) if $file =~ m|[:\[]|;
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 =