util/perl/OpenSSL/config.pm: Don't detect removed directories in
[openssl.git] / util / perl / OpenSSL / config.pm
1 #! /usr/bin/env perl
2 # Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved.
3 #
4 # Licensed under the Apache License 2.0 (the "License").  You may not use
5 # this file except in compliance with the License.  You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
8
9 # Determine the operating system and run ./Configure.  Far descendant from
10 # Apache's minarch and GuessOS.
11
12 package OpenSSL::config;
13
14 use strict;
15 use warnings;
16 use Getopt::Std;
17 use File::Basename;
18
19 # These control our behavior.
20 my $DRYRUN;
21 my $VERBOSE;
22 my $WAIT = 1;
23 my $WHERE = dirname($0);
24
25 # Machine type, etc., used to determine the platform
26 my $MACHINE;
27 my $RELEASE;
28 my $SYSTEM;
29 my $VERSION;
30 my $CCVER;
31 my $GCCVER;
32 my $GCC_BITS;
33 my $GCC_ARCH;
34
35 # Some environment variables; they will affect Configure
36 my $PERL = $ENV{PERL} // $^X // 'perl';
37 my $CONFIG_OPTIONS = $ENV{CONFIG_OPTIONS} // '';
38 my $CC = $ENV{CC} // 'cc';
39 my $CROSS_COMPILE = $ENV{CROSS_COMPILE} // "";
40 my $KERNEL_BITS = $ENV{KERNEL_BITS} // '';
41
42 # This is what we will set as the target for calling Configure.
43 my $options = '';
44
45 # Environment that will be passed to Configure
46 my $__CNF_CPPDEFINES = '';
47 my $__CNF_CPPINCLUDES = '';
48 my $__CNF_CPPFLAGS = '';
49 my $__CNF_CFLAGS = '';
50 my $__CNF_CXXFLAGS = '';
51 my $__CNF_LDFLAGS = '';
52 my $__CNF_LDLIBS = '';
53
54 # Pattern matches against "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}"
55 my $simple_guess_patterns = [
56     [ 'A\/UX:',               'm68k-apple-aux3' ],
57     [ 'AIX:[3-9]:4:',         '${MACHINE}-ibm-aix' ],
58     [ 'AIX:.*:[5-9]:',        '${MACHINE}-ibm-aix' ],
59     [ 'AIX:',                 '${MACHINE}-ibm-aix3' ],
60     [ 'HI-UX:',               '${MACHINE}-hi-hiux' ],
61     [ 'IRIX:6.',              'mips3-sgi-irix' ],
62     [ 'IRIX64:',              'mips4-sgi-irix64' ],
63     [ 'Linux:[2-9]',          '${MACHINE}-whatever-linux2' ],
64     [ 'Linux:1',              '${MACHINE}-whatever-linux1' ],
65     [ 'GNU',                  'hurd-x86' ],
66     [ 'LynxOS:',              '${MACHINE}-lynx-lynxos' ],
67     # BSD/OS always says 386
68     [ 'BSD\/OS:4.*',          'i486-whatever-bsdi4' ],
69     [ 'BSD\/386:.*|BSD\/OS:', '${MACHINE}-whatever-bsdi' ],
70     [ 'DragonFly:',           '${MACHINE}-whatever-dragonfly' ],
71     [ 'FreeBSD:',             '${MACHINE}-whatever-freebsd' ],
72     [ 'Haiku:',               '${MACHINE}-whatever-haiku' ],
73     [ 'NetBSD:',              '${MACHINE}-whatever-netbsd' ],
74     [ 'OpenBSD:',             '${MACHINE}-whatever-openbsd' ],
75     [ 'OpenUNIX:',            '${MACHINE}-unknown-OpenUNIX${VERSION}' ],
76     [ 'Paragon.*:',           'i860-intel-osf1' ],
77     [ 'Rhapsody:',            'ppc-apple-rhapsody' ],
78     [ 'SunOS:5.',             '${MACHINE}-whatever-solaris2' ],
79     [ 'SunOS:',               '${MACHINE}-sun-sunos4' ],
80     [ 'UNIX_System_V:4.*:',   '${MACHINE}-whatever-sysv4' ],
81     [ 'VOS:.*:.*:i786',       'i386-stratus-vos' ],
82     [ 'VOS:.*:.*:',           'hppa1.1-stratus-vos' ],
83     [ '.*:4.*:R4.*:m88k',     '${MACHINE}-whatever-sysv4' ],
84     [ 'DYNIX\/ptx:4.*:',      '${MACHINE}-whatever-sysv4' ],
85     [ ':4.0:3.0:3[34]',       'i486-ncr-sysv4' ],
86     [ 'ULTRIX:',              '${MACHINE}-unknown-ultrix' ],
87     [ 'POSIX-BC',             'BS2000-siemens-sysv4' ],
88     [ 'machten:',             '${MACHINE}-tenon-${SYSTEM}' ],
89     [ 'library:',             '${MACHINE}-ncr-sysv4' ],
90     [ 'ConvexOS:.*:11.0:',    '${MACHINE}-v11-${SYSTEM}' ],
91     [ 'MINGW64.*:.*x86_64',   '${MACHINE}-whatever-mingw64' ],
92     [ 'MINGW',                '${MACHINE}-whatever-mingw' ],
93     [ 'CYGWIN',               '${MACHINE}-pc-cygwin' ],
94     [ 'vxworks',              '${MACHINE}-whatever-vxworks' ],
95     [ 'Darwin:.*Power',       'ppc-apple-darwin' ],
96     [ 'Darwin:.*x86_64',      'x86_64-apple-darwin' ],
97     [ 'Darwin:',              'i686-apple-darwin' ],
98 ];
99
100 # More complex cases that require run-time code.
101 my $complex_sys_list = [
102     [ 'HP-UX:', sub {
103         my $HPUXVER = $RELEASE;
104         $HPUXVER = s/[^.]*.[0B]*//;
105         # HPUX 10 and 11 targets are unified
106         return "${MACHINE}-hp-hpux1x" if $HPUXVER =~ m@1[0-9]@;
107         return "${MACHINE}-hp-hpux";
108     } ],
109
110     [ 'BSD/386:.*:.*:.*486.*|BSD/OS:.*:.*:.*:.*486', sub {
111         my $BSDVAR = `/sbin/sysctl -n hw.model`;
112         return "i586-whatever-bsdi" if $BSDVAR =~ m@Pentium@;
113         return "i386-whatever-bsdi";
114     } ],
115
116     [ 'FreeBSD:.*:.*:.*386', sub {
117         my $VERS = $RELEASE;
118         $VERS =~ s/[-(].*//;
119         my $MACH = `sysctl -n hw.model`;
120         $MACH = "i386" if $MACH =~ m@386@;
121         $MACH = "i486" if $MACH =~ m@486@;
122         $MACH = "i686" if $MACH =~ m@Pentium II@;
123         $MACH = "i586" if $MACH =~ m@Pentium@;
124         $MACH = "$MACHINE" if $MACH !~ /i.86/;
125         my $ARCH = 'whatever';
126         $ARCH = "pc" if $MACH =~ m@i[0-9]86@;
127         return "${MACH}-${ARCH}-freebsd${VERS}";
128     } ],
129
130     [ 'NetBSD:.*:.*:.*386', sub {
131         my $hw = `/usr/sbin/sysctl -n hw.model || /sbin/sysctl -n hw.model`;
132         $hw =~  s@.*(.)86-class.*@i${1}86@;
133         return "${hw}-whatever-netbsd";
134     } ],
135
136     [ 'OSF1:.*:.*:.*alpha', sub {
137         my $OSFMAJOR = $RELEASE;
138         $OSFMAJOR =~ 's/^V([0-9]*)\..*$/\1/';
139         return "${MACHINE}-dec-tru64" if $OSFMAJOR =~ m@[45]@;
140         return "${MACHINE}-dec-osf";
141     } ],
142 ];
143
144
145 # Run a command, return true if exit zero else false.
146 # Multiple args are glued together into a pipeline.
147 # Name comes from OpenSSL tests, often written as "ok(run(...."
148 sub okrun {
149     my $command = join(' | ', @_);
150     my $status = system($command) >> 8;
151     return $status == 0;
152 }
153
154 # Give user a chance to abort/interrupt if interactive if interactive.
155 sub maybe_abort {
156     if ( $WAIT && -t 1 ) {
157         eval {
158             local $SIG{ALRM} = sub { die "Timeout"; };
159             local $| = 1;
160             alarm(5);
161             print "You have about five seconds to abort: ";
162             my $ignored = <STDIN>;
163             alarm(0);
164         };
165         print "\n" if $@ =~ /Timeout/;
166     }
167 }
168
169 # Parse options.
170 sub call_getopt {
171     our($opt_d);
172     our($opt_h);
173     our($opt_t);
174     our($opt_v);
175     our($opt_w);
176     getopts("dhtvw");
177
178     # Building on windows needs a VisualC target.
179     my $iswin = $^O eq 'MSWin32';
180     my $foundvc = 0;
181
182     if ( $opt_h ) {
183         print <<'EOF';
184 Usage: config [options] [args...]
185   -d    Build with debugging when possible.
186   -t    Test mode, do not run the Configure perl script.
187   -v    Verbose mode, show the exact Configure call that is being made.
188   -w    Do not wait after displaying any warnings.
189   -h    This help.
190 All other arguments are passed to the Configure script.
191 See INSTALL for instructions.
192 EOF
193         exit;
194     }
195     # All other parameters are passed to Configure
196     foreach my $opt ( @ARGV ) {
197         # Could make the VC- part optional, but that might cause
198         # confusion.
199         if ( $iswin && $opt =~ /^VC-(WIN32|WIN64A|WIN64I|CE)$/i ) {
200             $opt = tr/a-z/A-Z/;
201             $opt = "VC-$opt" unless $opt =~ /^VC-/;
202             $foundvc = 1;
203         }
204         $options .= " $opt";
205     }
206     if ( $iswin && !$foundvc ) {
207         print <<EOF;
208 WARNING: Did not find VisualC target.  See INSTALL for details.
209 EOF
210         maybe_abort();
211     }
212     $options = " --debug" if $opt_d;
213     $DRYRUN = $opt_t;
214     $VERBOSE = $opt_v || $opt_t;
215     $WAIT = 0 if $opt_w;
216 }
217
218 # call uname with specified arg, return result.
219 sub uname {
220     my $arg = shift;
221     open UNAME, "uname $arg 2>/dev/null|" or return "unknown";
222     my $line = <UNAME>;
223     close UNAME;
224     $line =~ s/[\r\n]+$//;
225     return "unknown" if $line eq '';
226     return $line;
227 }
228
229 # Set machine type, release, etc., variables.
230 sub get_machine_etc {
231     $MACHINE = $ENV{MACHINE} // uname('-m');
232     $RELEASE = $ENV{RELEASE} // uname('-r');
233     $SYSTEM = $ENV{SYSTEM} // uname("-s");
234     $VERSION = uname('-v');
235 }
236
237 # Expand variable references in a string.
238 sub expand {
239     my $var = shift;
240     $var =~ s/\$\{MACHINE\}/${MACHINE}/;
241     return $var;
242 }
243
244 # Look for ISC/SCO with its unique uname program
245 sub is_sco_uname {
246     open UNAME, "uname -X 2>/dev/null|" or return '';
247     my $line = "";
248     while ( <UNAME> ) {
249         chop;
250         $line = $_ if m@^Release@;
251     }
252     close UNAME;
253     return "" if $line eq '';
254     my @fields = split($line);
255     return $fields[2];
256 }
257
258 sub get_sco_type {
259     my $REL = shift;
260
261     if ( -f "/etc/kconfig" ) {
262         return "${MACHINE}-whatever-isc4" if $REL eq '4.0' || $REL eq '4.1';
263     } else {
264         return "whatever-whatever-sco3" if $REL eq '3.2v4.2';
265         return "whatever-whatever-sco5" if $REL =~ m@3\.2v5\.0.*@;
266         if ( $REL eq "4.2MP" ) {
267             return "whatever-whatever-unixware20" if $VERSION =~ m@2\.0.*@;
268             return "whatever-whatever-unixware21" if $VERSION =~ m@2\.1.*@;
269             return "whatever-whatever-unixware2" if $VERSION =~ m@2.*@;
270         }
271         return "whatever-whatever-unixware1" if $REL eq "4.2";
272         if ( $REL =~ m@5.*@ ) {
273             # We hardcode i586 in place of ${MACHINE} for the following
274             # reason: even though Pentium is minimum requirement for
275             # platforms in question, ${MACHINE} gets always assigned to
276             # i386. This means i386 gets passed to Configure, which will
277             # cause bad assembler code to be generated.
278             return "i586-sco-unixware7" if $VERSION =~ m@[678].*@;
279         }
280     }
281 }
282
283 # Return the cputype-vendor-osversion
284 sub guess_system {
285     # Special-cases for ISC, SCO, Unixware
286     my $REL = is_sco_uname();
287     if ( $REL ne "" ) {
288         my $result = get_sco_type($REL);
289         return expand($result) if $result ne '';
290     }
291
292     # Now pattern-match
293     my $sys = "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}";
294
295     # Simple cases
296     foreach my $tuple ( @$simple_guess_patterns ) {
297         my $pat = @$tuple[0];
298         # Trailing $ omitted on purpose.
299         next if $sys !~ /^$pat/;
300         my $result = @$tuple[1];
301         return expand($result);
302     }
303
304     # Complex cases.
305     foreach my $tuple ( @$complex_sys_list ) {
306         my $pat = @$tuple[0];
307         # Trailing $ omitted on purpose.
308         next if $sys !~ /^$pat/;
309         my $ref = @$tuple[1];
310         my $result = &$ref;
311         return expand($result);
312     }
313
314     # Oh well.
315     return "${MACHINE}-whatever-${SYSTEM}";
316 }
317
318 # Figure out CC, GCCVAR, etc.
319 sub determine_compiler_settings {
320     if ( "$CROSS_COMPILE$CC" eq '' ) {
321         $GCCVER = `gcc -dumpversion 2>/dev/null`;
322         if ( $GCCVER ne "" ) {
323             # Strip off whatever prefix egcs prepends the number with.
324             # Hopefully, this will work for any future prefixes as well.
325             $GCCVER =~ s/^[a-zA-Z]*\-//;
326             # Since gcc 3.1 gcc --version behaviour has changed, but
327             # -dumpversion gives us what we want though, so use that.
328             # We only want the major and minor version numbers.  The
329             # pattern is deliberate; single digit before and after first
330             # dot, e.g. 2.95.1 gives 29
331             $GCCVER =~ s/([0-9])\.([0-9]).*/$1$2/;
332             $GCCVER = int($GCCVER);
333             $CC = 'gcc';
334         }
335     }
336
337     $GCCVER //= 0;
338
339     if ( $SYSTEM eq "HP-UX" ) {
340         # By default gcc is a ILP32 compiler (with long long == 64).
341         $GCC_BITS = "32";
342         if ( $GCCVER >= 30 ) {
343             # PA64 support only came in with gcc 3.0.x.
344             # We check if the preprocessor symbol __LP64__ is defined.
345             if ( okrun('echo __LP64__',
346                     'gcc -v -E -x c - 2>/dev/null',
347                     'grep "^__LP64__" 2>&1 >/dev/null') ) {
348                 # __LP64__ has slipped through, it therefore is not defined
349             } else {
350                 $GCC_BITS = '64';
351             }
352         }
353         return;
354     }
355
356     if ( ${SYSTEM} eq 'AIX' ) {
357         # favor vendor cc over gcc
358         if ( okrun('(cc) 2>&1',
359                 'grep -iv "not found" >/dev/null') ) {
360             $CC = 'cc';
361         }
362         return;
363     }
364
365     if ( $SYSTEM eq "SunOS" ) {
366         if ( $GCCVER >= 30 ) {
367             # 64-bit ABI isn't officially supported in gcc 3.0, but seems
368             # to be working; at the very least 'make test' passes.
369             if ( okrun('gcc -v -E -x c /dev/null 2>&1',
370                     'grep __arch64__ >/dev/null') ) {
371                 $GCC_ARCH = "-m64"
372             } else {
373                 $GCC_ARCH = "-m32"
374             }
375         }
376         # check for WorkShop C, expected output is "cc: blah-blah C x.x"
377         $CCVER = `(cc -V 2>&1) 2>/dev/null | egrep -e '^cc: .* C [0-9]\.[0-9]'`;
378         $CCVER =~ s/.* C \([0-9]\)\.\([0-9]\).*/$1$2/;
379         $CCVER //= 0;
380         if ( $MACHINE ne 'i86pc' && $CCVER > 40 ) {
381             # overrides gcc!!!
382             $CC = 'cc';
383             if ( $CCVER == 50 ) {
384                 print <<'EOF';
385 WARNING! Found WorkShop C 5.0.
386          Make sure you have patch #107357-01 or later applied.
387 EOF
388                 maybe_abort();
389             }
390         }
391     }
392 }
393
394 # Map GUESSOS into OpenSSL terminology. Also sets some of variables
395 # like $options, $__CNX_xxx.  And uses some, like the KERNEL flags
396 # and MACHINE.
397 # It would be nice to fix this so that this weren't necessary. :( XXX
398 sub map_guess {
399     my $GUESSOS = shift;
400     my $OUT;
401     return 'uClinux-dist64' if $GUESSOS =~ 'uClinux.*64.*';
402     return 'uClinux-dist' if $GUESSOS =~ 'uClinux.*';
403     return "irix-mips3-$CC" if $GUESSOS =~ 'mips3-sgi-irix';
404     if ( $GUESSOS =~ 'mips4-sgi-irix64' ) {
405         print <<EOF;
406 WARNING! To build 64-bit package, do this:
407          $WHERE/Configure irix64-mips4-$CC
408 EOF
409         maybe_abort();
410         return "irix-mips3-$CC";
411     }
412     return "rhapsody-ppc-cc" if $GUESSOS =~ 'ppc-apple-rhapsody';
413     if ( $GUESSOS =~ 'ppc-apple-darwin' ) {
414         my $ISA64 = `sysctl -n hw.optional.64bitops 2>/dev/null`;
415         if ( $ISA64 == 1 && $KERNEL_BITS eq '' ) {
416             print <<EOF;
417 WARNING! To build 64-bit package, do this:
418          $WHERE/Configure darwin64-ppc-cc
419 EOF
420             maybe_abort();
421         }
422         return "darwin64-ppc-cc" if $ISA64 == 1 && $KERNEL_BITS eq '64';
423         return "darwin-ppc-cc";
424     }
425     if ( $GUESSOS =~ 'i.86-apple-darwin' ) {
426         my $ISA64 = `sysctl -n hw.optional.x86_64 2>/dev/null`;
427         if ( $ISA64 == 1 && $KERNEL_BITS eq '' ) {
428             print <<EOF;
429 WARNING! To build 64-bit package, do this:
430          KERNEL_BITS=64 $WHERE/config $options
431 EOF
432             maybe_abort();
433         }
434         return "darwin64-x86_64-cc" if $ISA64 == 1 && $KERNEL_BITS eq '64';
435         return "darwin-i386-cc";
436     }
437     if ( $GUESSOS =~ 'x86_64-apple-darwin' ) {
438         return "darwin-i386-cc" if $KERNEL_BITS eq '32';
439
440         print <<EOF;
441 WARNING! To build 32-bit package, do this:
442          KERNEL_BITS=32 $WHERE/config $options
443 EOF
444         maybe_abort();
445         return "darwin64-x86_64-cc"
446     }
447     if ( $GUESSOS =~ 'armv6+7-.*-iphoneos' ) {
448         $__CNF_CFLAGS .= " -arch armv6 -arch armv7";
449         $__CNF_CXXFLAGS .= " -arch armv6 -arch armv7";
450         return "iphoneos-cross";
451     }
452     if ( $GUESSOS =~ '.*-.*-iphoneos' ) {
453         $__CNF_CFLAGS .= " -arch ${MACHINE}";
454         $__CNF_CXXFLAGS .= " -arch ${MACHINE}";
455         return "iphoneos-cross";
456     }
457     return "ios64-cross" if $GUESSOS =~ 'arm64-.*-iphoneos|.*-.*-ios64';
458     if ( $GUESSOS =~ 'alpha-.*-linux2' ) {
459         my $ISA = `awk '/cpu model/{print \$4;exit(0);}' /proc/cpuinfo`;
460         $ISA //= 'generic';
461         if ( $CC eq "gcc" ) {
462             if ( $ISA =~ 'EV5|EV45' ) {
463                 $__CNF_CFLAGS .= " -mcpu=ev5";
464                 $__CNF_CFLAGS .= " -mcpu=ev5";
465             } elsif ( $ISA =~ 'EV56|PCA56' ) {
466                 $__CNF_CFLAGS .= " -mcpu=ev56";
467                 $__CNF_CXXFLAGS .= " -mcpu=ev56";
468             } else {
469                 $__CNF_CFLAGS .= "-mcpu=ev6";
470                 $__CNF_CXXFLAGS .= "-mcpu=ev6";
471             }
472         }
473         return "linux-alpha-$CC";
474     }
475     if ( $GUESSOS =~ 'ppc64-.*-linux2' ) {
476         if ( $KERNEL_BITS eq '' ) {
477             print <<EOF;
478 WARNING! To build 64-bit package, do this:
479          $WHERE/Configure linux-ppc64
480 EOF
481             maybe_abort();
482         }
483         return "linux-ppc64" if $KERNEL_BITS eq '64';
484         if (!okrun('echo __LP64__',
485                 'gcc -E -x c - 2>/dev/null',
486                 'grep "^__LP64__" 2>&1 >/dev/null') ) {
487             $__CNF_CFLAGS .= " -m32";
488             $__CNF_CXXFLAGS .= " -m32";
489         }
490         return "linux-ppc";
491     }
492     return "linux-ppc64le" if $GUESSOS =~ 'ppc64le-.*-linux2';
493     return "linux-ppc" if $GUESSOS =~ 'ppc-.*-linux2';
494     if ( $GUESSOS =~ 'mips64.*-*-linux2' ) {
495         print <<EOF;
496 WARNING! To build 64-bit package, do this:
497          $WHERE/Configure linux64-mips64
498 EOF
499         maybe_abort();
500         return "linux-mips64";
501     }
502     return "linux-mips32" if $GUESSOS =~ 'mips.*-.*-linux2';
503     return "vxworks-ppc60x" if $GUESSOS =~ 'ppc60x-.*-vxworks*';
504     return "vxworks-ppcgen" if $GUESSOS =~ 'ppcgen-.*-vxworks*';
505     return "vxworks-pentium" if $GUESSOS =~ 'pentium-.*-vxworks*';
506     return "vxworks-simlinux" if $GUESSOS =~ 'simlinux-.*-vxworks*';
507     return "vxworks-mips" if $GUESSOS =~ 'mips-.*-vxworks*';
508     return "linux-generic64 -DL_ENDIAN" if $GUESSOS =~ 'e2k-.*-linux*';
509     return "linux-ia64" if $GUESSOS =~ 'ia64-.*-linux.';
510     if ( $GUESSOS =~ 'sparc64-.*-linux2' ) {
511         print <<EOF;
512 WARNING! If you *know* that your GNU C supports 64-bit/V9 ABI and you
513          want to build 64-bit library, do this:
514          $WHERE/Configure linux64-sparcv9
515 EOF
516         maybe_abort();
517         return "linux-sparcv9";
518     }
519     if ( $GUESSOS =~ 'sparc-.*-linux2' ) {
520         my $KARCH = `awk '/^type/{print \$3;exit(0);}' /proc/cpuinfo`;
521         $KARCH //= "sun4";
522         return "linux-sparcv9" if $KARCH =~ 'sun4u*';
523         return "linux-sparcv8" if $KARCH =~ 'sun4[md]';
524         $__CNF_CPPFLAGS .= " -DB_ENDIAN";
525         return "linux-generic32";
526     }
527     if ( $GUESSOS =~ 'parisc.*-.*-linux2' ) {
528         # 64-bit builds under parisc64 linux are not supported and
529         # compiler is expected to generate 32-bit objects...
530         my $CPUARCH =
531         `awk '/cpu family/{print substr(\$5,1,3); exit(0);}' /proc/cpuinfo`;
532         my $CPUSCHEDULE =
533         `awk '/^cpu.[   ]*: PA/{print substr(\$3,3); exit(0);}' /proc/cpuinfo`;
534         # TODO XXX  Model transformations
535         # 0. CPU Architecture for the 1.1 processor has letter suffixes. We
536         #    strip that off assuming no further arch. identification will ever
537         #    be used by GCC.
538         # 1. I'm most concerned about whether is a 7300LC is closer to a 7100
539         #    versus a 7100LC.
540         # 2. The variant 64-bit processors cause concern should GCC support
541         #    explicit schedulers for these chips in the future.
542         #         PA7300LC -> 7100LC (1.1)
543         #         PA8200   -> 8000   (2.0)
544         #         PA8500   -> 8000   (2.0)
545         #         PA8600   -> 8000   (2.0)
546         $CPUSCHEDULE =~ s/7300LC/7100LC/;
547         $CPUSCHEDULE =~ s/8.00/8000/;
548         # Finish Model transformations
549         $__CNF_CPPFLAGS .= " -DB_ENDIAN";
550         $__CNF_CFLAGS .= " -mschedule=$CPUSCHEDULE -march=$CPUARCH";
551         $__CNF_CXXFLAGS .= " -mschedule=$CPUSCHEDULE -march=$CPUARCH";
552         return "linux-generic32";
553     }
554     return "linux-generic32" if $GUESSOS =~ 'armv[1-3].*-.*-linux2';
555     if ( $GUESSOS =~ 'armv[7-9].*-.*-linux2' ) {
556         $__CNF_CFLAGS .= " -march=armv7-a";
557         $__CNF_CXXFLAGS .= " -march=armv7-a";
558         return "linux-armv4";
559     }
560     return "linux-armv4" if $GUESSOS =~ 'arm.*-.*-linux2';
561     return "linux-aarch64" if $GUESSOS =~ 'aarch64-.*-linux2';
562     if ( $GUESSOS =~ 'sh.*b-.*-linux2' ) {
563         $__CNF_CPPFLAGS .= " -DB_ENDIAN";
564         return "linux-generic32";
565     }
566     if ( $GUESSOS =~ 'sh.*-.*-linux2' ) {
567         $__CNF_CPPFLAGS .= " -DL_ENDIAN";
568         return "linux-generic32";
569     }
570     if ( $GUESSOS =~ 'm68k.*-.*-linux2' || $GUESSOS =~ 's390-.*-linux2' ) {
571         $__CNF_CPPFLAGS .= " -DB_ENDIAN";
572         return "linux-generic32";
573     }
574     if ( $GUESSOS =~ 's390x-.*-linux2' ) {
575         # Disabled until a glibc bug is fixed; see Configure.
576         if (0 || okrun(
577                 'egrep -e \'^features.* highgprs\' /proc/cpuinfo >/dev/null') )
578         {
579             print <<EOF;
580 WARNING! To build "highgprs" 32-bit package, do this:
581          $WHERE/Configure linux32-s390x
582 EOF
583             maybe_abort();
584         }
585         return "linux64-s390x";
586     }
587     if ( $GUESSOS =~ 'x86_64-.*-linux.' ) {
588         return "linux-x32"
589             if okrun("$CC -dM -E -x c /dev/null 2>&1",
590                 'grep -q ILP32 >/dev/null');
591         return "linux-x86_64";
592     }
593     if ( $GUESSOS =~ '.*86-.*-linux2' ) {
594         # On machines where the compiler understands -m32, prefer a
595         # config target that uses it
596         return "linux-x86"
597             if okrun("$CC -m32 -E -x c /dev/null >/dev/null 2>&1");
598         return "linux-elf"
599     }
600     return "linux-aout" if $GUESSOS =~ '.*86-.*-linux1';
601     return "linux-generic32" if $GUESSOS =~ '.*-.*-linux.';
602     if ( $GUESSOS =~ 'sun4[uv].*-.*-solaris2' ) {
603         my $ISA64 = `isainfo 2>/dev/null | grep sparcv9`;
604         if ( $ISA64 ne "" && $KERNEL_BITS eq '' ) {
605             if ( $CC eq "cc" && $CCVER >= 50 ) {
606                 print <<EOF;
607 WARNING! To build 64-bit package, do this:
608          $WHERE/Configure solaris64-sparcv9-cc
609 EOF
610                 maybe_abort();
611             } elsif ( $CC eq "gcc" && $GCC_ARCH eq "-m64" ) {
612                 # $GCC_ARCH denotes default ABI chosen by compiler driver
613                 # (first one found on the $PATH). I assume that user
614                 # expects certain consistency with the rest of his builds
615                 # and therefore switch over to 64-bit. <appro>
616                 print <<EOF;
617 WARNING! To build 32-bit package, do this:
618          $WHERE/Configure solaris-sparcv9-gcc
619 EOF
620                 maybe_abort();
621                 return "solaris64-sparcv9-gcc";
622             } elsif ( $GCC_ARCH eq "-m32" ) {
623                 print <<EOF;
624 NOTICE! If you *know* that your GNU C supports 64-bit/V9 ABI and you wish
625         to build 64-bit library, do this:
626         $WHERE/Configure solaris64-sparcv9-gcc
627 EOF
628                 maybe_abort();
629             }
630         }
631         return "solaris64-sparcv9-$CC" if $ISA64 ne "" && $KERNEL_BITS eq '64';
632         return "solaris-sparcv9-$CC";
633     }
634     return "solaris-sparcv8-$CC" if $GUESSOS =~ 'sun4m-.*-solaris2';
635     return "solaris-sparcv8-$CC" if $GUESSOS =~ 'sun4d-.*-solaris2';
636     return "solaris-sparcv7-$CC" if $GUESSOS =~ 'sun4.*-.*-solaris2';
637     if ( $GUESSOS =~ '.*86.*-.*-solaris2' ) {
638         my $ISA64 = `isainfo 2>/dev/null | grep amd64`;
639         my $KB = $KERNEL_BITS // '64';
640         return "solaris64-x86_64-$CC" if $ISA64 ne "" && $KB eq '64';
641         my $REL = uname('-r');
642         $REL =~ s/5\.//;
643         $options .= " no-sse2" if int($REL) < 10;
644         return "solaris-x86-$CC";
645     }
646     return "sunos-$CC" if $GUESSOS =~ '.*-.*-sunos4';
647     if ( $GUESSOS =~ '.*86.*-.*-bsdi4' ) {
648         $options .= " no-sse2";
649         $__CNF_LDFLAGS .= " -ldl";
650         return "BSD-x86-elf";
651     }
652     if ( $GUESSOS =~ 'alpha.*-.*-.*bsd.*' ) {
653         $__CNF_CPPFLAGS .= " -DL_ENDIAN";
654         return "BSD-generic64";
655     }
656     if ( $GUESSOS =~ 'powerpc64-.*-.*bsd.*' ) {
657         $__CNF_CPPFLAGS .= " -DB_ENDIAN";
658         return "BSD-generic64";
659     }
660     return "BSD-sparc64" if $GUESSOS =~ 'sparc64-.*-.*bsd.*';
661     return "BSD-ia64" if $GUESSOS =~ 'ia64-.*-.*bsd.*';
662     return "BSD-x86_64" if $GUESSOS =~ 'x86_64-.*-dragonfly.*';
663     return "BSD-x86_64" if $GUESSOS =~ 'amd64-.*-.*bsd.*';
664     if ( $GUESSOS =~ '.*86.*-.*-.*bsd.*' ) {
665         # mimic ld behaviour when it's looking for libc...
666         my $libc;
667         if ( -l "/usr/lib/libc.so" ) {
668             $libc = "/usr/lib/libc.so";
669         } else {
670             # ld searches for highest libc.so.* and so do we
671             $libc = 
672             `(ls /usr/lib/libc.so.* /lib/libc.so.* | tail -1) 2>/dev/null`;
673         }
674         my $what = `file -L $libc 2>/dev/null`;
675         return "BSD-x86-elf" if $what =~ /ELF/;
676         $options .= " no-sse2";
677         return "BSD-x86";
678     }
679     return "BSD-generic32" if $GUESSOS =~ '.*-.*-.*bsd.*';
680     return "haiku-x86_64" if $GUESSOS =~ 'x86_64-.*-haiku';
681     return "haiku-x86" if $GUESSOS =~ '.*-.*-haiku';
682     return "osf1-alpha-cc" if $GUESSOS =~ '.*-.*-osf';
683     return "tru64-alpha-cc" if $GUESSOS =~ '.*-.*-tru64';
684     if ( $GUESSOS =~ '.*-.*-[Uu]nix[Ww]are7' ) {
685         $options .= "no-sse2";
686         return "unixware-7-gcc" if $CC eq "gcc";
687         $__CNF_CPPFLAGS .= " -D__i386__";
688         return "unixware-7";
689     }
690     if ( $GUESSOS =~ '.*-.*-[Uu]nix[Ww]are20*' ) {
691         $options .= " no-sse2 no-sha512";
692         return "unixware-2.0";
693     }
694     if ( $GUESSOS =~ '.*-.*-[Uu]nix[Ww]are21*' ) {
695         $options .= " no-sse2 no-sha512";
696         return "unixware-2.1";
697     }
698     if ( $GUESSOS =~ '.*-.*-vos' ) {
699         $options .= " no-threads no-shared no-asm no-dso";
700         return "vos-$CC";
701     }
702     return "BS2000-OSD" if $GUESSOS =~ 'BS2000-siemens-sysv4';
703     return "Cygwin-x86" if $GUESSOS =~ 'i[3456]86-.*-cygwin';
704     return "Cygwin-${MACHINE}" if $GUESSOS =~ '.*-.*-cygwin';
705     return "android-x86" if $GUESSOS =~ 'x86-.*-android|i.86-.*-android';
706     if ( $GUESSOS =~ 'armv[7-9].*-.*-android' ) {
707         $__CNF_CFLAGS .= " -march=armv7-a";
708         $__CNF_CXXFLAGS .= " -march=armv7-a";
709         return "android-armeabi";
710     }
711     return "android-armeabi" if $GUESSOS =~ 'arm.*-.*-android';
712     if ( $GUESSOS =~ '.*-hpux1.*' ) {
713         $OUT = "hpux64-parisc2-gcc" if $CC = "gcc" && $GCC_BITS eq '64';
714         $KERNEL_BITS //= `getconf KERNEL_BITS 2>/dev/null` // '32';
715         # See <sys/unistd.h> for further info on CPU_VERSION.
716         my $CPU_VERSION = `getconf CPU_VERSION 2>/dev/null` // 0;
717         $__CNF_CPPFLAGS .= " -D_REENTRANT";
718         if ( $CPU_VERSION >= 768 ) {
719             # IA-64 CPU
720             return "hpux64-ia64-cc" if $KERNEL_BITS eq '64' && $CC eq "cc";
721             return "hpux-ia64-cc"
722         }
723         if ( $CPU_VERSION >= 532 ) {
724             # PA-RISC 2.x CPU
725             # PA-RISC 2.0 is no longer supported as separate 32-bit
726             # target. This is compensated for by run-time detection
727             # in most critical assembly modules and taking advantage
728             # of 2.0 architecture in PA-RISC 1.1 build.
729             $OUT //= "hpux-parisc1_1-${CC}";
730             if ( $KERNEL_BITS eq '64' && $CC eq "cc" ) {
731                 print <<EOF;
732 WARNING! To build 64-bit package, do this:
733          $WHERE/Configure hpux64-parisc2-cc
734 EOF
735                 maybe_abort();
736             }
737             return $OUT;
738         }
739         # PA-RISC 1.1+ CPU?
740         return "hpux-parisc1_1-${CC}" if $CPU_VERSION >= 528;
741         # PA-RISC 1.0 CPU
742         return "hpux-parisc-${CC}" if $CPU_VERSION >= 523;
743         # Motorola(?) CPU
744         return "hpux-$CC";
745         return $OUT;
746     }
747     return "hpux-parisc-$CC" if $GUESSOS =~ '.*-hpux';
748     if ( $GUESSOS =~ '.*-aix' ) {
749         $KERNEL_BITS //= `getconf KERNEL_BITMODE 2>/dev/null`;
750         $KERNEL_BITS //= '32';
751         my $OBJECT_MODE //= 32;
752         if ( $CC eq "gcc" ) {
753             $OUT = "aix-gcc";
754             if ( $OBJECT_MODE == 64 ) {
755                 print 'Your $OBJECT_MODE was found to be set to 64';
756                 $OUT = "aix64-gcc"
757             }
758         } elsif ( $OBJECT_MODE == 64 ) {
759             print 'Your $OBJECT_MODE was found to be set to 64';
760             $OUT = "aix64-cc";
761         } else {
762             $OUT = "aix-cc";
763             if ( $KERNEL_BITS eq '64' ) {
764                 print <<EOF;
765 WARNING! To build 64-bit package, do this:
766          $WHERE/Configure aix64-cc
767 EOF
768                 maybe_abort();
769             }
770         }
771         if ( okrun(
772                 "lsattr -E -O -l `lsdev -c processor|awk '{print \$1;exit}'`",
773                 'grep -i powerpc) >/dev/null 2>&1') ) {
774             # this applies even to Power3 and later, as they return
775             # PowerPC_POWER[345]
776         } else {
777             $options .= " no-asm";
778         }
779         return $OUT;
780     }
781
782     # Last case, return "z" from x-y-z
783     my @fields = split(/-/, $GUESSOS);
784     return $fields[2];
785 }
786
787 # gcc < 2.8 does not support -march=ultrasparc
788 sub check_solaris_sparc8 {
789     my $OUT = shift;
790     if ( $OUT eq 'solaris-sparcv9-gcc' && $GCCVER < 28 ) {
791         print <<EOF;
792 WARNING! Downgrading to solaris-sparcv8-gcc
793          Upgrade to gcc-2.8 or later.
794 EOF
795       maybe_abort();
796       return 'solaris-sparcv8-gcc';
797     }
798     if ( $OUT eq "linux-sparcv9" && $GCCVER < 28 ) {
799       print <<EOF;
800 WARNING! Downgrading to linux-sparcv8
801          Upgrade to gcc-2.8 or later.
802 EOF
803       maybe_abort();
804       return 'linux-sparcv8';
805     }
806     return $OUT;
807 }
808
809 # Append $CC to the target if that's in the Config list.
810 sub check_target_exists {
811     my $OUT = shift;
812     my %table;
813
814     open T, "$PERL $WHERE/Configure LIST|" or die "Can't get LIST, $!";
815     while ( <T> ) {
816         chop;
817         $table{$_} = 1;
818     }
819     close T;
820     return "$OUT-$CC" if defined $table{"$OUT-$CC"};
821     return "$OUT" if defined $table{$OUT};
822     print "This system ($OUT) is not supported. See INSTALL for details.\n";
823     exit 1;
824 }
825
826
827 ###
828 ###   MAIN PROCESSING
829 ###
830
831 # Common part, does all the real work.
832 sub common {
833     my $showguess = shift;
834
835     get_machine_etc();
836     my $GUESSOS = guess_system();
837     print "Operating system: $GUESSOS\n" if $VERBOSE || $showguess;
838     $options .= " 386" if $GUESSOS =~ /i386-/;
839     remove_removed_crypto_directories();
840     determine_compiler_settings();
841     my $TARGET = map_guess($GUESSOS) // $CC;
842     $TARGET = check_solaris_sparc8($TARGET);
843     $TARGET = check_target_exists($TARGET);
844     $options .= " $CONFIG_OPTIONS" if $CONFIG_OPTIONS ne '';
845     return $TARGET;
846 }
847
848 ##  If called from Configure
849 sub get_platform {
850     my $ref = shift;
851     my %options = %{$ref};
852     $VERBOSE = 1 if defined $options{verbose};
853     $options .= " --debug" if defined $options{debug};
854     $WAIT = 0 if defined $options{nowait};
855
856     my $TARGET = common(0);
857
858     # Populate the environment settings.
859     my %env;
860     $env{__CNF_CPPDEFINES} = $__CNF_CPPDEFINES;
861     $env{__CNF_CPPINCLUDES} = $__CNF_CPPINCLUDES;
862     $env{__CNF_CPPFLAGS} = $__CNF_CPPFLAGS;
863     $env{__CNF_CFLAGS} = $__CNF_CFLAGS;
864     $env{__CNF_CXXFLAGS} = $__CNF_CXXFLAGS;
865
866     # Prepare results and return them
867     my %ret = {
868         'target' => $TARGET,
869         'options' => $options,
870         'envvars' => %env,
871     };
872     return %ret;
873 }
874
875
876 # If running tandlone (via the "config" shell script)
877 sub main {
878     call_getopt();
879
880     my $TARGET = common(1);
881
882     if ( $VERBOSE ) {
883         print <<EOF;
884
885 export __CNF_CPPDEFINES="$__CNF_CPPDEFINES"
886 export __CNF_CPPINCLUDES="$__CNF_CPPINCLUDES"
887 export __CNF_CPPFLAGS="$__CNF_CPPFLAGS"
888 export __CNF_CFLAGS="$__CNF_CFLAGS"
889 export __CNF_CXXFLAGS="$__CNF_CXXFLAGS"
890 export __CNF_LDFLAGS="$__CNF_LDFLAGS"
891 export __CNF_LDLIBS="$__CNF_LDLIBS"
892 $PERL $WHERE/Configure $TARGET $options
893 EOF
894     }
895
896     return if $DRYRUN;
897
898     print "\n";
899     $ENV{__CNF_CPPDEFINES} = $__CNF_CPPDEFINES;
900     $ENV{__CNF_CPPINCLUDES} = $__CNF_CPPINCLUDES;
901     $ENV{__CNF_CPPFLAGS} = $__CNF_CPPFLAGS;
902     $ENV{__CNF_CFLAGS} = $__CNF_CFLAGS;
903     $ENV{__CNF_CXXFLAGS} = $__CNF_CXXFLAGS;
904     $ENV{__CNF_LDFLAGS} = $__CNF_LDFLAGS;
905     $ENV{__CNF_LDLIBS} = $__CNF_LDLIBS;
906     exit 1 if ! okrun("$PERL $WHERE/Configure $TARGET $options");
907 }
908
909 1;