summaryrefslogtreecommitdiff
path: root/util/perl
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-03-02 23:14:09 +0100
committerRichard Levitte <levitte@openssl.org>2020-06-28 18:34:35 +0200
commita3310b182ca3952c2876792b35035b54a4c77713 (patch)
tree5df2dabd3c77b818ac2dbabd98cc672dbc762af8 /util/perl
parent48704cc651b937bf2e265aeaae55d44c9ed81e55 (diff)
downloadopenssl-new-a3310b182ca3952c2876792b35035b54a4c77713.tar.gz
util/perl/OpenSSL/config.pm: Rework determining compiler information
determine_compiler_settings() has been refactored to: - find a compiler if none has been given by the user - allow platform specific overrides, but only when the user didn't already specify a desired compiler - figure out the compiler vendor and version, making sure that the version number is deterministic - gather platform specific compiler information Reviewed-by: Tim Hudson <tjh@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11230)
Diffstat (limited to 'util/perl')
-rwxr-xr-xutil/perl/OpenSSL/config.pm253
1 files changed, 183 insertions, 70 deletions
diff --git a/util/perl/OpenSSL/config.pm b/util/perl/OpenSSL/config.pm
index c2d079a64f..62fc5ce312 100755
--- a/util/perl/OpenSSL/config.pm
+++ b/util/perl/OpenSSL/config.pm
@@ -15,7 +15,9 @@ use strict;
use warnings;
use Getopt::Std;
use File::Basename;
+use IPC::Cmd;
use POSIX;
+use Carp;
# These control our behavior.
my $DRYRUN;
@@ -28,18 +30,40 @@ my $MACHINE;
my $RELEASE;
my $SYSTEM;
my $VERSION;
+my $CCVENDOR;
my $CCVER;
-my $GCCVER;
my $GCC_BITS;
my $GCC_ARCH;
# Some environment variables; they will affect Configure
my $PERL = $ENV{PERL} // $^X // 'perl';
my $CONFIG_OPTIONS = $ENV{CONFIG_OPTIONS} // '';
-my $CC = $ENV{CC} // 'cc';
+my $CC = $ENV{CC} // '';
my $CROSS_COMPILE = $ENV{CROSS_COMPILE} // "";
my $KERNEL_BITS = $ENV{KERNEL_BITS} // '';
+# For determine_compiler_settings, the list of known compilers
+my @c_compilers = qw(clang gcc cc);
+# Methods to determine compiler version. The expected output is one of
+# MAJOR or MAJOR.MINOR or MAJOR.MINOR.PATCH... or false if the compiler
+# isn't of the given brand.
+# This is a list to ensure that gnu comes last, as we've made it a fallback
+my @cc_version =
+ (
+ clang => sub {
+ my $v = `$CROSS_COMPILE$CC -v 2>&1`;
+ $v =~ m/(?:(?:^clang|LLVM) version|.*based on LLVM)\s+([0-9]+\.[0-9]+)/;
+ return $1;
+ },
+ gnu => sub {
+ my $v = `$CROSS_COMPILE$CC -dumpversion 2>/dev/null`;
+ # Strip off whatever prefix egcs prepends the number with.
+ # Hopefully, this will work for any future prefixes as well.
+ $v =~ s/^[a-zA-Z]*\-//;
+ return $v;
+ },
+ );
+
# This is what we will set as the target for calling Configure.
my $options = '';
@@ -263,79 +287,166 @@ sub guess_system {
return "${MACHINE}-whatever-${SYSTEM}";
}
+# We would use List::Util::pair() for this... unfortunately, that function
+# only appeared in perl v5.19.3, and we claim to support perl v5.10 and on.
+# Therefore, we implement a quick cheap variant of our own.
+sub _pairs (@) {
+ croak "Odd number of arguments" if @_ & 1;
+
+ my @pairlist = ();
+
+ while (@_) {
+ my $x = [ shift, shift ];
+ push @pairlist, $x;
+ }
+ return @pairlist;
+}
+
# Figure out CC, GCCVAR, etc.
sub determine_compiler_settings {
- if ( "$CROSS_COMPILE$CC" eq '' ) {
- $GCCVER = `gcc -dumpversion 2>/dev/null`;
- if ( $GCCVER ne "" ) {
- # Strip off whatever prefix egcs prepends the number with.
- # Hopefully, this will work for any future prefixes as well.
- $GCCVER =~ s/^[a-zA-Z]*\-//;
- # Since gcc 3.1 gcc --version behaviour has changed, but
- # -dumpversion gives us what we want though, so use that.
- # We only want the major and minor version numbers. The
- # pattern is deliberate; single digit before and after first
- # dot, e.g. 2.95.1 gives 29
- $GCCVER =~ s/([0-9])\.([0-9]).*/$1$2/;
- $GCCVER = int($GCCVER);
- $CC = 'gcc';
+ # Make a copy and don't touch it. That helps determine if we're
+ # finding the compiler here
+ my $cc = $CC;
+
+ # Set certain default
+ $CCVER = 0; # Unknown
+ $CCVENDOR = ''; # Dunno, don't care (unless found later)
+
+ # Find a compiler if we don't already have one
+ if ( ! $cc ) {
+ foreach (@c_compilers) {
+ next unless IPC::Cmd::can_run("$CROSS_COMPILE$_");
+ $CC = $_;
+ last;
+ }
+ }
+
+ # Find the compiler vendor and version number for certain compilers
+ foreach my $pair (_pairs @cc_version) {
+ # Try to get the version number.
+ # Failure gets us undef or an empty string
+ my ( $k, $v ) = @$pair;
+ $v = $v->();
+
+ # If we got a version number, process it
+ if ($v) {
+ $CCVENDOR = $k;
+
+ # The returned version is expected to be one of
+ #
+ # MAJOR
+ # MAJOR.MINOR
+ # MAJOR.MINOR.{whatever}
+ #
+ # We don't care what comes after MAJOR.MINOR. All we need is to
+ # have them calculated into a single number, using this formula:
+ #
+ # MAJOR * 100 + MINOR
+ # Here are a few examples of what we should get:
+ #
+ # 2.95.1 => 295
+ # 3.1 => 301
+ # 9 => 900
+ my @numbers = split /\./, $v;
+ my @factors = (100, 1);
+ while (@numbers && @factors) {
+ $CCVER += shift(@numbers) * shift(@factors)
+ }
+ last;
+ }
+ }
+
+ # If no C compiler has been determined at this point, we die. Hard.
+ die <<_____
+ERROR!
+No C compiler found, please specify one with the environment variable CC,
+or configure with an explicit configuration target.
+_____
+ unless $CC;
+
+ # Vendor specific overrides, only if we determined the compiler here
+ if ( ! $cc ) {
+ if ( ${SYSTEM} eq 'AIX' ) {
+ # favor vendor cc over gcc
+ if (IPC::Cmd::can_run('cc')) {
+ $CC = 'cc';
+ $CCVENDOR = ''; # Determine later
+ $CCVER = 0;
+ }
+ }
+
+ if ( $SYSTEM eq "SunOS" ) {
+ # check for WorkShop C, expected output is "cc: blah-blah C x.x"
+ my $v = `(cc -V 2>&1) 2>/dev/null | egrep -e '^cc: .* C [0-9]\.[0-9]'`;
+ chomp $v;
+ $v =~ s/.* C \([0-9]\)\.\([0-9]\).*/$1.$2/;
+ my @numbers = split /\./, $v;
+ my @factors = (100, 1);
+ $v = 0;
+ while (@numbers && @factors) {
+ $v += shift(@numbers) * shift(@factors)
+ }
+
+ if ( $v > 40000 && $MACHINE ne 'i86pc' ) {
+ $CC = 'cc';
+ $CCVENDOR = ''; # Determine later
+ $CCVER = $v;
+
+ if ( $CCVER == 50000 ) {
+ print <<'EOF';
+WARNING! Found WorkShop C 5.0.
+ Make sure you have patch #107357-01 or later applied.
+EOF
+ maybe_abort();
+ }
+ }
}
}
- $GCCVER //= 0;
+ # On some systems, we assume a cc vendor if it's not already determined
- if ( $SYSTEM eq "HP-UX" ) {
+ if ( ! $CCVENDOR ) {
+ $CCVENDOR = 'aix' if $SYSTEM eq 'AIX';
+ $CCVENDOR = 'sun' if $SYSTEM eq 'SunOS';
+ }
+
+ # Some systems need to know extra details
+
+ if ( $SYSTEM eq "HP-UX" && $CCVENDOR eq 'gnu' ) {
# By default gcc is a ILP32 compiler (with long long == 64).
$GCC_BITS = "32";
- if ( $GCCVER >= 30 ) {
+ if ( $CCVER >= 300 ) {
# PA64 support only came in with gcc 3.0.x.
# We check if the preprocessor symbol __LP64__ is defined.
if ( okrun('echo __LP64__',
- 'gcc -v -E -x c - 2>/dev/null',
- 'grep "^__LP64__" 2>&1 >/dev/null') ) {
+ "$CC -v -E -x c - 2>/dev/null",
+ 'grep "^__LP64__" 2>&1 >/dev/null') ) {
# __LP64__ has slipped through, it therefore is not defined
} else {
$GCC_BITS = '64';
}
}
- return;
- }
-
- if ( ${SYSTEM} eq 'AIX' ) {
- # favor vendor cc over gcc
- if ( okrun('(cc) 2>&1',
- 'grep -iv "not found" >/dev/null') ) {
- $CC = 'cc';
- }
- return;
}
- if ( $SYSTEM eq "SunOS" ) {
- if ( $GCCVER >= 30 ) {
+ if ( $SYSTEM eq "SunOS" && $CCVENDOR eq 'gnu' ) {
+ if ( $CCVER >= 300 ) {
# 64-bit ABI isn't officially supported in gcc 3.0, but seems
# to be working; at the very least 'make test' passes.
- if ( okrun('gcc -v -E -x c /dev/null 2>&1',
- 'grep __arch64__ >/dev/null') ) {
+ if ( okrun("$CC -v -E -x c /dev/null 2>&1",
+ 'grep __arch64__ >/dev/null') ) {
$GCC_ARCH = "-m64"
} else {
$GCC_ARCH = "-m32"
}
}
- # check for WorkShop C, expected output is "cc: blah-blah C x.x"
- $CCVER = `(cc -V 2>&1) 2>/dev/null | egrep -e '^cc: .* C [0-9]\.[0-9]'`;
- $CCVER =~ s/.* C \([0-9]\)\.\([0-9]\).*/$1$2/;
- $CCVER //= 0;
- if ( $MACHINE ne 'i86pc' && $CCVER > 40 ) {
- # overrides gcc!!!
- $CC = 'cc';
- if ( $CCVER == 50 ) {
- print <<'EOF';
-WARNING! Found WorkShop C 5.0.
- Make sure you have patch #107357-01 or later applied.
-EOF
- maybe_abort();
- }
- }
+ }
+
+ if ($VERBOSE) {
+ my $vendor = $CCVENDOR ? $CCVENDOR : "(undetermined)";
+ my $version = $CCVER ? $CCVER : "(undetermined)";
+ print "C compiler: $CC\n";
+ print "C compiler vendor: $vendor\n";
+ print "C compiler version: $version\n";
}
}
@@ -406,7 +517,7 @@ EOF
if ( $GUESSOS =~ 'alpha-.*-linux2' ) {
my $ISA = `awk '/cpu model/{print \$4;exit(0);}' /proc/cpuinfo`;
$ISA //= 'generic';
- if ( $CC eq "gcc" ) {
+ if ( $CCVENDOR eq "gnu" ) {
if ( $ISA =~ 'EV5|EV45' ) {
$__CNF_CFLAGS .= " -mcpu=ev5";
$__CNF_CFLAGS .= " -mcpu=ev5";
@@ -550,13 +661,13 @@ EOF
if ( $GUESSOS =~ 'sun4[uv].*-.*-solaris2' ) {
my $ISA64 = `isainfo 2>/dev/null | grep sparcv9`;
if ( $ISA64 ne "" && $KERNEL_BITS eq '' ) {
- if ( $CC eq "cc" && $CCVER >= 50 ) {
+ if ( $CCVENDOR eq "sun" && $CCVER >= 500 ) {
print <<EOF;
WARNING! To build 64-bit package, do this:
$WHERE/Configure solaris64-sparcv9-cc
EOF
maybe_abort();
- } elsif ( $CC eq "gcc" && $GCC_ARCH eq "-m64" ) {
+ } elsif ( $CCVENDOR eq "gnu" && $GCC_ARCH eq "-m64" ) {
# $GCC_ARCH denotes default ABI chosen by compiler driver
# (first one found on the $PATH). I assume that user
# expects certain consistency with the rest of his builds
@@ -631,7 +742,7 @@ EOF
return "tru64-alpha-cc" if $GUESSOS =~ '.*-.*-tru64';
if ( $GUESSOS =~ '.*-.*-[Uu]nix[Ww]are7' ) {
$options .= "no-sse2";
- return "unixware-7-gcc" if $CC eq "gcc";
+ return "unixware-7-gcc" if $CCVENDOR eq "gnu";
$__CNF_CPPFLAGS .= " -D__i386__";
return "unixware-7";
}
@@ -658,14 +769,14 @@ EOF
}
return "android-armeabi" if $GUESSOS =~ 'arm.*-.*-android';
if ( $GUESSOS =~ '.*-hpux1.*' ) {
- $OUT = "hpux64-parisc2-gcc" if $CC = "gcc" && $GCC_BITS eq '64';
+ $OUT = "hpux64-parisc2-gcc" if $CCVENDOR eq "gnu" && $GCC_BITS eq '64';
$KERNEL_BITS //= `getconf KERNEL_BITS 2>/dev/null` // '32';
# See <sys/unistd.h> for further info on CPU_VERSION.
my $CPU_VERSION = `getconf CPU_VERSION 2>/dev/null` // 0;
$__CNF_CPPFLAGS .= " -D_REENTRANT";
if ( $CPU_VERSION >= 768 ) {
# IA-64 CPU
- return "hpux64-ia64-cc" if $KERNEL_BITS eq '64' && $CC eq "cc";
+ return "hpux64-ia64-cc" if $KERNEL_BITS eq '64' && ! $CCVENDOR;
return "hpux-ia64-cc"
}
if ( $CPU_VERSION >= 532 ) {
@@ -675,7 +786,7 @@ EOF
# in most critical assembly modules and taking advantage
# of 2.0 architecture in PA-RISC 1.1 build.
$OUT //= "hpux-parisc1_1-${CC}";
- if ( $KERNEL_BITS eq '64' && $CC eq "cc" ) {
+ if ( $KERNEL_BITS eq '64' && ! $CCVENDOR ) {
print <<EOF;
WARNING! To build 64-bit package, do this:
$WHERE/Configure hpux64-parisc2-cc
@@ -697,7 +808,7 @@ EOF
$KERNEL_BITS //= `getconf KERNEL_BITMODE 2>/dev/null`;
$KERNEL_BITS //= '32';
my $OBJECT_MODE //= 32;
- if ( $CC eq "gcc" ) {
+ if ( $CCVENDOR eq "gcc" ) {
$OUT = "aix-gcc";
if ( $OBJECT_MODE == 64 ) {
print 'Your $OBJECT_MODE was found to be set to 64';
@@ -722,34 +833,36 @@ EOF
# this applies even to Power3 and later, as they return
# PowerPC_POWER[345]
} else {
- $options .= " no-asm";
+ $config{disable} = [ 'asm' ];
}
- return $OUT;
+ return %config;
}
# Last case, return "z" from x-y-z
my @fields = split(/-/, $GUESSOS);
- return $fields[2];
+ return ( target => $fields[2] );
}
# gcc < 2.8 does not support -march=ultrasparc
sub check_solaris_sparc8 {
my $OUT = shift;
- if ( $OUT eq 'solaris-sparcv9-gcc' && $GCCVER < 28 ) {
- print <<EOF;
+ if ( $CCVENDOR eq 'gnu' && $CCVER < 208 ) {
+ if ( $OUT eq 'solaris-sparcv9-gcc' ) {
+ print <<EOF;
WARNING! Downgrading to solaris-sparcv8-gcc
Upgrade to gcc-2.8 or later.
EOF
- maybe_abort();
- return 'solaris-sparcv8-gcc';
- }
- if ( $OUT eq "linux-sparcv9" && $GCCVER < 28 ) {
- print <<EOF;
+ maybe_abort();
+ return 'solaris-sparcv8-gcc';
+ }
+ if ( $OUT eq "linux-sparcv9" ) {
+ print <<EOF;
WARNING! Downgrading to linux-sparcv8
Upgrade to gcc-2.8 or later.
EOF
- maybe_abort();
- return 'linux-sparcv8';
+ maybe_abort();
+ return 'linux-sparcv8';
+ }
}
return $OUT;
}