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