Home | History | Annotate | Line # | Download | only in OpenSSL
      1      1.1  christos #! /usr/bin/env perl
      2  1.1.1.2  christos # Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos #
      4      1.1  christos # Licensed under the Apache License 2.0 (the "License").  You may not use
      5      1.1  christos # this file except in compliance with the License.  You can obtain a copy
      6      1.1  christos # in the file LICENSE in the source distribution or at
      7      1.1  christos # https://www.openssl.org/source/license.html
      8      1.1  christos 
      9      1.1  christos # Determine the operating system and run ./Configure.  Far descendant from
     10      1.1  christos # Apache's minarch and GuessOS.
     11      1.1  christos 
     12      1.1  christos package OpenSSL::config;
     13      1.1  christos 
     14      1.1  christos use strict;
     15      1.1  christos use warnings;
     16      1.1  christos use Getopt::Std;
     17      1.1  christos use File::Basename;
     18      1.1  christos use File::Spec;
     19      1.1  christos use IPC::Cmd;
     20      1.1  christos use POSIX;
     21      1.1  christos use Config;
     22      1.1  christos use Carp;
     23      1.1  christos 
     24      1.1  christos # These control our behavior.
     25      1.1  christos my $DRYRUN;
     26      1.1  christos my $VERBOSE;
     27      1.1  christos my $WHERE = dirname($0);
     28      1.1  christos my $WAIT = 1;
     29      1.1  christos 
     30      1.1  christos # Machine type, etc., used to determine the platform
     31      1.1  christos my $MACHINE;
     32      1.1  christos my $RELEASE;
     33      1.1  christos my $SYSTEM;
     34      1.1  christos my $VERSION;
     35      1.1  christos my $CCVENDOR;
     36      1.1  christos my $CCVER;
     37      1.1  christos my $CL_ARCH;
     38      1.1  christos my $GCC_BITS;
     39      1.1  christos my $GCC_ARCH;
     40      1.1  christos 
     41      1.1  christos # Some environment variables; they will affect Configure
     42      1.1  christos my $CONFIG_OPTIONS = $ENV{CONFIG_OPTIONS} // '';
     43      1.1  christos my $CC;
     44      1.1  christos my $CROSS_COMPILE;
     45      1.1  christos 
     46      1.1  christos # For determine_compiler_settings, the list of known compilers
     47      1.1  christos my @c_compilers = qw(clang gcc cc);
     48      1.1  christos # Methods to determine compiler version.  The expected output is one of
     49      1.1  christos # MAJOR or MAJOR.MINOR or MAJOR.MINOR.PATCH...  or false if the compiler
     50      1.1  christos # isn't of the given brand.
     51      1.1  christos # This is a list to ensure that gnu comes last, as we've made it a fallback
     52      1.1  christos my @cc_version =
     53      1.1  christos     (
     54      1.1  christos      clang => sub {
     55      1.1  christos          return undef unless IPC::Cmd::can_run("$CROSS_COMPILE$CC");
     56      1.1  christos          my $v = `$CROSS_COMPILE$CC -v 2>&1`;
     57      1.1  christos          $v =~ m/(?:(?:clang|LLVM) version|.*based on LLVM)\s+([0-9]+\.[0-9]+)/;
     58      1.1  christos          return $1;
     59      1.1  christos      },
     60      1.1  christos      gnu => sub {
     61      1.1  christos          return undef unless IPC::Cmd::can_run("$CROSS_COMPILE$CC");
     62      1.1  christos          my $nul = File::Spec->devnull();
     63      1.1  christos          my $v = `$CROSS_COMPILE$CC -dumpversion 2> $nul`;
     64      1.1  christos          # Strip off whatever prefix egcs prepends the number with.
     65      1.1  christos          # Hopefully, this will work for any future prefixes as well.
     66      1.1  christos          $v =~ s/^[a-zA-Z]*\-//;
     67      1.1  christos          return $v;
     68      1.1  christos      },
     69      1.1  christos     );
     70      1.1  christos 
     71      1.1  christos # This is what we will set as the target for calling Configure.
     72      1.1  christos my $options = '';
     73      1.1  christos 
     74      1.1  christos # Pattern matches against "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}"
     75      1.1  christos # The patterns are assumed to be wrapped like this: /^(${pattern})$/
     76      1.1  christos my $guess_patterns = [
     77      1.1  christos     [ 'A\/UX:.*',                   'm68k-apple-aux3' ],
     78      1.1  christos     [ 'AIX:[3-9]:4:.*',             '${MACHINE}-ibm-aix' ],
     79      1.1  christos     [ 'AIX:.*?:[5-9]:.*',           '${MACHINE}-ibm-aix' ],
     80      1.1  christos     [ 'AIX:.*',                     '${MACHINE}-ibm-aix3' ],
     81      1.1  christos     [ 'HI-UX:.*',                   '${MACHINE}-hi-hiux' ],
     82      1.1  christos     [ 'HP-UX:.*',
     83      1.1  christos       sub {
     84      1.1  christos           my $HPUXVER = $RELEASE;
     85  1.1.1.3  christos           $HPUXVER =~ s/[^.]*.[0B]*//;
     86      1.1  christos           # HPUX 10 and 11 targets are unified
     87      1.1  christos           return "${MACHINE}-hp-hpux1x" if $HPUXVER =~ m@1[0-9]@;
     88      1.1  christos           return "${MACHINE}-hp-hpux";
     89      1.1  christos       }
     90      1.1  christos     ],
     91      1.1  christos     [ 'IRIX:6\..*',                 'mips3-sgi-irix' ],
     92      1.1  christos     [ 'IRIX64:.*',                  'mips4-sgi-irix64' ],
     93      1.1  christos     [ 'Linux:[2-9]\..*',            '${MACHINE}-whatever-linux2' ],
     94      1.1  christos     [ 'Linux:1\..*',                '${MACHINE}-whatever-linux1' ],
     95      1.1  christos     [ 'GNU.*',                      'hurd-x86' ],
     96      1.1  christos     [ 'LynxOS:.*',                  '${MACHINE}-lynx-lynxos' ],
     97      1.1  christos     # BSD/OS always says 386
     98      1.1  christos     [ 'BSD\/OS:4\..*',              'i486-whatever-bsdi4' ],
     99      1.1  christos     # Order is important, this has to appear before 'BSD\/386:'
    100      1.1  christos     [ 'BSD/386:.*?:.*?:.*486.*|BSD/OS:.*?:.*?:.*?:.*486.*',
    101      1.1  christos       sub {
    102      1.1  christos           my $BSDVAR = `/sbin/sysctl -n hw.model`;
    103      1.1  christos           return "i586-whatever-bsdi" if $BSDVAR =~ m@Pentium@;
    104      1.1  christos           return "i386-whatever-bsdi";
    105      1.1  christos       }
    106      1.1  christos     ],
    107      1.1  christos     [ 'BSD\/386:.*|BSD\/OS:.*',     '${MACHINE}-whatever-bsdi' ],
    108      1.1  christos     # Order is important, this has to appear before 'FreeBSD:'
    109      1.1  christos     [ 'FreeBSD:.*?:.*?:.*386.*',
    110      1.1  christos       sub {
    111      1.1  christos           my $VERS = $RELEASE;
    112      1.1  christos           $VERS =~ s/[-(].*//;
    113      1.1  christos           my $MACH = `sysctl -n hw.model`;
    114      1.1  christos           $MACH = "i386" if $MACH =~ m@386@;
    115      1.1  christos           $MACH = "i486" if $MACH =~ m@486@;
    116      1.1  christos           $MACH = "i686" if $MACH =~ m@Pentium II@;
    117      1.1  christos           $MACH = "i586" if $MACH =~ m@Pentium@;
    118      1.1  christos           $MACH = "$MACHINE" if $MACH !~ /i.86/;
    119      1.1  christos           my $ARCH = 'whatever';
    120      1.1  christos           $ARCH = "pc" if $MACH =~ m@i[0-9]86@;
    121      1.1  christos           return "${MACH}-${ARCH}-freebsd${VERS}";
    122      1.1  christos       }
    123      1.1  christos     ],
    124      1.1  christos     [ 'DragonFly:.*',               '${MACHINE}-whatever-dragonfly' ],
    125      1.1  christos     [ 'FreeBSD:.*',                 '${MACHINE}-whatever-freebsd' ],
    126      1.1  christos     [ 'Haiku:.*',                   '${MACHINE}-whatever-haiku' ],
    127      1.1  christos     # Order is important, this has to appear before 'NetBSD:.*'
    128      1.1  christos     [ 'NetBSD:.*?:.*?:.*386.*',
    129      1.1  christos       sub {
    130      1.1  christos           my $hw = `/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model`;
    131      1.1  christos           $hw =~  s@.*(.)86-class.*@i${1}86@;
    132      1.1  christos           return "${hw}-whatever-netbsd";
    133      1.1  christos       }
    134      1.1  christos     ],
    135      1.1  christos     [ 'NetBSD:.*',                  '${MACHINE}-whatever-netbsd' ],
    136      1.1  christos     [ 'OpenBSD:.*',                 '${MACHINE}-whatever-openbsd' ],
    137      1.1  christos     [ 'OpenUNIX:.*',                '${MACHINE}-unknown-OpenUNIX${VERSION}' ],
    138      1.1  christos     [ 'OSF1:.*?:.*?:.*alpha.*',
    139      1.1  christos       sub {
    140      1.1  christos           my $OSFMAJOR = $RELEASE;
    141      1.1  christos           $OSFMAJOR =~ 's/^V([0-9]*)\..*$/\1/';
    142      1.1  christos           return "${MACHINE}-dec-tru64" if $OSFMAJOR =~ m@[45]@;
    143      1.1  christos           return "${MACHINE}-dec-osf";
    144      1.1  christos       }
    145      1.1  christos     ],
    146      1.1  christos     [ 'Paragon.*?:.*',              'i860-intel-osf1' ],
    147      1.1  christos     [ 'Rhapsody:.*',                'ppc-apple-rhapsody' ],
    148      1.1  christos     [ 'Darwin:.*?:.*?:Power.*',     'ppc-apple-darwin' ],
    149      1.1  christos     [ 'Darwin:.*',                  '${MACHINE}-apple-darwin' ],
    150      1.1  christos     [ 'SunOS:5\..*',                '${MACHINE}-whatever-solaris2' ],
    151      1.1  christos     [ 'SunOS:.*',                   '${MACHINE}-sun-sunos4' ],
    152      1.1  christos     [ 'UNIX_System_V:4\..*?:.*',    '${MACHINE}-whatever-sysv4' ],
    153      1.1  christos     [ 'VOS:.*?:.*?:i786',           'i386-stratus-vos' ],
    154      1.1  christos     [ 'VOS:.*?:.*?:.*',             'hppa1.1-stratus-vos' ],
    155      1.1  christos     [ '.*?:4.*?:R4.*?:m88k',        '${MACHINE}-whatever-sysv4' ],
    156      1.1  christos     [ 'DYNIX\/ptx:4.*?:.*',         '${MACHINE}-whatever-sysv4' ],
    157      1.1  christos     [ '.*?:4\.0:3\.0:3[34]..(,.*)?', 'i486-ncr-sysv4' ],
    158      1.1  christos     [ 'ULTRIX:.*',                  '${MACHINE}-unknown-ultrix' ],
    159      1.1  christos     [ 'POSIX-BC.*',                 'BS2000-siemens-sysv4' ],
    160      1.1  christos     [ 'machten:.*',                 '${MACHINE}-tenon-${SYSTEM}' ],
    161      1.1  christos     [ 'library:.*',                 '${MACHINE}-ncr-sysv4' ],
    162      1.1  christos     [ 'ConvexOS:.*?:11\.0:.*',      '${MACHINE}-v11-${SYSTEM}' ],
    163      1.1  christos     [ 'MINGW64.*?:.*?:.*?:x86_64',  '${MACHINE}-whatever-mingw64' ],
    164      1.1  christos     [ 'MINGW.*',                    '${MACHINE}-whatever-mingw' ],
    165      1.1  christos     [ 'CYGWIN.*',                   '${MACHINE}-pc-cygwin' ],
    166      1.1  christos     [ 'vxworks.*',                  '${MACHINE}-whatever-vxworks' ],
    167      1.1  christos 
    168      1.1  christos     # The MACHINE part of the array POSIX::uname() returns on VMS isn't
    169      1.1  christos     # worth the bits wasted on it.  It's better, then, to rely on perl's
    170      1.1  christos     # %Config, which has a trustworthy item 'archname', especially since
    171      1.1  christos     # VMS installation aren't multiarch (yet)
    172      1.1  christos     [ 'OpenVMS:.*',                 "$Config{archname}-whatever-OpenVMS" ],
    173      1.1  christos 
    174      1.1  christos     # Note: there's also NEO and NSR, but they are old and unsupported
    175      1.1  christos     [ 'NONSTOP_KERNEL:.*:NSE-.*?',  'nse-tandem-nsk${RELEASE}' ],
    176      1.1  christos     [ 'NONSTOP_KERNEL:.*:NSV-.*?',  'nsv-tandem-nsk${RELEASE}' ],
    177      1.1  christos     [ 'NONSTOP_KERNEL:.*:NSX-.*?',  'nsx-tandem-nsk${RELEASE}' ],
    178      1.1  christos 
    179      1.1  christos     [ sub { -d '/usr/apollo' },     'whatever-apollo-whatever' ],
    180      1.1  christos ];
    181      1.1  christos 
    182      1.1  christos # Run a command, return true if exit zero else false.
    183      1.1  christos # Multiple args are glued together into a pipeline.
    184      1.1  christos # Name comes from OpenSSL tests, often written as "ok(run(...."
    185      1.1  christos sub okrun {
    186      1.1  christos     my $command = join(' | ', @_);
    187      1.1  christos     my $status = system($command) >> 8;
    188      1.1  christos     return $status == 0;
    189      1.1  christos }
    190      1.1  christos 
    191      1.1  christos # Give user a chance to abort/interrupt if interactive if interactive.
    192      1.1  christos sub maybe_abort {
    193      1.1  christos     if ( $WAIT && -t 1 ) {
    194      1.1  christos         eval {
    195      1.1  christos             local $SIG{ALRM} = sub { die "Timeout"; };
    196      1.1  christos             local $| = 1;
    197      1.1  christos             alarm(5);
    198      1.1  christos             print "You have about five seconds to abort: ";
    199      1.1  christos             my $ignored = <STDIN>;
    200      1.1  christos             alarm(0);
    201      1.1  christos         };
    202      1.1  christos         print "\n" if $@ =~ /Timeout/;
    203      1.1  christos     }
    204      1.1  christos }
    205      1.1  christos 
    206      1.1  christos # Look for ISC/SCO with its unique uname program
    207      1.1  christos sub is_sco_uname {
    208      1.1  christos     return undef unless IPC::Cmd::can_run('uname');
    209      1.1  christos 
    210      1.1  christos     open UNAME, "uname -X 2>/dev/null|" or return '';
    211      1.1  christos     my $line = "";
    212      1.1  christos     my $os = "";
    213      1.1  christos     while ( <UNAME> ) {
    214      1.1  christos         chop;
    215      1.1  christos         $line = $_ if m@^Release@;
    216      1.1  christos         $os = $_ if m@^System@;
    217      1.1  christos     }
    218      1.1  christos     close UNAME;
    219      1.1  christos 
    220      1.1  christos     return undef if $line eq '' or $os eq 'System = SunOS';
    221      1.1  christos 
    222      1.1  christos     my @fields = split(/\s+/, $line);
    223      1.1  christos     return $fields[2];
    224      1.1  christos }
    225      1.1  christos 
    226      1.1  christos sub get_sco_type {
    227      1.1  christos     my $REL = shift;
    228      1.1  christos 
    229      1.1  christos     if ( -f "/etc/kconfig" ) {
    230      1.1  christos         return "${MACHINE}-whatever-isc4" if $REL eq '4.0' || $REL eq '4.1';
    231      1.1  christos     } else {
    232      1.1  christos         return "whatever-whatever-sco3" if $REL eq '3.2v4.2';
    233      1.1  christos         return "whatever-whatever-sco5" if $REL =~ m@3\.2v5\.0.*@;
    234      1.1  christos         if ( $REL eq "4.2MP" ) {
    235      1.1  christos             return "whatever-whatever-unixware20" if $VERSION =~ m@2\.0.*@;
    236      1.1  christos             return "whatever-whatever-unixware21" if $VERSION =~ m@2\.1.*@;
    237      1.1  christos             return "whatever-whatever-unixware2" if $VERSION =~ m@2.*@;
    238      1.1  christos         }
    239      1.1  christos         return "whatever-whatever-unixware1" if $REL eq "4.2";
    240      1.1  christos         if ( $REL =~ m@5.*@ ) {
    241      1.1  christos             # We hardcode i586 in place of ${MACHINE} for the following
    242      1.1  christos             # reason: even though Pentium is minimum requirement for
    243      1.1  christos             # platforms in question, ${MACHINE} gets always assigned to
    244      1.1  christos             # i386. This means i386 gets passed to Configure, which will
    245      1.1  christos             # cause bad assembler code to be generated.
    246      1.1  christos             return "i586-sco-unixware7" if $VERSION =~ m@[678].*@;
    247      1.1  christos         }
    248      1.1  christos     }
    249      1.1  christos }
    250      1.1  christos 
    251      1.1  christos # Return the cputype-vendor-osversion
    252      1.1  christos sub guess_system {
    253      1.1  christos     ($SYSTEM, undef, $RELEASE, $VERSION, $MACHINE) = POSIX::uname();
    254      1.1  christos     my $sys = "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}";
    255      1.1  christos     
    256      1.1  christos     # Special-cases for ISC, SCO, Unixware
    257      1.1  christos     my $REL = is_sco_uname();
    258      1.1  christos     if ( defined $REL ) {
    259      1.1  christos         my $result = get_sco_type($REL);
    260      1.1  christos         return eval "\"$result\"" if $result ne '';
    261      1.1  christos     }
    262      1.1  christos 
    263      1.1  christos     # Now pattern-match
    264      1.1  christos 
    265      1.1  christos     # Simple cases
    266      1.1  christos     foreach my $tuple ( @$guess_patterns ) {
    267      1.1  christos         my $pat = @$tuple[0];
    268      1.1  christos         my $check = ref $pat eq 'CODE' ? $pat->($sys) : $sys =~ /^(${pat})$/;
    269      1.1  christos         next unless $check;
    270      1.1  christos 
    271      1.1  christos         my $result = @$tuple[1];
    272      1.1  christos         $result = $result->() if ref $result eq 'CODE';
    273      1.1  christos         return eval "\"$result\"";
    274      1.1  christos     }
    275      1.1  christos 
    276      1.1  christos     # Oh well.
    277      1.1  christos     return "${MACHINE}-whatever-${SYSTEM}";
    278      1.1  christos }
    279      1.1  christos 
    280      1.1  christos # We would use List::Util::pair() for this...  unfortunately, that function
    281      1.1  christos # only appeared in perl v5.19.3, and we claim to support perl v5.10 and on.
    282      1.1  christos # Therefore, we implement a quick cheap variant of our own.
    283      1.1  christos sub _pairs (@) {
    284      1.1  christos     croak "Odd number of arguments" if @_ & 1;
    285      1.1  christos 
    286      1.1  christos     my @pairlist = ();
    287      1.1  christos 
    288      1.1  christos     while (@_) {
    289      1.1  christos         my $x = [ shift, shift ];
    290      1.1  christos         push @pairlist, $x;
    291      1.1  christos     }
    292      1.1  christos     return @pairlist;
    293      1.1  christos }
    294      1.1  christos 
    295      1.1  christos # Figure out CC, GCCVAR, etc.
    296      1.1  christos sub determine_compiler_settings {
    297      1.1  christos     # Make a copy and don't touch it.  That helps determine if we're finding
    298      1.1  christos     # the compiler here (false), or if it was set by the user (true.
    299      1.1  christos     my $cc = $CC;
    300      1.1  christos 
    301      1.1  christos     # Set certain default
    302      1.1  christos     $CCVER = 0;                 # Unknown
    303      1.1  christos     $CCVENDOR = '';             # Dunno, don't care (unless found later)
    304      1.1  christos 
    305      1.1  christos     # Find a compiler if we don't already have one
    306      1.1  christos     if ( ! $cc ) {
    307      1.1  christos         foreach (@c_compilers) {
    308      1.1  christos             next unless IPC::Cmd::can_run("$CROSS_COMPILE$_");
    309      1.1  christos             $CC = $_;
    310      1.1  christos             last;
    311      1.1  christos         }
    312      1.1  christos     }
    313      1.1  christos 
    314      1.1  christos     if ( $CC ) {
    315      1.1  christos         # Find the compiler vendor and version number for certain compilers
    316      1.1  christos         foreach my $pair (_pairs @cc_version) {
    317      1.1  christos             # Try to get the version number.
    318      1.1  christos             # Failure gets us undef or an empty string
    319      1.1  christos             my ( $k, $v ) = @$pair;
    320      1.1  christos             $v = $v->();
    321      1.1  christos 
    322      1.1  christos             # If we got a version number, process it
    323      1.1  christos             if ($v) {
    324  1.1.1.3  christos                 $v =~ s/[^.]*.0*// if $SYSTEM eq 'HP-UX';
    325      1.1  christos                 $CCVENDOR = $k;
    326      1.1  christos 
    327      1.1  christos                 # The returned version is expected to be one of
    328      1.1  christos                 #
    329      1.1  christos                 # MAJOR
    330      1.1  christos                 # MAJOR.MINOR
    331      1.1  christos                 # MAJOR.MINOR.{whatever}
    332      1.1  christos                 #
    333      1.1  christos                 # We don't care what comes after MAJOR.MINOR.  All we need is
    334      1.1  christos                 # to have them calculated into a single number, using this
    335      1.1  christos                 # formula:
    336      1.1  christos                 #
    337      1.1  christos                 # MAJOR * 100 + MINOR
    338      1.1  christos                 # Here are a few examples of what we should get:
    339      1.1  christos                 #
    340      1.1  christos                 # 2.95.1    => 295
    341      1.1  christos                 # 3.1       => 301
    342      1.1  christos                 # 9         => 900
    343      1.1  christos                 my @numbers = split /\./, $v;
    344      1.1  christos                 my @factors = (100, 1);
    345      1.1  christos                 while (@numbers && @factors) {
    346      1.1  christos                     $CCVER += shift(@numbers) * shift(@factors)
    347      1.1  christos                 }
    348      1.1  christos                 last;
    349      1.1  christos             }
    350      1.1  christos         }
    351      1.1  christos     }
    352      1.1  christos 
    353      1.1  christos     # Vendor specific overrides, only if we didn't determine the compiler here
    354      1.1  christos     if ( ! $cc ) {
    355      1.1  christos         if ( $SYSTEM eq 'OpenVMS' ) {
    356      1.1  christos             my $v = `CC/VERSION NLA0:`;
    357      1.1  christos             if ($? == 0) {
    358  1.1.1.2  christos                 # The normal releases have a version number prefixed with a V.
    359  1.1.1.2  christos                 # However, other letters have been seen as well (for example X),
    360  1.1.1.2  christos                 # and it's documented that HP (now VSI) reserve the letter W, X,
    361  1.1.1.2  christos                 # Y and Z for their own uses.
    362  1.1.1.3  christos                 my ($vendor, $arch, $version, $extra) =
    363  1.1.1.3  christos                     ( $v =~ m/^
    364  1.1.1.3  christos                               ([A-Z]+)                  # Usually VSI
    365  1.1.1.3  christos                               \s+ C
    366  1.1.1.3  christos                               (?:\s+(.*?))?             # Possible build arch
    367  1.1.1.3  christos                               \s+ [VWXYZ]([0-9\.-]+)    # Version
    368  1.1.1.3  christos                               (?:\s+\((.*?)\))?         # Possible extra data
    369  1.1.1.3  christos                               \s+ on
    370  1.1.1.3  christos                              /x );
    371      1.1  christos                 my ($major, $minor, $patch) =
    372      1.1  christos                     ( $version =~ m/^([0-9]+)\.([0-9]+)-0*?(0|[1-9][0-9]*)$/ );
    373      1.1  christos                 $CC = 'CC';
    374      1.1  christos                 $CCVENDOR = $vendor;
    375      1.1  christos                 $CCVER = ( $major * 100 + $minor ) * 100 + $patch;
    376      1.1  christos             }
    377      1.1  christos         }
    378      1.1  christos 
    379      1.1  christos         if ( ${SYSTEM} eq 'AIX' ) {
    380      1.1  christos             # favor vendor cc over gcc
    381      1.1  christos             if (IPC::Cmd::can_run('cc')) {
    382      1.1  christos                 $CC = 'cc';
    383      1.1  christos                 $CCVENDOR = ''; # Determine later
    384      1.1  christos                 $CCVER = 0;
    385      1.1  christos             }
    386      1.1  christos         }
    387      1.1  christos 
    388      1.1  christos         if ( $SYSTEM eq "SunOS" ) {
    389      1.1  christos             # check for Oracle Developer Studio, expected output is "cc: blah-blah C x.x blah-blah"
    390      1.1  christos             my $v = `(cc -V 2>&1) 2>/dev/null | egrep -e '^cc: .* C [0-9]\.[0-9]'`;
    391      1.1  christos             my @numbers = 
    392      1.1  christos                     ( $v =~ m/^.* C ([0-9]+)\.([0-9]+) .*/ );
    393      1.1  christos             my @factors = (100, 1);
    394      1.1  christos             $v = 0;
    395      1.1  christos             while (@numbers && @factors) {
    396      1.1  christos                 $v += shift(@numbers) * shift(@factors)
    397      1.1  christos             }
    398      1.1  christos 
    399      1.1  christos             if ($v > 500) {
    400      1.1  christos                 $CC = 'cc';
    401      1.1  christos                 $CCVENDOR = 'sun';
    402      1.1  christos                 $CCVER = $v;
    403      1.1  christos             }
    404      1.1  christos         }
    405      1.1  christos 
    406      1.1  christos         # 'Windows NT' is the system name according to POSIX::uname()!
    407      1.1  christos         if ( $SYSTEM eq "Windows NT" ) {
    408      1.1  christos             # favor vendor cl over gcc
    409      1.1  christos             if (IPC::Cmd::can_run('cl')) {
    410      1.1  christos                 $CC = 'cl';
    411      1.1  christos                 $CCVENDOR = ''; # Determine later
    412      1.1  christos                 $CCVER = 0;
    413      1.1  christos 
    414      1.1  christos                 my $v = `cl 2>&1`;
    415      1.1  christos                 if ( $v =~ /Microsoft .* Version ([0-9\.]+) for (x86|x64|ARM|ia64)/ ) {
    416      1.1  christos                     $CCVER = $1;
    417      1.1  christos                     $CL_ARCH = $2;
    418      1.1  christos                 }
    419      1.1  christos             }
    420      1.1  christos         }
    421      1.1  christos     }
    422      1.1  christos 
    423      1.1  christos     # If no C compiler has been determined at this point, we die.  Hard.
    424      1.1  christos     die <<_____
    425      1.1  christos ERROR!
    426      1.1  christos No C compiler found, please specify one with the environment variable CC,
    427      1.1  christos or configure with an explicit configuration target.
    428      1.1  christos _____
    429      1.1  christos         unless $CC;
    430      1.1  christos 
    431      1.1  christos     # On some systems, we assume a cc vendor if it's not already determined
    432      1.1  christos 
    433      1.1  christos     if ( ! $CCVENDOR ) {
    434      1.1  christos         $CCVENDOR = 'aix' if $SYSTEM eq 'AIX';
    435      1.1  christos         $CCVENDOR = 'sun' if $SYSTEM eq 'SunOS';
    436      1.1  christos     }
    437      1.1  christos 
    438      1.1  christos     # Some systems need to know extra details
    439      1.1  christos 
    440      1.1  christos     if ( $SYSTEM eq "HP-UX" && $CCVENDOR eq 'gnu' ) {
    441      1.1  christos         # By default gcc is a ILP32 compiler (with long long == 64).
    442      1.1  christos         $GCC_BITS = "32";
    443      1.1  christos         if ( $CCVER >= 300 ) {
    444      1.1  christos             # PA64 support only came in with gcc 3.0.x.
    445      1.1  christos             # We check if the preprocessor symbol __LP64__ is defined.
    446      1.1  christos             if ( okrun('echo __LP64__',
    447      1.1  christos                        "$CC -v -E -x c - 2>/dev/null",
    448      1.1  christos                        'grep "^__LP64__" 2>&1 >/dev/null') ) {
    449      1.1  christos                 # __LP64__ has slipped through, it therefore is not defined
    450      1.1  christos             } else {
    451      1.1  christos                 $GCC_BITS = '64';
    452      1.1  christos             }
    453      1.1  christos         }
    454      1.1  christos     }
    455      1.1  christos 
    456      1.1  christos     if ( $SYSTEM eq "SunOS" && $CCVENDOR eq 'gnu' ) {
    457      1.1  christos         if ( $CCVER >= 300 ) {
    458      1.1  christos             # 64-bit ABI isn't officially supported in gcc 3.0, but seems
    459      1.1  christos             # to be working; at the very least 'make test' passes.
    460      1.1  christos             if ( okrun("$CC -v -E -x c /dev/null 2>&1",
    461      1.1  christos                        'grep __arch64__ >/dev/null') ) {
    462      1.1  christos                 $GCC_ARCH = "-m64"
    463      1.1  christos             } else {
    464      1.1  christos                 $GCC_ARCH = "-m32"
    465      1.1  christos             }
    466      1.1  christos         }
    467      1.1  christos     }
    468      1.1  christos 
    469      1.1  christos     if ($VERBOSE) {
    470      1.1  christos         my $vendor = $CCVENDOR ? $CCVENDOR : "(undetermined)";
    471      1.1  christos         my $version = $CCVER ? $CCVER : "(undetermined)";
    472      1.1  christos         print "C compiler: $CC\n";
    473      1.1  christos         print "C compiler vendor: $vendor\n";
    474      1.1  christos         print "C compiler version: $version\n";
    475      1.1  christos     }
    476      1.1  christos }
    477      1.1  christos 
    478      1.1  christos my $map_patterns =
    479      1.1  christos     [ [ 'uClinux.*64.*',          { target => 'uClinux-dist64' } ],
    480      1.1  christos       [ 'uClinux.*',              { target => 'uClinux-dist' } ],
    481      1.1  christos       [ 'mips3-sgi-irix',         { target => 'irix-mips3' } ],
    482      1.1  christos       [ 'mips4-sgi-irix64',
    483      1.1  christos         sub {
    484      1.1  christos             print <<EOF;
    485      1.1  christos WARNING! To build 64-bit package, do this:
    486      1.1  christos          $WHERE/Configure irix64-mips4-$CC
    487      1.1  christos EOF
    488      1.1  christos             maybe_abort();
    489      1.1  christos             return { target => "irix-mips3" };
    490      1.1  christos         }
    491      1.1  christos       ],
    492      1.1  christos       [ 'ppc-apple-rhapsody',     { target => "rhapsody-ppc" } ],
    493      1.1  christos       [ 'ppc-apple-darwin.*',
    494      1.1  christos         sub {
    495      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS} // '';
    496      1.1  christos             my $ISA64 = `sysctl -n hw.optional.64bitops 2>/dev/null`;
    497      1.1  christos             if ( $ISA64 == 1 && $KERNEL_BITS eq '' ) {
    498      1.1  christos                 print <<EOF;
    499      1.1  christos WARNING! To build 64-bit package, do this:
    500      1.1  christos          $WHERE/Configure darwin64-ppc-cc
    501      1.1  christos EOF
    502      1.1  christos                 maybe_abort();
    503      1.1  christos             }
    504      1.1  christos             return { target => "darwin64-ppc" }
    505      1.1  christos                 if $ISA64 == 1 && $KERNEL_BITS eq '64';
    506      1.1  christos             return { target => "darwin-ppc" };
    507      1.1  christos         }
    508      1.1  christos       ],
    509      1.1  christos       [ 'i.86-apple-darwin.*',
    510      1.1  christos         sub {
    511      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS} // '';
    512      1.1  christos             my $ISA64 = `sysctl -n hw.optional.x86_64 2>/dev/null`;
    513      1.1  christos             if ( $ISA64 == 1 && $KERNEL_BITS eq '' ) {
    514      1.1  christos                 print <<EOF;
    515      1.1  christos WARNING! To build 64-bit package, do this:
    516      1.1  christos          KERNEL_BITS=64 $WHERE/Configure \[\[ options \]\]
    517      1.1  christos EOF
    518      1.1  christos                 maybe_abort();
    519      1.1  christos             }
    520      1.1  christos             return { target => "darwin64-x86_64" }
    521      1.1  christos                 if $ISA64 == 1 && $KERNEL_BITS eq '64';
    522      1.1  christos             return { target => "darwin-i386" };
    523      1.1  christos         }
    524      1.1  christos       ],
    525      1.1  christos       [ 'x86_64-apple-darwin.*',
    526      1.1  christos         sub {
    527      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS} // '';
    528      1.1  christos             # macOS >= 10.15 is 64-bit only
    529      1.1  christos             my $SW_VERS = `sw_vers -productVersion 2>/dev/null`;
    530      1.1  christos             if ($SW_VERS =~ /^(\d+)\.(\d+)\.(\d+)$/) {
    531      1.1  christos                 if ($1 > 10 || ($1 == 10 && $2 >= 15)) {
    532      1.1  christos                     die "32-bit applications not supported on macOS 10.15 or later\n" if $KERNEL_BITS eq '32';
    533      1.1  christos                     return { target => "darwin64-x86_64" };
    534      1.1  christos                 }
    535      1.1  christos             }
    536      1.1  christos             return { target => "darwin-i386" } if $KERNEL_BITS eq '32';
    537      1.1  christos 
    538      1.1  christos             print <<EOF;
    539      1.1  christos WARNING! To build 32-bit package, do this:
    540      1.1  christos          KERNEL_BITS=32 $WHERE/Configure \[\[ options \]\]
    541      1.1  christos EOF
    542      1.1  christos             maybe_abort();
    543      1.1  christos             return { target => "darwin64-x86_64" };
    544      1.1  christos         }
    545      1.1  christos       ],
    546      1.1  christos       [ 'arm64-apple-darwin.*', { target => "darwin64-arm64" } ],
    547      1.1  christos       [ 'armv6\+7-.*-iphoneos',
    548      1.1  christos         { target => "iphoneos-cross",
    549      1.1  christos           cflags => [ qw(-arch armv6 -arch armv7) ],
    550      1.1  christos           cxxflags => [ qw(-arch armv6 -arch armv7) ] }
    551      1.1  christos       ],
    552      1.1  christos       [ 'arm64-.*-iphoneos|.*-.*-ios64',
    553      1.1  christos         { target => "ios64-cross" }
    554      1.1  christos       ],
    555      1.1  christos       [ '.*-.*-iphoneos',
    556      1.1  christos         sub { return { target => "iphoneos-cross",
    557      1.1  christos                        cflags => [ "-arch ${MACHINE}" ],
    558      1.1  christos                        cxxflags => [ "-arch ${MACHINE}" ] }; }
    559      1.1  christos       ],
    560      1.1  christos       [ 'alpha-.*-linux2.*',
    561      1.1  christos         sub {
    562      1.1  christos             my $ISA = `awk '/cpu model/{print \$4;exit(0);}' /proc/cpuinfo`;
    563      1.1  christos             $ISA //= 'generic';
    564      1.1  christos             my %config = ();
    565      1.1  christos             if ( $CCVENDOR eq "gnu" ) {
    566      1.1  christos                 if ( $ISA =~ 'EV5|EV45' ) {
    567      1.1  christos                     %config = ( cflags => [ '-mcpu=ev5' ],
    568      1.1  christos                                 cxxflags =>  [ '-mcpu=ev5' ] );
    569      1.1  christos                 } elsif ( $ISA =~ 'EV56|PCA56' ) {
    570      1.1  christos                     %config = ( cflags => [ '-mcpu=ev56' ],
    571      1.1  christos                                 cxxflags =>  [ '-mcpu=ev56' ] );
    572      1.1  christos                 } else {
    573      1.1  christos                     %config = ( cflags => [ '-mcpu=ev6' ],
    574      1.1  christos                                 cxxflags =>  [ '-mcpu=ev6' ] );
    575      1.1  christos                 }
    576      1.1  christos             }
    577      1.1  christos             return { target => "linux-alpha",
    578      1.1  christos                      %config };
    579      1.1  christos         }
    580      1.1  christos       ],
    581      1.1  christos       [ 'ppc64-.*-linux2',
    582      1.1  christos         sub {
    583      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS} // '';
    584      1.1  christos             if ( $KERNEL_BITS eq '' ) {
    585      1.1  christos                 print <<EOF;
    586      1.1  christos WARNING! To build 64-bit package, do this:
    587      1.1  christos          $WHERE/Configure linux-ppc64
    588      1.1  christos EOF
    589      1.1  christos                 maybe_abort();
    590      1.1  christos             }
    591      1.1  christos             return { target => "linux-ppc64" } if $KERNEL_BITS eq '64';
    592      1.1  christos 
    593      1.1  christos             my %config = ();
    594      1.1  christos             if (!okrun('echo __LP64__',
    595      1.1  christos                        'gcc -E -x c - 2>/dev/null',
    596      1.1  christos                        'grep "^__LP64__" 2>&1 >/dev/null') ) {
    597      1.1  christos                 %config = ( cflags => [ '-m32' ],
    598      1.1  christos                             cxxflags =>  [ '-m32' ] );
    599      1.1  christos             }
    600      1.1  christos             return { target => "linux-ppc",
    601      1.1  christos                      %config };
    602      1.1  christos         }
    603      1.1  christos       ],
    604      1.1  christos       [ 'ppc64le-.*-linux2',      { target => "linux-ppc64le" } ],
    605      1.1  christos       [ 'ppc-.*-linux2',          { target => "linux-ppc" } ],
    606      1.1  christos       [ 'mips64.*-*-linux2',
    607      1.1  christos         sub {
    608      1.1  christos             print <<EOF;
    609      1.1  christos WARNING! To build 64-bit package, do this:
    610      1.1  christos          $WHERE/Configure linux64-mips64
    611      1.1  christos EOF
    612      1.1  christos             maybe_abort();
    613      1.1  christos             return { target => "linux-mips64" };
    614      1.1  christos         }
    615      1.1  christos       ],
    616      1.1  christos       [ 'mips.*-.*-linux2',       { target => "linux-mips32" } ],
    617      1.1  christos       [ 'ppc60x-.*-vxworks.*',    { target => "vxworks-ppc60x" } ],
    618      1.1  christos       [ 'ppcgen-.*-vxworks.*',    { target => "vxworks-ppcgen" } ],
    619      1.1  christos       [ 'pentium-.*-vxworks.*',   { target => "vxworks-pentium" } ],
    620      1.1  christos       [ 'simlinux-.*-vxworks.*',  { target => "vxworks-simlinux" } ],
    621      1.1  christos       [ 'mips-.*-vxworks.*',      { target => "vxworks-mips" } ],
    622      1.1  christos       [ 'e2k-.*-linux.*',         { target => "linux-generic64",
    623      1.1  christos                                     defines => [ 'L_ENDIAN' ] } ],
    624      1.1  christos       [ 'ia64-.*-linux.',         { target => "linux-ia64" } ],
    625      1.1  christos       [ 'sparc64-.*-linux2',
    626      1.1  christos         sub {
    627      1.1  christos             print <<EOF;
    628      1.1  christos WARNING! If you *know* that your GNU C supports 64-bit/V9 ABI and you
    629      1.1  christos          want to build 64-bit library, do this:
    630      1.1  christos          $WHERE/Configure linux64-sparcv9
    631      1.1  christos EOF
    632      1.1  christos             maybe_abort();
    633      1.1  christos             return { target => "linux-sparcv9" };
    634      1.1  christos         }
    635      1.1  christos       ],
    636      1.1  christos       [ 'sparc-.*-linux2',
    637      1.1  christos         sub {
    638      1.1  christos             my $KARCH = `awk '/^type/{print \$3;exit(0);}' /proc/cpuinfo`;
    639      1.1  christos             $KARCH //= "sun4";
    640      1.1  christos             return { target => "linux-sparcv9" } if $KARCH =~ 'sun4u.*';
    641      1.1  christos             return { target => "linux-sparcv8" } if $KARCH =~ 'sun4[md]';
    642      1.1  christos             return { target => "linux-generic32",
    643      1.1  christos                      defines => [ 'L_ENDIAN' ] };
    644      1.1  christos         }
    645      1.1  christos       ],
    646      1.1  christos       [ 'parisc.*-.*-linux2',
    647      1.1  christos         sub {
    648      1.1  christos             # 64-bit builds under parisc64 linux are not supported and
    649      1.1  christos             # compiler is expected to generate 32-bit objects...
    650      1.1  christos             my $CPUARCH =
    651      1.1  christos                 `awk '/cpu family/{print substr(\$5,1,3); exit(0);}' /proc/cpuinfo`;
    652      1.1  christos             my $CPUSCHEDULE =
    653      1.1  christos                 `awk '/^cpu.[ 	]*: PA/{print substr(\$3,3); exit(0);}' /proc/cpuinfo`;
    654      1.1  christos             # TODO XXX  Model transformations
    655      1.1  christos             # 0. CPU Architecture for the 1.1 processor has letter suffixes.
    656      1.1  christos             #    We strip that off assuming no further arch. identification
    657      1.1  christos             #    will ever be used by GCC.
    658      1.1  christos             # 1. I'm most concerned about whether is a 7300LC is closer to a
    659      1.1  christos             #    7100 versus a 7100LC.
    660      1.1  christos             # 2. The variant 64-bit processors cause concern should GCC support
    661      1.1  christos             #    explicit schedulers for these chips in the future.
    662      1.1  christos             #         PA7300LC -> 7100LC (1.1)
    663      1.1  christos             #         PA8200   -> 8000   (2.0)
    664      1.1  christos             #         PA8500   -> 8000   (2.0)
    665      1.1  christos             #         PA8600   -> 8000   (2.0)
    666      1.1  christos             $CPUSCHEDULE =~ s/7300LC/7100LC/;
    667      1.1  christos             $CPUSCHEDULE =~ s/8.00/8000/;
    668      1.1  christos             return
    669      1.1  christos                 { target => "linux-generic32",
    670      1.1  christos                   defines => [ 'B_ENDIAN' ],
    671      1.1  christos                   cflags => [ "-mschedule=$CPUSCHEDULE", "-march=$CPUARCH" ],
    672      1.1  christos                   cxxflags => [ "-mschedule=$CPUSCHEDULE", "-march=$CPUARCH" ]
    673      1.1  christos                 };
    674      1.1  christos         }
    675      1.1  christos       ],
    676      1.1  christos       [ 'armv[1-3].*-.*-linux2',  { target => "linux-generic32" } ],
    677      1.1  christos       [ 'armv[7-9].*-.*-linux2',  { target => "linux-armv4",
    678      1.1  christos                                     cflags => [ '-march=armv7-a' ],
    679      1.1  christos                                     cxxflags => [ '-march=armv7-a' ] } ],
    680      1.1  christos       [ 'arm.*-.*-linux2',        { target => "linux-armv4" } ],
    681      1.1  christos       [ 'aarch64-.*-linux2',      { target => "linux-aarch64" } ],
    682      1.1  christos       [ 'sh.*b-.*-linux2',        { target => "linux-generic32",
    683      1.1  christos                                     defines => [ 'B_ENDIAN' ] } ],
    684      1.1  christos       [ 'sh.*-.*-linux2',         { target => "linux-generic32",
    685      1.1  christos                                     defines => [ 'L_ENDIAN' ] } ],
    686      1.1  christos       [ 'm68k.*-.*-linux2',       { target => "linux-generic32",
    687      1.1  christos                                     defines => [ 'B_ENDIAN' ] } ],
    688      1.1  christos       [ 's390-.*-linux2',         { target => "linux-generic32",
    689      1.1  christos                                     defines => [ 'B_ENDIAN' ] } ],
    690      1.1  christos       [ 's390x-.*-linux2',
    691      1.1  christos         sub {
    692      1.1  christos             # Disabled until a glibc bug is fixed; see Configure.
    693      1.1  christos             if (0
    694      1.1  christos                 || okrun('egrep -e \'^features.* highgprs\' /proc/cpuinfo >/dev/null') )
    695      1.1  christos                 {
    696      1.1  christos                     print <<EOF;
    697      1.1  christos WARNING! To build "highgprs" 32-bit package, do this:
    698      1.1  christos          $WHERE/Configure linux32-s390x
    699      1.1  christos EOF
    700      1.1  christos                     maybe_abort();
    701      1.1  christos                 }
    702      1.1  christos             return { target => "linux64-s390x" };
    703      1.1  christos         }
    704      1.1  christos       ],
    705      1.1  christos       [ 'x86_64-.*-linux.',
    706      1.1  christos         sub {
    707      1.1  christos             return { target => "linux-x32" }
    708      1.1  christos                 if okrun("$CC -dM -E -x c /dev/null 2>&1",
    709      1.1  christos                          'grep -q ILP32 >/dev/null');
    710      1.1  christos             return { target => "linux-x86_64" };
    711      1.1  christos         }
    712      1.1  christos       ],
    713      1.1  christos       [ '.*86-.*-linux2',
    714      1.1  christos         sub {
    715      1.1  christos             # On machines where the compiler understands -m32, prefer a
    716      1.1  christos             # config target that uses it
    717      1.1  christos             return { target => "linux-x86" }
    718      1.1  christos                 if okrun("$CC -m32 -E -x c /dev/null >/dev/null 2>&1");
    719      1.1  christos             return { target => "linux-elf" };
    720      1.1  christos         }
    721      1.1  christos       ],
    722      1.1  christos       [ '.*86-.*-linux1',         { target => "linux-aout" } ],
    723      1.1  christos       [ 'riscv64-.*-linux.',      { target => "linux64-riscv64" } ],
    724      1.1  christos       [ '.*-.*-linux.',           { target => "linux-generic32" } ],
    725      1.1  christos       [ 'sun4[uv].*-.*-solaris2',
    726      1.1  christos         sub {
    727      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS};
    728      1.1  christos             my $ISA64 = `isainfo 2>/dev/null | grep sparcv9`;
    729      1.1  christos             my $KB = $KERNEL_BITS // '64';
    730      1.1  christos             if ( $ISA64 ne "" && $KB eq '64' ) {
    731      1.1  christos                 if ( $CCVENDOR eq "sun" && $CCVER >= 500 ) {
    732      1.1  christos                     print <<EOF;
    733      1.1  christos WARNING! To build 32-bit package, do this:
    734      1.1  christos          $WHERE/Configure solaris-sparcv9-cc
    735      1.1  christos EOF
    736      1.1  christos                     maybe_abort();
    737      1.1  christos                 } elsif ( $CCVENDOR eq "gnu" && $GCC_ARCH eq "-m64" ) {
    738      1.1  christos                     # $GCC_ARCH denotes default ABI chosen by compiler driver
    739      1.1  christos                     # (first one found on the $PATH). I assume that user
    740      1.1  christos                     # expects certain consistency with the rest of his builds
    741      1.1  christos                     # and therefore switch over to 64-bit. <appro>
    742      1.1  christos                     print <<EOF;
    743      1.1  christos WARNING! To build 32-bit package, do this:
    744      1.1  christos          $WHERE/Configure solaris-sparcv9-gcc
    745      1.1  christos EOF
    746      1.1  christos                     maybe_abort();
    747      1.1  christos                     return { target => "solaris64-sparcv9-gcc" };
    748      1.1  christos                 } elsif ( $GCC_ARCH eq "-m32" ) {
    749      1.1  christos                     print <<EOF;
    750      1.1  christos NOTICE! If you *know* that your GNU C supports 64-bit/V9 ABI and you wish
    751      1.1  christos         to build 64-bit library, do this:
    752      1.1  christos         $WHERE/Configure solaris64-sparcv9-gcc
    753      1.1  christos EOF
    754      1.1  christos                     maybe_abort();
    755      1.1  christos                 }
    756      1.1  christos             }
    757      1.1  christos             return { target => "solaris64-sparcv9-cc" }
    758      1.1  christos                 if $ISA64 ne "" && $KB eq '64';
    759      1.1  christos             return { target => "solaris-sparcv9-cc" };
    760      1.1  christos         }
    761      1.1  christos       ],
    762      1.1  christos       [ 'sun4m-.*-solaris2',      { target => "solaris-sparcv8" } ],
    763      1.1  christos       [ 'sun4d-.*-solaris2',      { target => "solaris-sparcv8" } ],
    764      1.1  christos       [ 'sun4.*-.*-solaris2',     { target => "solaris-sparcv7" } ],
    765      1.1  christos       [ '.*86.*-.*-solaris2',
    766      1.1  christos         sub {
    767      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS};
    768      1.1  christos             my $ISA64 = `isainfo 2>/dev/null | grep amd64`;
    769      1.1  christos             my $KB = $KERNEL_BITS // '64';
    770      1.1  christos             if ($ISA64 ne "" && $KB eq '64') {
    771      1.1  christos                 return { target => "solaris64-x86_64-gcc" } if $CCVENDOR eq "gnu";
    772      1.1  christos                 return { target => "solaris64-x86_64-cc" };
    773      1.1  christos             }
    774      1.1  christos             my $REL = uname('-r');
    775      1.1  christos             $REL =~ s/5\.//;
    776      1.1  christos             my @tmp_disable = ();
    777      1.1  christos             push @tmp_disable, 'sse2' if int($REL) < 10;
    778      1.1  christos             #There is no solaris-x86-cc target
    779      1.1  christos             return { target => "solaris-x86-gcc",
    780      1.1  christos                      disable => [ @tmp_disable ] };
    781      1.1  christos         }
    782      1.1  christos       ],
    783      1.1  christos       # We don't have any sunos target in Configurations/*.conf, so why here?
    784      1.1  christos       [ '.*-.*-sunos4',           { target => "sunos" } ],
    785      1.1  christos       [ '.*86.*-.*-bsdi4',        { target => "BSD-x86-elf",
    786      1.1  christos                                     lflags => [ '-ldl' ],
    787      1.1  christos                                     disable => [ 'sse2' ] } ],
    788      1.1  christos       [ 'alpha.*-.*-.*bsd.*',     { target => "BSD-generic64",
    789      1.1  christos                                     defines => [ 'L_ENDIAN' ] } ],
    790      1.1  christos       [ 'powerpc64-.*-.*bsd.*',   { target => "BSD-generic64",
    791      1.1  christos                                     defines => [ 'B_ENDIAN' ] } ],
    792      1.1  christos       [ 'riscv64-.*-.*bsd.*',     { target => "BSD-riscv64" } ],
    793      1.1  christos       [ 'sparc64-.*-.*bsd.*',     { target => "BSD-sparc64" } ],
    794      1.1  christos       [ 'ia64-.*-.*bsd.*',        { target => "BSD-ia64" } ],
    795      1.1  christos       [ 'x86_64-.*-dragonfly.*',  { target => "BSD-x86_64" } ],
    796      1.1  christos       [ 'amd64-.*-.*bsd.*',       { target => "BSD-x86_64" } ],
    797      1.1  christos       [ 'arm64-.*-.*bsd.*',       { target => "BSD-aarch64" } ],
    798      1.1  christos       [ '.*86.*-.*-.*bsd.*',
    799      1.1  christos         sub {
    800      1.1  christos             # mimic ld behaviour when it's looking for libc...
    801      1.1  christos             my $libc;
    802      1.1  christos             if ( -l "/usr/lib/libc.so" ) {
    803      1.1  christos                 $libc = "/usr/lib/libc.so";
    804      1.1  christos             } else {
    805      1.1  christos                 # ld searches for highest libc.so.* and so do we
    806      1.1  christos                 $libc =
    807      1.1  christos                     `(ls /usr/lib/libc.so.* /lib/libc.so.* | tail -1) 2>/dev/null`;
    808      1.1  christos             }
    809      1.1  christos             my $what = `file -L $libc 2>/dev/null`;
    810      1.1  christos             return { target => "BSD-x86-elf" } if $what =~ /ELF/;
    811      1.1  christos             return { target => "BSD-x86",
    812      1.1  christos                      disable => [ 'sse2' ] };
    813      1.1  christos         }
    814      1.1  christos       ],
    815      1.1  christos       [ '.*-.*-.*bsd.*',          { target => "BSD-generic32" } ],
    816      1.1  christos       [ 'x86_64-.*-haiku',        { target => "haiku-x86_64" } ],
    817      1.1  christos       [ '.*-.*-haiku',            { target => "haiku-x86" } ],
    818      1.1  christos       [ '.*-.*-osf',              { target => "osf1-alpha" } ],
    819      1.1  christos       [ '.*-.*-tru64',            { target => "tru64-alpha" } ],
    820      1.1  christos       [ '.*-.*-[Uu]nix[Ww]are7',
    821      1.1  christos         sub {
    822      1.1  christos             return { target => "unixware-7",
    823      1.1  christos                      disable => [ 'sse2' ] } if $CCVENDOR eq "gnu";
    824      1.1  christos             return { target => "unixware-7",
    825      1.1  christos                      defines => [ '__i386__' ] };
    826      1.1  christos         }
    827      1.1  christos       ],
    828      1.1  christos       [ '.*-.*-[Uu]nix[Ww]are20.*', { target => "unixware-2.0",
    829      1.1  christos                                       disable => [ 'sse2', 'sha512' ] } ],
    830      1.1  christos       [ '.*-.*-[Uu]nix[Ww]are21.*', { target => "unixware-2.1",
    831      1.1  christos                                       disable => [ 'sse2', 'sha512' ] } ],
    832      1.1  christos       [ '.*-.*-vos',              { target => "vos",
    833      1.1  christos                                     disable => [ 'threads', 'shared', 'asm',
    834      1.1  christos                                                  'dso' ] } ],
    835      1.1  christos       [ 'BS2000-siemens-sysv4',   { target => "BS2000-OSD" } ],
    836      1.1  christos       [ 'i[3456]86-.*-cygwin',    { target => "Cygwin-x86" } ],
    837      1.1  christos       [ '.*-.*-cygwin',
    838      1.1  christos         sub { return { target => "Cygwin-${MACHINE}" } } ],
    839      1.1  christos       [ 'x86-.*-android|i.86-.*-android', { target => "android-x86" } ],
    840      1.1  christos       [ 'armv[7-9].*-.*-android', { target => "android-armeabi",
    841      1.1  christos                                     cflags => [ '-march=armv7-a' ],
    842      1.1  christos                                     cxxflags => [ '-march=armv7-a' ] } ],
    843      1.1  christos       [ 'arm.*-.*-android',       { target => "android-armeabi" } ],
    844      1.1  christos       [ '.*-hpux1.*',
    845      1.1  christos         sub {
    846      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS};
    847      1.1  christos             my %common_return = ( defines => [ '_REENTRANT' ] );
    848      1.1  christos             $KERNEL_BITS ||= `getconf KERNEL_BITS 2>/dev/null` // '32';
    849      1.1  christos             # See <sys/unistd.h> for further info on CPU_VERSION.
    850      1.1  christos             my $CPU_VERSION = `getconf CPU_VERSION 2>/dev/null` // 0;
    851      1.1  christos             if ( $CPU_VERSION >= 768 ) {
    852      1.1  christos                 # IA-64 CPU
    853      1.1  christos                 return { target => "hpux64-ia64",
    854      1.1  christos                          %common_return }
    855      1.1  christos                     if $KERNEL_BITS eq '64' && ! $CCVENDOR;
    856      1.1  christos                 return { target => "hpux-ia64",
    857      1.1  christos                          %common_return };
    858      1.1  christos             }
    859      1.1  christos             if ( $CPU_VERSION >= 532 ) {
    860      1.1  christos                 # PA-RISC 2.x CPU
    861      1.1  christos                 # PA-RISC 2.0 is no longer supported as separate 32-bit
    862      1.1  christos                 # target. This is compensated for by run-time detection
    863      1.1  christos                 # in most critical assembly modules and taking advantage
    864      1.1  christos                 # of 2.0 architecture in PA-RISC 1.1 build.
    865      1.1  christos                 my $target = ($CCVENDOR eq "gnu" && $GCC_BITS eq '64')
    866      1.1  christos                     ? "hpux64-parisc2"
    867      1.1  christos                     : "hpux-parisc1_1";
    868      1.1  christos                 if ( $KERNEL_BITS eq '64' && ! $CCVENDOR ) {
    869      1.1  christos                     print <<EOF;
    870      1.1  christos WARNING! To build 64-bit package, do this:
    871      1.1  christos          $WHERE/Configure hpux64-parisc2-cc
    872      1.1  christos EOF
    873      1.1  christos                     maybe_abort();
    874      1.1  christos                 }
    875      1.1  christos                 return { target => $target,
    876      1.1  christos                          %common_return };
    877      1.1  christos             }
    878      1.1  christos             # PA-RISC 1.1+ CPU?
    879      1.1  christos             return { target => "hpux-parisc1_1",
    880      1.1  christos                      %common_return } if $CPU_VERSION >= 528;
    881      1.1  christos             # PA-RISC 1.0 CPU
    882      1.1  christos             return { target => "hpux-parisc",
    883      1.1  christos                      %common_return } if $CPU_VERSION >= 523;
    884      1.1  christos             # Motorola(?) CPU
    885      1.1  christos             return { target => "hpux",
    886      1.1  christos                      %common_return };
    887      1.1  christos         }
    888      1.1  christos       ],
    889      1.1  christos       [ '.*-hpux',                { target => "hpux-parisc" } ],
    890      1.1  christos       [ '.*-aix',
    891      1.1  christos         sub {
    892      1.1  christos             my %config = ();
    893      1.1  christos             my $KERNEL_BITS = $ENV{KERNEL_BITS};
    894      1.1  christos             $KERNEL_BITS ||= `getconf KERNEL_BITMODE 2>/dev/null`;
    895      1.1  christos             $KERNEL_BITS ||= '32';
    896      1.1  christos             my $OBJECT_MODE = $ENV{OBJECT_MODE};
    897      1.1  christos             $OBJECT_MODE ||= 32;
    898      1.1  christos             $config{target} = "aix";
    899      1.1  christos             if ( $OBJECT_MODE == 64 ) {
    900      1.1  christos                 print 'Your $OBJECT_MODE was found to be set to 64';
    901      1.1  christos                 $config{target} = "aix64";
    902      1.1  christos             } else {
    903      1.1  christos                 if ( $CCVENDOR ne 'gnu' && $KERNEL_BITS eq '64' ) {
    904      1.1  christos                     print <<EOF;
    905      1.1  christos WARNING! To build 64-bit package, do this:
    906      1.1  christos          $WHERE/Configure aix64-cc
    907      1.1  christos EOF
    908      1.1  christos                     maybe_abort();
    909      1.1  christos                 }
    910      1.1  christos             }
    911      1.1  christos             if ( okrun(
    912      1.1  christos                        "(lsattr -E -O -l `lsdev -c processor|awk '{print \$1;exit}'`",
    913      1.1  christos                        'grep -i powerpc) >/dev/null 2>&1') ) {
    914      1.1  christos                 # this applies even to Power3 and later, as they return
    915      1.1  christos                 # PowerPC_POWER[345]
    916      1.1  christos             } else {
    917      1.1  christos                 $config{disable} = [ 'asm' ];
    918      1.1  christos             }
    919      1.1  christos             return { %config };
    920      1.1  christos         }
    921      1.1  christos       ],
    922      1.1  christos 
    923      1.1  christos       # Windows values found by looking at Perl 5's win32/win32.c
    924      1.1  christos       [ '(amd64|ia64|x86|ARM)-.*?-Windows NT',
    925      1.1  christos         sub {
    926      1.1  christos             # If we determined the arch by asking cl, take that value,
    927      1.1  christos             # otherwise the SYSTEM we got from from POSIX::uname().
    928      1.1  christos             my $arch = $CL_ARCH // $1;
    929      1.1  christos             my $config;
    930      1.1  christos 
    931      1.1  christos             if ($arch) {
    932      1.1  christos                 $config = { 'amd64' => { target => 'VC-WIN64A'    },
    933      1.1  christos                             'ia64'  => { target => 'VC-WIN64I'    },
    934      1.1  christos                             'x86'   => { target => 'VC-WIN32'     },
    935      1.1  christos                             'x64'   => { target => 'VC-WIN64A'    },
    936      1.1  christos                             'ARM'   => { target => 'VC-WIN64-ARM' },
    937      1.1  christos                           } -> {$arch};
    938      1.1  christos                 die <<_____ unless defined $config;
    939      1.1  christos ERROR
    940      1.1  christos I do not know how to handle ${arch}.
    941      1.1  christos _____
    942      1.1  christos             }
    943      1.1  christos             die <<_____ unless defined $config;
    944      1.1  christos ERROR
    945      1.1  christos Could not figure out the architecture.
    946      1.1  christos _____
    947      1.1  christos 
    948      1.1  christos             return $config;
    949      1.1  christos         }
    950      1.1  christos       ],
    951      1.1  christos 
    952      1.1  christos       # VMS values found by observation on existing machinery.
    953      1.1  christos       [ 'VMS_AXP-.*?-OpenVMS',    { target => 'vms-alpha'  } ],
    954      1.1  christos       [ 'VMS_IA64-.*?-OpenVMS',   { target => 'vms-ia64'   } ],
    955      1.1  christos       [ 'VMS_x86_64-.*?-OpenVMS', { target => 'vms-x86_64' } ],
    956      1.1  christos 
    957      1.1  christos       # TODO: There are a few more choices among OpenSSL config targets, but
    958      1.1  christos       # reaching them involves a bit more than just a host tripet.  Select
    959      1.1  christos       # environment variables could do the job to cover for more granular
    960      1.1  christos       # build options such as data model (ILP32 or LP64), thread support
    961      1.1  christos       # model (PUT, SPT or nothing), target execution environment (OSS or
    962      1.1  christos       # GUARDIAN).  And still, there must be some kind of default when
    963      1.1  christos       # nothing else is said.
    964      1.1  christos       #
    965      1.1  christos       # nsv is a virtual x86 environment, equivalent to nsx, so we enforce
    966      1.1  christos       # the latter.
    967      1.1  christos       [ 'nse-tandem-nsk.*',       { target => 'nonstop-nse' } ],
    968      1.1  christos       [ 'nsv-tandem-nsk.*',       { target => 'nonstop-nsx' } ],
    969      1.1  christos       [ 'nsx-tandem-nsk.*',       { target => 'nonstop-nsx' } ],
    970      1.1  christos 
    971      1.1  christos     ];
    972      1.1  christos 
    973      1.1  christos # Map GUESSOS into OpenSSL terminology.
    974      1.1  christos # Returns a hash table with diverse entries, most importantly 'target',
    975      1.1  christos # but also other entries that are fitting for Configure's %config
    976      1.1  christos # and MACHINE.
    977      1.1  christos # It would be nice to fix this so that this weren't necessary. :( XXX
    978      1.1  christos sub map_guess {
    979      1.1  christos     my $GUESSOS = shift;
    980      1.1  christos 
    981      1.1  christos     foreach my $tuple ( @$map_patterns ) {
    982      1.1  christos         my $pat = @$tuple[0];
    983      1.1  christos         next if $GUESSOS !~ /^${pat}$/;
    984      1.1  christos         my $result = @$tuple[1];
    985      1.1  christos         $result = $result->() if ref $result eq 'CODE';
    986      1.1  christos         return %$result;
    987      1.1  christos     }
    988      1.1  christos 
    989      1.1  christos     # Last case, return "z" from x-y-z
    990      1.1  christos     my @fields = split(/-/, $GUESSOS);
    991      1.1  christos     return ( target => $fields[2] );
    992      1.1  christos }
    993      1.1  christos 
    994      1.1  christos # gcc < 2.8 does not support -march=ultrasparc
    995      1.1  christos sub check_solaris_sparc8 {
    996      1.1  christos     my $OUT = shift;
    997      1.1  christos     if ( $CCVENDOR eq 'gnu' && $CCVER < 208 ) {
    998      1.1  christos         if ( $OUT eq 'solaris-sparcv9-gcc' ) {
    999      1.1  christos             print <<EOF;
   1000      1.1  christos WARNING! Downgrading to solaris-sparcv8-gcc
   1001      1.1  christos          Upgrade to gcc-2.8 or later.
   1002      1.1  christos EOF
   1003      1.1  christos             maybe_abort();
   1004      1.1  christos             return 'solaris-sparcv8-gcc';
   1005      1.1  christos         }
   1006      1.1  christos         if ( $OUT eq "linux-sparcv9" ) {
   1007      1.1  christos             print <<EOF;
   1008      1.1  christos WARNING! Downgrading to linux-sparcv8
   1009      1.1  christos          Upgrade to gcc-2.8 or later.
   1010      1.1  christos EOF
   1011      1.1  christos             maybe_abort();
   1012      1.1  christos             return 'linux-sparcv8';
   1013      1.1  christos         }
   1014      1.1  christos     }
   1015      1.1  christos     return $OUT;
   1016      1.1  christos }
   1017      1.1  christos 
   1018      1.1  christos ###
   1019      1.1  christos ###   MAIN PROCESSING
   1020      1.1  christos ###
   1021      1.1  christos 
   1022      1.1  christos sub get_platform {
   1023      1.1  christos     my %options = @_;
   1024      1.1  christos 
   1025      1.1  christos     $VERBOSE = 1 if defined $options{verbose};
   1026      1.1  christos     $WAIT = 0 if defined $options{nowait};
   1027      1.1  christos     $CC = $options{CC};
   1028      1.1  christos     $CROSS_COMPILE = $options{CROSS_COMPILE} // '';
   1029      1.1  christos 
   1030      1.1  christos     my $GUESSOS = guess_system();
   1031      1.1  christos     determine_compiler_settings();
   1032      1.1  christos 
   1033      1.1  christos     my %ret = map_guess($GUESSOS);
   1034      1.1  christos     $ret{target} = check_solaris_sparc8($ret{target});
   1035      1.1  christos     return %ret;
   1036      1.1  christos }
   1037      1.1  christos 
   1038      1.1  christos 1;
   1039