Fix a merge error
[openssl.git] / Configure
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3 # Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
4 #
5 # Licensed under the OpenSSL license (the "License").  You may not use
6 # this file except in compliance with the License.  You can obtain a copy
7 # in the file LICENSE in the source distribution or at
8 # https://www.openssl.org/source/license.html
9
10 ##  Configure -- OpenSSL source tree configuration script
11
12 require 5.10.0;
13 use strict;
14 use Config;
15 use File::Basename;
16 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
17 use File::Path qw/mkpath/;
18 use if $^O ne "VMS", 'File::Glob' => qw/glob/;
19
20 # see INSTALL for instructions.
21
22 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
23
24 # Options:
25 #
26 # --config      add the given configuration file, which will be read after
27 #               any "Configurations*" files that are found in the same
28 #               directory as this script.
29 # --prefix      prefix for the OpenSSL installation, which includes the
30 #               directories bin, lib, include, share/man, share/doc/openssl
31 #               This becomes the value of INSTALLTOP in Makefile
32 #               (Default: /usr/local)
33 # --openssldir  OpenSSL data area, such as openssl.cnf, certificates and keys.
34 #               If it's a relative directory, it will be added on the directory
35 #               given with --prefix.
36 #               This becomes the value of OPENSSLDIR in Makefile and in C.
37 #               (Default: PREFIX/ssl)
38 #
39 # --cross-compile-prefix Add specified prefix to binutils components.
40 #
41 # --api         One of 0.9.8, 1.0.0 or 1.1.0.  Do not compile support for
42 #               interfaces deprecated as of the specified OpenSSL version.
43 #
44 # no-hw-xxx     do not compile support for specific crypto hardware.
45 #               Generic OpenSSL-style methods relating to this support
46 #               are always compiled but return NULL if the hardware
47 #               support isn't compiled.
48 # no-hw         do not compile support for any crypto hardware.
49 # [no-]threads  [don't] try to create a library that is suitable for
50 #               multithreaded applications (default is "threads" if we
51 #               know how to do it)
52 # [no-]shared   [don't] try to create shared libraries when supported.
53 # [no-]pic      [don't] try to build position independent code when supported.
54 #               If disabled, it also disables shared and dynamic-engine.
55 # no-asm        do not use assembler
56 # no-dso        do not compile in any native shared-library methods. This
57 #               will ensure that all methods just return NULL.
58 # no-egd        do not compile support for the entropy-gathering daemon APIs
59 # [no-]zlib     [don't] compile support for zlib compression.
60 # zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
61 #               library and will be loaded in run-time by the OpenSSL library.
62 # sctp          include SCTP support
63 # enable-weak-ssl-ciphers
64 #               Enable weak ciphers that are disabled by default. This currently
65 #               only includes RC4 based ciphers.
66 # 386           generate 80386 code in assembly modules
67 # no-sse2       disables IA-32 SSE2 code in assembly modules, the above
68 #               mentioned '386' option implies this one
69 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
70 # -<xxx> +<xxx> compiler options are passed through
71 # -static       while -static is also a pass-through compiler option (and
72 #               as such is limited to environments where it's actually
73 #               meaningful), it triggers a number configuration options,
74 #               namely no-dso, no-pic, no-shared and no-threads. It is
75 #               argued that the only reason to produce statically linked
76 #               binaries (and in context it means executables linked with
77 #               -static flag, and not just executables linked with static
78 #               libcrypto.a) is to eliminate dependency on specific run-time,
79 #               a.k.a. libc version. The mentioned config options are meant
80 #               to achieve just that. Unfortunately on Linux it's impossible
81 #               to eliminate the dependency completely for openssl executable
82 #               because of getaddrinfo and gethostbyname calls, which can
83 #               invoke dynamically loadable library facility anyway to meet
84 #               the lookup requests. For this reason on Linux statically
85 #               linked openssl executable has rather debugging value than
86 #               production quality.
87 #
88 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
89 #               provided to stack calls. Generates unique stack functions for
90 #               each possible stack type.
91 # BN_LLONG      use the type 'long long' in crypto/bn/bn.h
92 # RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
93 # Following are set automatically by this script
94 #
95 # MD5_ASM       use some extra md5 assembler,
96 # SHA1_ASM      use some extra sha1 assembler, must define L_ENDIAN for x86
97 # RMD160_ASM    use some extra ripemd160 assembler,
98 # SHA256_ASM    sha256_block is implemented in assembler
99 # SHA512_ASM    sha512_block is implemented in assembler
100 # AES_ASM       AES_[en|de]crypt is implemented in assembler
101
102 # Minimum warning options... any contributions to OpenSSL should at least get
103 # past these.
104
105 # DEBUG_UNUSED enables __owur (warn unused result) checks.
106 # -DPEDANTIC complements -pedantic and is meant to mask code that
107 # is not strictly standard-compliant and/or implementation-specific,
108 # e.g. inline assembly, disregards to alignment requirements, such
109 # that -pedantic would complain about. Incidentally -DPEDANTIC has
110 # to be used even in sanitized builds, because sanitizer too is
111 # supposed to and does take notice of non-standard behaviour. Then
112 # -pedantic with pre-C9x compiler would also complain about 'long
113 # long' not being supported. As 64-bit algorithms are common now,
114 # it grew impossible to resolve this without sizeable additional
115 # code, so we just tell compiler to be pedantic about everything
116 # but 'long long' type.
117
118 my $gcc_devteam_warn = "-DDEBUG_UNUSED"
119         . " -Wswitch"
120         . " -DPEDANTIC -pedantic -Wno-long-long"
121         . " -Wall"
122         . " -Wsign-compare"
123         . " -Wmissing-prototypes"
124         . " -Wshadow"
125         . " -Wformat"
126         . " -Wtype-limits"
127         . " -Wno-parentheses-equality"
128         . " -Werror"
129         ;
130
131 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
132 # TODO(openssl-team): fix problems and investigate if (at least) the
133 # following warnings can also be enabled:
134 #       -Wcast-align
135 #       -Wunreachable-code -- no, too ugly/compiler-specific
136 #       -Wlanguage-extension-token -- no, we use asm()
137 #       -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
138 #       -Wextended-offsetof -- no, needed in CMS ASN1 code
139 my $clang_devteam_warn = ""
140         . " -Qunused-arguments"
141         . " -Wextra"
142         . " -Wswitch -Wswitch-default"
143         . " -Wno-unused-parameter"
144         . " -Wno-parentheses-equality"
145         . " -Wno-missing-field-initializers"
146         . " -Wno-language-extension-token"
147         . " -Wno-extended-offsetof"
148         . " -Wconditional-uninitialized"
149         . " -Wincompatible-pointer-types-discards-qualifiers"
150         . " -Wmissing-variable-declarations"
151         ;
152
153 # This adds backtrace information to the memory leak info.  Is only used
154 # when crypto-mdebug-backtrace is enabled.
155 my $memleak_devteam_backtrace = "-rdynamic";
156
157 my $strict_warnings = 0;
158
159 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
160 # which would cover all BSD flavors. -pthread applies to them all,
161 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
162 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
163 # which has to be accompanied by explicit -D_THREAD_SAFE and
164 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
165 # seems to be sufficient?
166 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
167
168 #
169 # API compatibility name to version number mapping.
170 #
171 my $maxapi = "1.1.0";           # API for "no-deprecated" builds
172 my $apitable = {
173     "1.1.0" => "0x10100000L",
174     "1.0.0" => "0x10000000L",
175     "0.9.8" => "0x00908000L",
176 };
177
178 our %table = ();
179 our %config = ();
180 our %withargs = ();
181
182 # Forward declarations ###############################################
183
184 # read_config(filename)
185 #
186 # Reads a configuration file and populates %table with the contents
187 # (which the configuration file places in %targets).
188 sub read_config;
189
190 # resolve_config(target)
191 #
192 # Resolves all the late evaluations, inheritances and so on for the
193 # chosen target and any target it inherits from.
194 sub resolve_config;
195
196
197 # Information collection #############################################
198
199 # Unified build supports separate build dir
200 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
201 my $blddir = catdir(absolutedir("."));         # catdir ensures local syntax
202 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
203
204 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
205
206 $config{sourcedir} = abs2rel($srcdir);
207 $config{builddir} = abs2rel($blddir);
208
209 # Collect reconfiguration information if needed
210 my @argvcopy=@ARGV;
211
212 if (grep /^reconf(igure)?$/, @argvcopy) {
213     if (-f "./configdata.pm") {
214         my $file = "./configdata.pm";
215         unless (my $return = do $file) {
216             die "couldn't parse $file: $@" if $@;
217             die "couldn't do $file: $!"    unless defined $return;
218             die "couldn't run $file"       unless $return;
219         }
220
221         @argvcopy = defined($configdata::config{perlargv}) ?
222             @{$configdata::config{perlargv}} : ();
223         die "Incorrect data to reconfigure, please do a normal configuration\n"
224             if (grep(/^reconf/,@argvcopy));
225         $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
226             if defined($configdata::config{cross_compile_prefix});
227         $ENV{CC} = $configdata::config{cc}
228             if defined($configdata::config{cc});
229         $ENV{CXX} = $configdata::config{cxx}
230             if defined($configdata::config{cxx});
231         $ENV{BUILDFILE} = $configdata::config{build_file}
232             if defined($configdata::config{build_file});
233         $ENV{$local_config_envname} = $configdata::config{local_config_dir}
234             if defined($configdata::config{local_config_dir});
235
236         print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
237         print "    CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
238             if $ENV{CROSS_COMPILE};
239         print "    CC = ",$ENV{CC},"\n" if $ENV{CC};
240         print "    CXX = ",$ENV{CXX},"\n" if $ENV{CXX};
241         print "    BUILDFILE = ",$ENV{BUILDFILE},"\n" if $ENV{BUILDFILE};
242         print "    $local_config_envname = ",$ENV{$local_config_envname},"\n"
243             if $ENV{$local_config_envname};
244     } else {
245         die "Insufficient data to reconfigure, please do a normal configuration\n";
246     }
247 }
248
249 $config{perlargv} = [ @argvcopy ];
250
251 # Collect version numbers
252 $config{version} = "unknown";
253 $config{version_num} = "unknown";
254 $config{shlib_version_number} = "unknown";
255 $config{shlib_version_history} = "unknown";
256
257 collect_information(
258     collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
259     qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
260     qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/      => sub { $config{version_num}=$1 },
261     qr/SHLIB_VERSION_NUMBER *"([^"]+)"/      => sub { $config{shlib_version_number}=$1 },
262     qr/SHLIB_VERSION_HISTORY *"([^"]*)"/     => sub { $config{shlib_version_history}=$1 }
263     );
264 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
265
266 ($config{major}, $config{minor})
267     = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
268 ($config{shlib_major}, $config{shlib_minor})
269     = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
270 die "erroneous version information in opensslv.h: ",
271     "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
272     if ($config{major} eq "" || $config{minor} eq ""
273         || $config{shlib_major} eq "" ||  $config{shlib_minor} eq "");
274
275 # Collect target configurations
276
277 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
278 foreach (sort glob($pattern)) {
279     &read_config($_);
280 }
281
282 if (defined $ENV{$local_config_envname}) {
283     if ($^O eq 'VMS') {
284         # VMS environment variables are logical names,
285         # which can be used as is
286         $pattern = $local_config_envname . ':' . '*.conf';
287     } else {
288         $pattern = catfile($ENV{$local_config_envname}, '*.conf');
289     }
290
291     foreach (sort glob($pattern)) {
292         &read_config($_);
293     }
294 }
295
296
297 print "Configuring OpenSSL version $config{version} ($config{version_num})\n";
298
299 $config{prefix}="";
300 $config{openssldir}="";
301 $config{processor}="";
302 $config{libdir}="";
303 $config{cross_compile_prefix}="";
304 $config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
305 my $nofipscanistercheck=0;
306 $config{baseaddr}="0xFB00000";
307 my $auto_threads=1;    # enable threads automatically? true by default
308 my $default_ranlib;
309 $config{fips}=0;
310
311 # Top level directories to build
312 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
313 # crypto/ subdirectories to build
314 $config{sdirs} = [
315     "objects",
316     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash",
317     "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes",
318     "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
319     "buffer", "bio", "stack", "lhash", "rand", "err",
320     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
321     "cms", "ts", "srp", "cmac", "ct", "async", "kdf"
322     ];
323 # test/ subdirectories to build
324 $config{tdirs} = [ "ossl_shim" ];
325
326 # Known TLS and DTLS protocols
327 my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
328 my @dtls = qw(dtls1 dtls1_2);
329
330 # Explicitly known options that are possible to disable.  They can
331 # be regexps, and will be used like this: /^no-${option}$/
332 # For developers: keep it sorted alphabetically
333
334 my @disablables = (
335     "afalgeng",
336     "asan",
337     "asm",
338     "async",
339     "autoalginit",
340     "autoerrinit",
341     "bf",
342     "blake2",
343     "camellia",
344     "capieng",
345     "cast",
346     "chacha",
347     "cmac",
348     "cms",
349     "comp",
350     "crypto-mdebug",
351     "crypto-mdebug-backtrace",
352     "ct",
353     "deprecated",
354     "des",
355     "dgram",
356     "dh",
357     "dsa",
358     "dso",
359     "dtls",
360     "dynamic-engine",
361     "ec",
362     "ec2m",
363     "ecdh",
364     "ecdsa",
365     "ec_nistp_64_gcc_128",
366     "egd",
367     "engine",
368     "err",
369     "external-tests",
370     "filenames",
371     "fuzz-libfuzzer",
372     "fuzz-afl",
373     "gost",
374     "heartbeats",
375     "hw(-.+)?",
376     "idea",
377     "makedepend",
378     "md2",
379     "md4",
380     "mdc2",
381     "msan",
382     "multiblock",
383     "nextprotoneg",
384     "ocb",
385     "ocsp",
386     "pic",
387     "poly1305",
388     "posix-io",
389     "psk",
390     "rc2",
391     "rc4",
392     "rc5",
393     "rdrand",
394     "rfc3779",
395     "rmd160",
396     "scrypt",
397     "sctp",
398     "seed",
399     "shared",
400     "siphash",
401     "sock",
402     "srp",
403     "srtp",
404     "sse2",
405     "ssl",
406     "ssl-trace",
407     "static-engine",
408     "stdio",
409     "tests",
410     "threads",
411     "tls",
412     "ts",
413     "ubsan",
414     "ui",
415     "unit-test",
416     "whirlpool",
417     "weak-ssl-ciphers",
418     "zlib",
419     "zlib-dynamic",
420     );
421 foreach my $proto ((@tls, @dtls))
422         {
423         push(@disablables, $proto);
424         push(@disablables, "$proto-method");
425         }
426
427 my %deprecated_disablables = (
428     "ssl2" => undef,
429     "buf-freelists" => undef,
430     "ripemd" => "rmd160"
431     );
432
433 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
434
435 our %disabled = ( # "what"         => "comment"
436                   "asan"                => "default",
437                   "crypto-mdebug"       => "default",
438                   "crypto-mdebug-backtrace" => "default",
439                   "ec_nistp_64_gcc_128" => "default",
440                   "egd"                 => "default",
441                   "external-tests"      => "default",
442                   "fuzz-libfuzzer"      => "default",
443                   "fuzz-afl"            => "default",
444                   "heartbeats"          => "default",
445                   "md2"                 => "default",
446                   "msan"                => "default",
447                   "rc5"                 => "default",
448                   "sctp"                => "default",
449                   "ssl-trace"           => "default",
450                   "ssl3"                => "default",
451                   "ssl3-method"         => "default",
452                   "ubsan"               => "default",
453           #TODO(TLS1.3): Temporarily disabled while this is a WIP
454                   "tls1_3"              => "default",
455                   "unit-test"           => "default",
456                   "weak-ssl-ciphers"    => "default",
457                   "zlib"                => "default",
458                   "zlib-dynamic"        => "default",
459                 );
460
461 # Note: => pair form used for aesthetics, not to truly make a hash table
462 my @disable_cascades = (
463     # "what"            => [ "cascade", ... ]
464     sub { $config{processor} eq "386" }
465                         => [ "sse2" ],
466     "ssl"               => [ "ssl3" ],
467     "ssl3-method"       => [ "ssl3" ],
468     "zlib"              => [ "zlib-dynamic" ],
469     "des"               => [ "mdc2" ],
470     "ec"                => [ "ecdsa", "ecdh" ],
471
472     "dgram"             => [ "dtls", "sctp" ],
473     "sock"              => [ "dgram" ],
474     "dtls"              => [ @dtls ],
475
476     # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
477     "md5"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
478     "sha"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
479
480     # Additionally, SSL 3.0 requires either RSA or DSA+DH
481     sub { $disabled{rsa}
482           && ($disabled{dsa} || $disabled{dh}); }
483                         => [ "ssl" ],
484
485     # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
486     # or ECDSA + ECDH.  (D)TLS 1.2 has this requirement as well.
487     # (XXX: We don't support PSK-only builds).
488     sub { $disabled{rsa}
489           && ($disabled{dsa} || $disabled{dh})
490           && ($disabled{ecdsa} || $disabled{ecdh}); }
491                         => [ "tls1", "tls1_1", "tls1_2", "tls1_3",
492                              "dtls1", "dtls1_2" ],
493
494     "tls"               => [ @tls ],
495
496     # SRP and HEARTBEATS require TLSEXT
497     "tlsext"            => [ "srp", "heartbeats" ],
498
499     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
500
501     # Without DSO, we can't load dynamic engines, so don't build them dynamic
502     "dso"               => [ "dynamic-engine" ],
503
504     # Without position independent code, there can be no shared libraries or DSOs
505     "pic"               => [ "shared" ],
506     "shared"            => [ "dynamic-engine" ],
507     "engine"            => [ "afalgeng" ],
508
509     # no-autoalginit is only useful when building non-shared
510     "autoalginit"       => [ "shared", "apps" ],
511
512     "stdio"             => [ "apps", "capieng" ],
513     "apps"              => [ "tests" ],
514     "comp"              => [ "zlib" ],
515     "ec"                => [ "tls1_3" ],
516     sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
517
518     sub { !$disabled{"msan"} } => [ "asm" ],
519     );
520
521 # Avoid protocol support holes.  Also disable all versions below N, if version
522 # N is disabled while N+1 is enabled.
523 #
524 my @list = (reverse @tls);
525 while ((my $first, my $second) = (shift @list, shift @list)) {
526     last unless @list;
527     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
528                               => [ @list ] );
529     unshift @list, $second;
530 }
531 my @list = (reverse @dtls);
532 while ((my $first, my $second) = (shift @list, shift @list)) {
533     last unless @list;
534     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
535                               => [ @list ] );
536     unshift @list, $second;
537 }
538
539 # Explicit "no-..." options will be collected in %disabled along with the defaults.
540 # To remove something from %disabled, use "enable-foo".
541 # For symmetry, "disable-foo" is a synonym for "no-foo".
542
543 my $no_sse2=0;
544
545 &usage if ($#ARGV < 0);
546
547 my $user_cflags="";
548 my @user_defines=();
549 $config{openssl_api_defines}=[];
550 $config{openssl_algorithm_defines}=[];
551 $config{openssl_thread_defines}=[];
552 $config{openssl_sys_defines}=[];
553 $config{openssl_other_defines}=[];
554 my $libs="";
555 my $target="";
556 $config{options}="";
557 $config{build_type} = "release";
558
559 my %unsupported_options = ();
560 my %deprecated_options = ();
561 while (@argvcopy)
562         {
563         $_ = shift @argvcopy;
564         # VMS is a case insensitive environment, and depending on settings
565         # out of our control, we may receive options uppercased.  Let's
566         # downcase at least the part before any equal sign.
567         if ($^O eq "VMS")
568                 {
569                 s/^([^=]*)/lc($1)/e;
570                 }
571         s /^-no-/no-/; # some people just can't read the instructions
572
573         # rewrite some options in "enable-..." form
574         s /^-?-?shared$/enable-shared/;
575         s /^sctp$/enable-sctp/;
576         s /^threads$/enable-threads/;
577         s /^zlib$/enable-zlib/;
578         s /^zlib-dynamic$/enable-zlib-dynamic/;
579
580         if (/^(no|disable|enable)-(.+)$/)
581                 {
582                 my $word = $2;
583                 if (!exists $deprecated_disablables{$word}
584                         && !grep { $word =~ /^${_}$/ } @disablables)
585                         {
586                         $unsupported_options{$_} = 1;
587                         next;
588                         }
589                 }
590         if (/^no-(.+)$/ || /^disable-(.+)$/)
591                 {
592                 foreach my $proto ((@tls, @dtls))
593                         {
594                         if ($1 eq "$proto-method")
595                                 {
596                                 $disabled{"$proto"} = "option($proto-method)";
597                                 last;
598                                 }
599                         }
600                 if ($1 eq "dtls")
601                         {
602                         foreach my $proto (@dtls)
603                                 {
604                                 $disabled{$proto} = "option(dtls)";
605                                 }
606                         $disabled{"dtls"} = "option(dtls)";
607                         }
608                 elsif ($1 eq "ssl")
609                         {
610                         # Last one of its kind
611                         $disabled{"ssl3"} = "option(ssl)";
612                         }
613                 elsif ($1 eq "tls")
614                         {
615                         # XXX: Tests will fail if all SSL/TLS
616                         # protocols are disabled.
617                         foreach my $proto (@tls)
618                                 {
619                                 $disabled{$proto} = "option(tls)";
620                                 }
621                         }
622                 elsif ($1 eq "static-engine")
623                         {
624                         delete $disabled{"dynamic-engine"};
625                         }
626                 elsif ($1 eq "dynamic-engine")
627                         {
628                         $disabled{"dynamic-engine"} = "option";
629                         }
630                 elsif (exists $deprecated_disablables{$1})
631                         {
632                         $deprecated_options{$_} = 1;
633                         if (defined $deprecated_disablables{$1})
634                                 {
635                                 $disabled{$deprecated_disablables{$1}} = "option";
636                                 }
637                         }
638                 else
639                         {
640                         $disabled{$1} = "option";
641                         }
642                 # No longer an automatic choice
643                 $auto_threads = 0 if ($1 eq "threads");
644                 }
645         elsif (/^enable-(.+)$/)
646                 {
647                 if ($1 eq "static-engine")
648                         {
649                         $disabled{"dynamic-engine"} = "option";
650                         }
651                 elsif ($1 eq "dynamic-engine")
652                         {
653                         delete $disabled{"dynamic-engine"};
654                         }
655                 elsif ($1 eq "zlib-dynamic")
656                         {
657                         delete $disabled{"zlib"};
658                         }
659                 my $algo = $1;
660                 delete $disabled{$algo};
661
662                 # No longer an automatic choice
663                 $auto_threads = 0 if ($1 eq "threads");
664                 }
665         elsif (/^--strict-warnings$/)
666                 {
667                 $strict_warnings = 1;
668                 }
669         elsif (/^--debug$/)
670                 {
671                 $config{build_type} = "debug";
672                 }
673         elsif (/^--release$/)
674                 {
675                 $config{build_type} = "release";
676                 }
677         elsif (/^386$/)
678                 { $config{processor}=386; }
679         elsif (/^fips$/)
680                 {
681                 $config{fips}=1;
682                 }
683         elsif (/^rsaref$/)
684                 {
685                 # No RSAref support any more since it's not needed.
686                 # The check for the option is there so scripts aren't
687                 # broken
688                 }
689         elsif (/^nofipscanistercheck$/)
690                 {
691                 $config{fips} = 1;
692                 $nofipscanistercheck = 1;
693                 }
694         elsif (/^[-+]/)
695                 {
696                 if (/^--prefix=(.*)$/)
697                         {
698                         $config{prefix}=$1;
699                         die "Directory given with --prefix MUST be absolute\n"
700                                 unless file_name_is_absolute($config{prefix});
701                         }
702                 elsif (/^--api=(.*)$/)
703                         {
704                         $config{api}=$1;
705                         }
706                 elsif (/^--libdir=(.*)$/)
707                         {
708                         $config{libdir}=$1;
709                         }
710                 elsif (/^--openssldir=(.*)$/)
711                         {
712                         $config{openssldir}=$1;
713                         }
714                 elsif (/^--with-zlib-lib=(.*)$/)
715                         {
716                         $withargs{zlib_lib}=$1;
717                         }
718                 elsif (/^--with-zlib-include=(.*)$/)
719                         {
720                         $withargs{zlib_include}=$1;
721                         }
722                 elsif (/^--with-fuzzer-lib=(.*)$/)
723                         {
724                         $withargs{fuzzer_lib}=$1;
725                         }
726                 elsif (/^--with-fuzzer-include=(.*)$/)
727                         {
728                         $withargs{fuzzer_include}=$1;
729                         }
730                 elsif (/^--with-fipslibdir=(.*)$/)
731                         {
732                         $config{fipslibdir}="$1/";
733                         }
734                 elsif (/^--with-baseaddr=(.*)$/)
735                         {
736                         $config{baseaddr}="$1";
737                         }
738                 elsif (/^--cross-compile-prefix=(.*)$/)
739                         {
740                         $config{cross_compile_prefix}=$1;
741                         }
742                 elsif (/^--config=(.*)$/)
743                         {
744                         read_config $1;
745                         }
746                 elsif (/^-[lL](.*)$/ or /^-Wl,/)
747                         {
748                         $libs.=$_." ";
749                         }
750                 elsif (/^-rpath$/ or /^-R$/)
751                         # -rpath is the OSF1 rpath flag
752                         # -R is the old Solaris rpath flag
753                         {
754                         my $rpath = shift(@argvcopy) || "";
755                         $rpath .= " " if $rpath ne "";
756                         $libs.=$_." ".$rpath;
757                         }
758                 elsif (/^-static$/)
759                         {
760                         $libs.=$_." ";
761                         $disabled{"dso"} = "forced";
762                         $disabled{"pic"} = "forced";
763                         $disabled{"shared"} = "forced";
764                         $disabled{"threads"} = "forced";
765                         }
766                 elsif (/^-D(.*)$/)
767                         {
768                         push @user_defines, $1;
769                         }
770                 else    # common if (/^[-+]/), just pass down...
771                         {
772                         $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
773                         $user_cflags.=" ".$_;
774                         }
775                 }
776         else
777                 {
778                 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
779                 $target=$_;
780                 }
781         unless ($_ eq $target || /^no-/ || /^disable-/)
782                 {
783                 # "no-..." follows later after implied disactivations
784                 # have been derived.  (Don't take this too seriously,
785                 # we really only write OPTIONS to the Makefile out of
786                 # nostalgia.)
787
788                 if ($config{options} eq "")
789                         { $config{options} = $_; }
790                 else
791                         { $config{options} .= " ".$_; }
792                 }
793
794         if (defined($config{api}) && !exists $apitable->{$config{api}}) {
795                 die "***** Unsupported api compatibility level: $config{api}\n",
796         }
797
798         if (keys %deprecated_options)
799                 {
800                 warn "***** Deprecated options: ",
801                         join(", ", keys %deprecated_options), "\n";
802                 }
803         if (keys %unsupported_options)
804                 {
805                 die "***** Unsupported options: ",
806                         join(", ", keys %unsupported_options), "\n";
807                 }
808         }
809
810 if ($libs =~ /(^|\s)-Wl,-rpath,/
811     && !$disabled{shared}
812     && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
813     die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
814         "***** any of asan, msan or ubsan\n";
815 }
816
817 if ($config{fips})
818         {
819         delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/);
820         }
821 else
822         {
823         @{$config{dirs}} = grep !/^fips$/, @{$config{dirs}};
824         }
825
826 my @tocheckfor = (keys %disabled);
827 while (@tocheckfor) {
828     my %new_tocheckfor = ();
829     my @cascade_copy = (@disable_cascades);
830     while (@cascade_copy) {
831         my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
832         if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
833             foreach(grep { !defined($disabled{$_}) } @$descendents) {
834                 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
835             }
836         }
837     }
838     @tocheckfor = (keys %new_tocheckfor);
839 }
840
841 our $die = sub { die @_; };
842 if ($target eq "TABLE") {
843     local $die = sub { warn @_; };
844     foreach (sort keys %table) {
845         print_table_entry($_, "TABLE");
846     }
847     exit 0;
848 }
849
850 if ($target eq "LIST") {
851     foreach (sort keys %table) {
852         print $_,"\n" unless $table{$_}->{template};
853     }
854     exit 0;
855 }
856
857 if ($target eq "HASH") {
858     local $die = sub { warn @_; };
859     print "%table = (\n";
860     foreach (sort keys %table) {
861         print_table_entry($_, "HASH");
862     }
863     exit 0;
864 }
865
866 # Backward compatibility?
867 if ($target =~ m/^CygWin32(-.*)$/) {
868     $target = "Cygwin".$1;
869 }
870
871 foreach (sort (keys %disabled))
872         {
873         $config{options} .= " no-$_";
874
875         printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
876
877         if (/^dso$/)
878                 { }
879         elsif (/^threads$/)
880                 { }
881         elsif (/^shared$/)
882                 { }
883         elsif (/^pic$/)
884                 { }
885         elsif (/^zlib$/)
886                 { }
887         elsif (/^dynamic-engine$/)
888                 { }
889         elsif (/^makedepend$/)
890                 { }
891         elsif (/^zlib-dynamic$/)
892                 { }
893         elsif (/^sse2$/)
894                 { $no_sse2 = 1; }
895         elsif (/^engine$/)
896                 {
897                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
898                 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
899                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
900                 print " OPENSSL_NO_ENGINE (skip engines)";
901                 }
902         else
903                 {
904                 my ($WHAT, $what);
905
906                 ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/;
907
908                 # Fix up C macro end names
909                 $WHAT = "RMD160" if $what eq "ripemd";
910
911                 # fix-up crypto/directory name(s)
912                 $what = "ripemd" if $what eq "rmd160";
913                 $what = "whrlpool" if $what eq "whirlpool";
914
915                 if ($what ne "async" && $what ne "err"
916                     && grep { $_ eq $what } @{$config{sdirs}})
917                         {
918                         push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT";
919                         @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}};
920
921                         print " OPENSSL_NO_$WHAT (skip dir)";
922                         }
923                 else
924                         {
925                         push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
926                         print " OPENSSL_NO_$WHAT";
927
928                         if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
929                         }
930                 }
931
932         print "\n";
933         }
934
935 print "Configuring for $target\n";
936 # Support for legacy targets having a name starting with 'debug-'
937 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
938 if ($d) {
939     $config{build_type} = "debug";
940
941     # If we do not find debug-foo in the table, the target is set to foo.
942     if (!$table{$target}) {
943         $target = $t;
944     }
945 }
946 $config{target} = $target;
947 my %target = resolve_config($target);
948
949 &usage if (!%target || $target{template});
950
951 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
952 $config{conf_files} = [ sort keys %conf_files ];
953 %target = ( %{$table{DEFAULTS}}, %target );
954
955 $target{cxxflags}=$target{cflags} unless defined $target{cxxflags};
956 $target{exe_extension}="";
957 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
958                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
959 $target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
960
961 ($target{shared_extension_simple}=$target{shared_extension})
962     =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||;
963 $target{dso_extension}=$target{shared_extension_simple};
964 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
965     if ($config{target} =~ /^(?:Cygwin|mingw)/);
966
967
968 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
969     if $config{cross_compile_prefix} eq "";
970
971 # Allow overriding the names of some tools.  USE WITH CARE
972 # Note: only Unix cares about HASHBANGPERL...  that explains
973 # the default string.
974 $config{perl} =    ($^O ne "VMS" ? $^X : "perl");
975 $config{hashbangperl} =
976     $ENV{'HASHBANGPERL'}           || $ENV{'PERL'}     || "/usr/bin/env perl";
977 $target{cc} =      $ENV{'CC'}      || $target{cc}      || "cc";
978 $target{cxx} =     $ENV{'CXX'}     || $target{cxx}     || "c++";
979 $target{ranlib} =  $ENV{'RANLIB'}  || $target{ranlib}  ||
980                    (which("$config{cross_compile_prefix}ranlib") ?
981                           "\$(CROSS_COMPILE)ranlib" : "true");
982 $target{ar} =      $ENV{'AR'}      || $target{ar}      || "ar";
983 $target{nm} =      $ENV{'NM'}      || $target{nm}      || "nm";
984 $target{rc} =
985     $ENV{'RC'}  || $ENV{'WINDRES'} || $target{rc}      || "windres";
986
987 # Allow overriding the build file name
988 $target{build_file} = $ENV{BUILDFILE} || $target{build_file} || "Makefile";
989
990 # Cache information necessary for reconfiguration
991 $config{cc} = $target{cc};
992 $config{cxx} = $target{cxx};
993 $config{build_file} = $target{build_file};
994
995 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
996 # or release_ attributes.
997 # Do it in such a way that no spurious space is appended (hence the grep).
998 $config{defines} = [];
999 $config{cflags} = "";
1000 $config{cxxflags} = "";
1001 $config{ex_libs} = "";
1002 $config{shared_ldflag} = "";
1003
1004 # Make sure build_scheme is consistent.
1005 $target{build_scheme} = [ $target{build_scheme} ]
1006     if ref($target{build_scheme}) ne "ARRAY";
1007
1008 my ($builder, $builder_platform, @builder_opts) =
1009     @{$target{build_scheme}};
1010
1011 push @{$config{defines}}, "NDEBUG"    if $config{build_type} eq "release";
1012
1013 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
1014         {
1015         $config{cflags} .= " -mno-cygwin";
1016         $config{shared_ldflag} .= " -mno-cygwin";
1017         }
1018
1019 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
1020         # minimally required architecture flags for assembly modules
1021         $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
1022         $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
1023 }
1024
1025 my $no_shared_warn=0;
1026 my $no_user_cflags=0;
1027 my $no_user_defines=0;
1028
1029 # The DSO code currently always implements all functions so that no
1030 # applications will have to worry about that from a compilation point
1031 # of view. However, the "method"s may return zero unless that platform
1032 # has support compiled in for them. Currently each method is enabled
1033 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
1034 # string entry into using the following logic;
1035 if (!$disabled{dso} && $target{dso_scheme} ne "")
1036         {
1037         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
1038         if ($target{dso_scheme} eq "DLFCN")
1039                 {
1040                 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
1041                 }
1042         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
1043                 {
1044                 unshift @{$config{defines}}, "DSO_DLFCN";
1045                 }
1046         else
1047                 {
1048                 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
1049                 }
1050         }
1051
1052 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
1053
1054 if ($disabled{asm})
1055         {
1056         if ($config{fips})
1057                 {
1058                 @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}};
1059                 @{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}};
1060                 }
1061         }
1062
1063 # If threads aren't disabled, check how possible they are
1064 unless ($disabled{threads}) {
1065     if ($auto_threads) {
1066         # Enabled by default, disable it forcibly if unavailable
1067         if ($target{thread_scheme} eq "(unknown)") {
1068             $disabled{threads} = "unavailable";
1069         }
1070     } else {
1071         # The user chose to enable threads explicitly, let's see
1072         # if there's a chance that's possible
1073         if ($target{thread_scheme} eq "(unknown)") {
1074             # If the user asked for "threads" and we don't have internal
1075             # knowledge how to do it, [s]he is expected to provide any
1076             # system-dependent compiler options that are necessary.  We
1077             # can't truly check that the given options are correct, but
1078             # we expect the user to know what [s]He is doing.
1079             if ($no_user_cflags && $no_user_defines) {
1080                 die "You asked for multi-threading support, but didn't\n"
1081                     ,"provide any system-specific compiler options\n";
1082             }
1083         }
1084     }
1085 }
1086
1087 # If threads still aren't disabled, add a C macro to ensure the source
1088 # code knows about it.  Any other flag is taken care of by the configs.
1089 unless($disabled{threads}) {
1090     foreach (("defines", "openssl_thread_defines")) {
1091         push @{$config{$_}}, "OPENSSL_THREADS";
1092     }
1093 }
1094
1095 # With "deprecated" disable all deprecated features.
1096 if (defined($disabled{"deprecated"})) {
1097         $config{api} = $maxapi;
1098 }
1099
1100 if ($target{shared_target} eq "")
1101         {
1102         $no_shared_warn = 1
1103             if ((!$disabled{shared} || !$disabled{"dynamic-engine"})
1104                 && !$config{fips});
1105         $disabled{shared} = "no-shared-target";
1106         $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1107             "no-shared-target";
1108         }
1109
1110 if ($disabled{"dynamic-engine"}) {
1111         push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1112         $config{dynamic_engines} = 0;
1113 } else {
1114         push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1115         $config{dynamic_engines} = 1;
1116 }
1117
1118 unless ($disabled{asan}) {
1119     $config{cflags} .= "-fsanitize=address ";
1120 }
1121
1122 unless ($disabled{ubsan}) {
1123     # -DPEDANTIC or -fnosanitize=alignment may also be required on some
1124     # platforms.
1125     $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
1126 }
1127
1128 unless ($disabled{msan}) {
1129   $config{cflags} .= "-fsanitize=memory ";
1130 }
1131
1132 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1133         && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1134     $config{cflags} .= "-fno-omit-frame-pointer -g ";
1135 }
1136 #
1137 # Platform fix-ups
1138 #
1139
1140 # This saves the build files from having to check
1141 if ($disabled{pic})
1142         {
1143         $target{shared_cflag} = $target{shared_ldflag} =
1144                 $target{shared_rcflag} = "";
1145         }
1146 else
1147         {
1148         push @{$config{defines}}, "OPENSSL_PIC";
1149         }
1150
1151 if ($target{sys_id} ne "")
1152         {
1153         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1154         }
1155
1156 unless ($disabled{asm}) {
1157     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1158     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1159
1160     # bn-586 is the only one implementing bn_*_part_words
1161     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1162     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1163
1164     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1165     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1166     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1167
1168     if ($config{fips}) {
1169         push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
1170     }
1171
1172     if ($target{sha1_asm_src}) {
1173         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1174         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1175         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1176     }
1177     if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
1178         push @{$config{defines}}, "RC4_ASM";
1179     }
1180     if ($target{md5_asm_src}) {
1181         push @{$config{defines}}, "MD5_ASM";
1182     }
1183     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1184     if ($target{rmd160_asm_src}) {
1185         push @{$config{defines}}, "RMD160_ASM";
1186     }
1187     if ($target{aes_asm_src}) {
1188         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1189         # aes-ctr.fake is not a real file, only indication that assembler
1190         # module implements AES_ctr32_encrypt...
1191         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1192         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1193         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1194         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1195         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1196         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1197     }
1198     if ($target{wp_asm_src} =~ /mmx/) {
1199         if ($config{processor} eq "386") {
1200             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1201         } elsif (!$disabled{"whirlpool"}) {
1202             push @{$config{defines}}, "WHIRLPOOL_ASM";
1203         }
1204     }
1205     if ($target{modes_asm_src} =~ /ghash-/) {
1206         push @{$config{defines}}, "GHASH_ASM";
1207     }
1208     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1209         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1210     }
1211     if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
1212         push @{$config{defines}}, "PADLOCK_ASM";
1213     }
1214     if ($target{poly1305_asm_src} ne "") {
1215         push @{$config{defines}}, "POLY1305_ASM";
1216     }
1217 }
1218
1219 my $ecc = $target{cc};
1220 if ($^O ne "VMS" && !$disabled{makedepend}) {
1221     # Is the compiler gcc or clang?  $ecc is used below to see if
1222     # error-checking can be turned on.
1223     my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1224     open(PIPE, "$ccpcc --version 2>&1 |");
1225     my $lines = 2;
1226     while ( <PIPE> ) {
1227         # Find the version number and save the major.
1228         m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
1229         my $compiler_major = $1;
1230         # We know that GNU C version 3 and up as well as all clang
1231         # versions support dependency generation
1232         $config{makedepprog} = $ccpcc
1233             if (/clang/ || (/gcc/ && $compiler_major >= 3));
1234         $ecc = "clang" if /clang/;
1235         $ecc = "gcc" if /gcc/;
1236         last if ($config{makedepprog} || !$lines--);
1237     }
1238     close(PIPE);
1239
1240     $config{makedepprog} = which('makedepend') unless $config{makedepprog};
1241     $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1242 }
1243
1244
1245
1246 # Deal with bn_ops ###################################################
1247
1248 $config{bn_ll}                  =0;
1249 $config{export_var_as_fn}       =0;
1250 my $def_int="unsigned int";
1251 $config{rc4_int}                =$def_int;
1252 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1253
1254 my $count = 0;
1255 foreach (sort split(/\s+/,$target{bn_ops})) {
1256     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1257     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1258     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1259     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1260     ($config{b64l},$config{b64},$config{b32})
1261         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1262     ($config{b64l},$config{b64},$config{b32})
1263         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1264     ($config{b64l},$config{b64},$config{b32})
1265         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1266 }
1267 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1268     if $count > 1;
1269
1270
1271 # Hack cflags for better warnings (dev option) #######################
1272
1273 # "Stringify" the C flags string.  This permits it to be made part of a string
1274 # and works as well on command lines.
1275 $config{cflags} =~ s/([\\\"])/\\$1/g;
1276
1277 if (defined($config{api})) {
1278     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1279     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1280     push @{$config{defines}}, $apiflag;
1281 }
1282
1283 if ($strict_warnings)
1284         {
1285         my $wopt;
1286         die "ERROR --strict-warnings requires gcc or clang"
1287             unless $ecc eq 'gcc' || $ecc eq 'clang';
1288         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1289                 {
1290                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1291                 }
1292         if ($ecc eq "clang")
1293                 {
1294                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1295                         {
1296                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1297                         }
1298                 }
1299         }
1300
1301 unless ($disabled{"crypto-mdebug-backtrace"})
1302         {
1303         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1304                 {
1305                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1306                 }
1307         if ($target =~ /^BSD-/)
1308                 {
1309                 $config{ex_libs} .= " -lexecinfo";
1310                 }
1311         }
1312
1313 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; $config{cxxflags}="$config{cxxflags}$user_cflags";}
1314 else                    { $no_user_cflags=1;  }
1315 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1316 else               { $no_user_defines=1;    }
1317
1318 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1319
1320 unless ($disabled{afalgeng}) {
1321     $config{afalgeng}="";
1322     if ($target =~ m/^linux/) {
1323         my $minver = 4*10000 + 1*100 + 0;
1324         if ($config{cross_compile_prefix} eq "") {
1325             my $verstr = `uname -r`;
1326             my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1327             ($mi2) = $mi2 =~ /(\d+)/;
1328             my $ver = $ma*10000 + $mi1*100 + $mi2;
1329             if ($ver < $minver) {
1330                 $disabled{afalgeng} = "too-old-kernel";
1331             } else {
1332                 push @{$config{engdirs}}, "afalg";
1333             }
1334         } else {
1335             $disabled{afalgeng} = "cross-compiling";
1336         }
1337     } else {
1338         $disabled{afalgeng}  = "not-linux";
1339     }
1340 }
1341
1342 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1343
1344 # If we use the unified build, collect information from build.info files
1345 my %unified_info = ();
1346
1347 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1348 if ($builder eq "unified") {
1349     use lib catdir(dirname(__FILE__),"util");
1350     use with_fallback qw(Text::Template);
1351
1352     sub cleandir {
1353         my $base = shift;
1354         my $dir = shift;
1355         my $relativeto = shift || ".";
1356
1357         $dir = catdir($base,$dir) unless isabsolute($dir);
1358
1359         # Make sure the directories we're building in exists
1360         mkpath($dir);
1361
1362         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1363         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1364         return $res;
1365     }
1366
1367     sub cleanfile {
1368         my $base = shift;
1369         my $file = shift;
1370         my $relativeto = shift || ".";
1371
1372         $file = catfile($base,$file) unless isabsolute($file);
1373
1374         my $d = dirname($file);
1375         my $f = basename($file);
1376
1377         # Make sure the directories we're building in exists
1378         mkpath($d);
1379
1380         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1381         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1382         return $res;
1383     }
1384
1385     # Store the name of the template file we will build the build file from
1386     # in %config.  This may be useful for the build file itself.
1387     my @build_file_template_names =
1388         ( $builder_platform."-".$target{build_file}.".tmpl",
1389           $target{build_file}.".tmpl" );
1390     my @build_file_templates = ();
1391
1392     # First, look in the user provided directory, if given
1393     if (defined $ENV{$local_config_envname}) {
1394         @build_file_templates =
1395             map {
1396                 if ($^O eq 'VMS') {
1397                     # VMS environment variables are logical names,
1398                     # which can be used as is
1399                     $local_config_envname . ':' . $_;
1400                 } else {
1401                     catfile($ENV{$local_config_envname}, $_);
1402                 }
1403             }
1404             @build_file_template_names;
1405     }
1406     # Then, look in our standard directory
1407     push @build_file_templates,
1408         ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1409           @build_file_template_names );
1410
1411     my $build_file_template;
1412     for $_ (@build_file_templates) {
1413         $build_file_template = $_;
1414         last if -f $build_file_template;
1415
1416         $build_file_template = undef;
1417     }
1418     if (!defined $build_file_template) {
1419         die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1420     }
1421     $config{build_file_templates}
1422       = [ $build_file_template,
1423           cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1424                     $blddir) ];
1425
1426     my @build_infos = ( [ ".", "build.info" ] );
1427     foreach (@{$config{dirs}}) {
1428         push @build_infos, [ $_, "build.info" ]
1429             if (-f catfile($srcdir, $_, "build.info"));
1430     }
1431     foreach (@{$config{sdirs}}) {
1432         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1433             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1434     }
1435     foreach (@{$config{engdirs}}) {
1436         push @build_infos, [ catdir("engines", $_), "build.info" ]
1437             if (-f catfile($srcdir, "engines", $_, "build.info"));
1438     }
1439     foreach (@{$config{tdirs}}) {
1440         push @build_infos, [ catdir("test", $_), "build.info" ]
1441             if (-f catfile($srcdir, "test", $_, "build.info"));
1442     }
1443
1444     $config{build_infos} = [ ];
1445
1446     foreach (@build_infos) {
1447         my $sourced = catdir($srcdir, $_->[0]);
1448         my $buildd = catdir($blddir, $_->[0]);
1449
1450         mkpath($buildd);
1451
1452         my $f = $_->[1];
1453         # The basic things we're trying to build
1454         my @programs = ();
1455         my @programs_install = ();
1456         my @libraries = ();
1457         my @libraries_install = ();
1458         my @engines = ();
1459         my @engines_install = ();
1460         my @scripts = ();
1461         my @scripts_install = ();
1462         my @extra = ();
1463         my @overrides = ();
1464         my @intermediates = ();
1465         my @rawlines = ();
1466
1467         my %ordinals = ();
1468         my %sources = ();
1469         my %shared_sources = ();
1470         my %includes = ();
1471         my %depends = ();
1472         my %renames = ();
1473         my %sharednames = ();
1474         my %generate = ();
1475
1476         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1477         my $template = Text::Template->new(TYPE => 'FILE',
1478                                            SOURCE => catfile($sourced, $f));
1479         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1480         my @text =
1481             split /^/m,
1482             $template->fill_in(HASH => { config => \%config,
1483                                          target => \%target,
1484                                          disabled => \%disabled,
1485                                          withargs => \%withargs,
1486                                          builddir => abs2rel($buildd, $blddir),
1487                                          sourcedir => abs2rel($sourced, $blddir),
1488                                          buildtop => abs2rel($blddir, $blddir),
1489                                          sourcetop => abs2rel($srcdir, $blddir) },
1490                                DELIMITERS => [ "{-", "-}" ]);
1491
1492         # The top item of this stack has the following values
1493         # -2 positive already run and we found ELSE (following ELSIF should fail)
1494         # -1 positive already run (skip until ENDIF)
1495         # 0 negatives so far (if we're at a condition, check it)
1496         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1497         # 2 positive ELSE (following ELSIF should fail)
1498         my @skip = ();
1499         collect_information(
1500             collect_from_array([ @text ],
1501                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1502                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1503             # Info we're looking for
1504             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1505             => sub {
1506                 if (! @skip || $skip[$#skip] > 0) {
1507                     push @skip, !! $1;
1508                 } else {
1509                     push @skip, -1;
1510                 }
1511             },
1512             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1513             => sub { die "ELSIF out of scope" if ! @skip;
1514                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1515                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1516                      $skip[$#skip] = !! $1
1517                          if $skip[$#skip] == 0; },
1518             qr/^\s*ELSE\s*$/
1519             => sub { die "ELSE out of scope" if ! @skip;
1520                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1521                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1522             qr/^\s*ENDIF\s*$/
1523             => sub { die "ENDIF out of scope" if ! @skip;
1524                      pop @skip; },
1525             qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1526             => sub {
1527                 if (!@skip || $skip[$#skip] > 0) {
1528                     my $install = $1;
1529                     my @x = tokenize($2);
1530                     push @programs, @x;
1531                     push @programs_install, @x unless $install;
1532                 }
1533             },
1534             qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1535             => sub {
1536                 if (!@skip || $skip[$#skip] > 0) {
1537                     my $install = $1;
1538                     my @x = tokenize($2);
1539                     push @libraries, @x;
1540                     push @libraries_install, @x unless $install;
1541                 }
1542             },
1543             qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1544             => sub {
1545                 if (!@skip || $skip[$#skip] > 0) {
1546                     my $install = $1;
1547                     my @x = tokenize($2);
1548                     push @engines, @x;
1549                     push @engines_install, @x unless $install;
1550                 }
1551             },
1552             qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1553             => sub {
1554                 if (!@skip || $skip[$#skip] > 0) {
1555                     my $install = $1;
1556                     my @x = tokenize($2);
1557                     push @scripts, @x;
1558                     push @scripts_install, @x unless $install;
1559                 }
1560             },
1561             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1562             => sub { push @extra, tokenize($1)
1563                          if !@skip || $skip[$#skip] > 0 },
1564             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1565             => sub { push @overrides, tokenize($1)
1566                          if !@skip || $skip[$#skip] > 0 },
1567
1568             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1569             => sub { push @{$ordinals{$1}}, tokenize($2)
1570                          if !@skip || $skip[$#skip] > 0 },
1571             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1572             => sub { push @{$sources{$1}}, tokenize($2)
1573                          if !@skip || $skip[$#skip] > 0 },
1574             qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1575             => sub { push @{$shared_sources{$1}}, tokenize($2)
1576                          if !@skip || $skip[$#skip] > 0 },
1577             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1578             => sub { push @{$includes{$1}}, tokenize($2)
1579                          if !@skip || $skip[$#skip] > 0 },
1580             qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
1581             => sub { push @{$depends{$1}}, tokenize($2)
1582                          if !@skip || $skip[$#skip] > 0 },
1583             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1584             => sub { push @{$generate{$1}}, $2
1585                          if !@skip || $skip[$#skip] > 0 },
1586             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1587             => sub { push @{$renames{$1}}, tokenize($2)
1588                          if !@skip || $skip[$#skip] > 0 },
1589             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1590             => sub { push @{$sharednames{$1}}, tokenize($2)
1591                          if !@skip || $skip[$#skip] > 0 },
1592             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1593             => sub {
1594                 my $lineiterator = shift;
1595                 my $target_kind = $1;
1596                 while (defined $lineiterator->()) {
1597                     s|\R$||;
1598                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1599                         die "ENDRAW doesn't match BEGINRAW"
1600                             if $1 ne $target_kind;
1601                         last;
1602                     }
1603                     next if @skip && $skip[$#skip] <= 0;
1604                     push @rawlines,  $_
1605                         if ($target_kind eq $target{build_file}
1606                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1607                 }
1608             },
1609             qr/^\s*(?:#.*)?$/ => sub { },
1610             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1611             "BEFORE" => sub {
1612                 if ($buildinfo_debug) {
1613                     print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1614                     print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1615                 }
1616             },
1617             "AFTER" => sub {
1618                 if ($buildinfo_debug) {
1619                     print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1620                 }
1621             },
1622             );
1623         die "runaway IF?" if (@skip);
1624
1625         foreach (keys %renames) {
1626             die "$_ renamed to more than one thing: "
1627                 ,join(" ", @{$renames{$_}}),"\n"
1628                 if scalar @{$renames{$_}} > 1;
1629             my $dest = cleanfile($buildd, $_, $blddir);
1630             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1631             die "$dest renamed to more than one thing: "
1632                 ,$unified_info{rename}->{$dest}, $to
1633                 unless !defined($unified_info{rename}->{$dest})
1634                 or $unified_info{rename}->{$dest} eq $to;
1635             $unified_info{rename}->{$dest} = $to;
1636         }
1637
1638         foreach (@programs) {
1639             my $program = cleanfile($buildd, $_, $blddir);
1640             if ($unified_info{rename}->{$program}) {
1641                 $program = $unified_info{rename}->{$program};
1642             }
1643             $unified_info{programs}->{$program} = 1;
1644         }
1645
1646         foreach (@programs_install) {
1647             my $program = cleanfile($buildd, $_, $blddir);
1648             if ($unified_info{rename}->{$program}) {
1649                 $program = $unified_info{rename}->{$program};
1650             }
1651             $unified_info{install}->{programs}->{$program} = 1;
1652         }
1653
1654         foreach (@libraries) {
1655             my $library = cleanfile($buildd, $_, $blddir);
1656             if ($unified_info{rename}->{$library}) {
1657                 $library = $unified_info{rename}->{$library};
1658             }
1659             $unified_info{libraries}->{$library} = 1;
1660         }
1661
1662         foreach (@libraries_install) {
1663             my $library = cleanfile($buildd, $_, $blddir);
1664             if ($unified_info{rename}->{$library}) {
1665                 $library = $unified_info{rename}->{$library};
1666             }
1667             $unified_info{install}->{libraries}->{$library} = 1;
1668         }
1669
1670         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1671 ENGINES can only be used if configured with 'dynamic-engine'.
1672 This is usually a fault in a build.info file.
1673 EOF
1674         foreach (@engines) {
1675             my $library = cleanfile($buildd, $_, $blddir);
1676             if ($unified_info{rename}->{$library}) {
1677                 $library = $unified_info{rename}->{$library};
1678             }
1679             $unified_info{engines}->{$library} = 1;
1680         }
1681
1682         foreach (@engines_install) {
1683             my $library = cleanfile($buildd, $_, $blddir);
1684             if ($unified_info{rename}->{$library}) {
1685                 $library = $unified_info{rename}->{$library};
1686             }
1687             $unified_info{install}->{engines}->{$library} = 1;
1688         }
1689
1690         foreach (@scripts) {
1691             my $script = cleanfile($buildd, $_, $blddir);
1692             if ($unified_info{rename}->{$script}) {
1693                 $script = $unified_info{rename}->{$script};
1694             }
1695             $unified_info{scripts}->{$script} = 1;
1696         }
1697
1698         foreach (@scripts_install) {
1699             my $script = cleanfile($buildd, $_, $blddir);
1700             if ($unified_info{rename}->{$script}) {
1701                 $script = $unified_info{rename}->{$script};
1702             }
1703             $unified_info{install}->{scripts}->{$script} = 1;
1704         }
1705
1706         foreach (@extra) {
1707             my $extra = cleanfile($buildd, $_, $blddir);
1708             $unified_info{extra}->{$extra} = 1;
1709         }
1710
1711         foreach (@overrides) {
1712             my $override = cleanfile($buildd, $_, $blddir);
1713             $unified_info{overrides}->{$override} = 1;
1714         }
1715
1716         push @{$unified_info{rawlines}}, @rawlines;
1717
1718         unless ($disabled{shared}) {
1719             # Check sharednames.
1720             foreach (keys %sharednames) {
1721                 my $dest = cleanfile($buildd, $_, $blddir);
1722                 if ($unified_info{rename}->{$dest}) {
1723                     $dest = $unified_info{rename}->{$dest};
1724                 }
1725                 die "shared_name for $dest with multiple values: "
1726                     ,join(" ", @{$sharednames{$_}}),"\n"
1727                     if scalar @{$sharednames{$_}} > 1;
1728                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1729                 die "shared_name found for a library $dest that isn't defined\n"
1730                     unless $unified_info{libraries}->{$dest};
1731                 die "shared_name for $dest with multiple values: "
1732                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1733                     unless !defined($unified_info{sharednames}->{$dest})
1734                     or $unified_info{sharednames}->{$dest} eq $to;
1735                 $unified_info{sharednames}->{$dest} = $to;
1736             }
1737
1738             # Additionally, we set up sharednames for libraries that don't
1739             # have any, as themselves.
1740             foreach (keys %{$unified_info{libraries}}) {
1741                 if (!defined $unified_info{sharednames}->{$_}) {
1742                     $unified_info{sharednames}->{$_} = $_
1743                 }
1744             }
1745         }
1746
1747         foreach (keys %ordinals) {
1748             my $dest = $_;
1749             my $ddest = cleanfile($buildd, $_, $blddir);
1750             if ($unified_info{rename}->{$ddest}) {
1751                 $ddest = $unified_info{rename}->{$ddest};
1752             }
1753             foreach (@{$ordinals{$dest}}) {
1754                 my %known_ordinals =
1755                     (
1756                      crypto =>
1757                      cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1758                      ssl =>
1759                      cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1760                     );
1761                 my $o = $known_ordinals{$_};
1762                 die "Ordinals for $ddest defined more than once\n"
1763                     if $unified_info{ordinals}->{$ddest};
1764                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1765             }
1766         }
1767
1768         foreach (keys %sources) {
1769             my $dest = $_;
1770             my $ddest = cleanfile($buildd, $_, $blddir);
1771             if ($unified_info{rename}->{$ddest}) {
1772                 $ddest = $unified_info{rename}->{$ddest};
1773             }
1774             foreach (@{$sources{$dest}}) {
1775                 my $s = cleanfile($sourced, $_, $blddir);
1776
1777                 # If it isn't in the source tree, we assume it's generated
1778                 # in the build tree
1779                 if (! -f $s) {
1780                     $s = cleanfile($buildd, $_, $blddir);
1781                 }
1782                 # We recognise C++, C and asm files
1783                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1784                     my $o = $_;
1785                     $o =~ s/\.[csS]$/.o/; # C and assembler
1786                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1787                     $o = cleanfile($buildd, $o, $blddir);
1788                     $unified_info{sources}->{$ddest}->{$o} = 1;
1789                     $unified_info{sources}->{$o}->{$s} = 1;
1790                 } else {
1791                     $unified_info{sources}->{$ddest}->{$s} = 1;
1792                 }
1793             }
1794         }
1795
1796         foreach (keys %shared_sources) {
1797             my $dest = $_;
1798             my $ddest = cleanfile($buildd, $_, $blddir);
1799             if ($unified_info{rename}->{$ddest}) {
1800                 $ddest = $unified_info{rename}->{$ddest};
1801             }
1802             foreach (@{$shared_sources{$dest}}) {
1803                 my $s = cleanfile($sourced, $_, $blddir);
1804
1805                 # If it isn't in the source tree, we assume it's generated
1806                 # in the build tree
1807                 if (! -f $s) {
1808                     $s = cleanfile($buildd, $_, $blddir);
1809                 }
1810                 # We recognise C++, C and asm files
1811                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1812                     my $o = $_;
1813                     $o =~ s/\.[csS]$/.o/; # C and assembler
1814                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1815                     $o = cleanfile($buildd, $o, $blddir);
1816                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1817                     $unified_info{sources}->{$o}->{$s} = 1;
1818                 } else {
1819                     die "unrecognised source file type for shared library: $s\n";
1820                 }
1821             }
1822         }
1823
1824         foreach (keys %generate) {
1825             my $dest = $_;
1826             my $ddest = cleanfile($buildd, $_, $blddir);
1827             if ($unified_info{rename}->{$ddest}) {
1828                 $ddest = $unified_info{rename}->{$ddest};
1829             }
1830             die "more than one generator for $dest: "
1831                     ,join(" ", @{$generate{$_}}),"\n"
1832                     if scalar @{$generate{$_}} > 1;
1833             my @generator = split /\s+/, $generate{$dest}->[0];
1834             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1835             $unified_info{generate}->{$ddest} = [ @generator ];
1836         }
1837
1838         foreach (keys %depends) {
1839             my $dest = $_;
1840             my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
1841
1842             # If the destination doesn't exist in source, it can only be
1843             # a generated file in the build tree.
1844             if ($ddest ne "" && ! -f $ddest) {
1845                 $ddest = cleanfile($buildd, $_, $blddir);
1846                 if ($unified_info{rename}->{$ddest}) {
1847                     $ddest = $unified_info{rename}->{$ddest};
1848                 }
1849             }
1850             foreach (@{$depends{$dest}}) {
1851                 my $d = cleanfile($sourced, $_, $blddir);
1852
1853                 # If we know it's generated, or assume it is because we can't
1854                 # find it in the source tree, we set file we depend on to be
1855                 # in the build tree rather than the source tree, and assume
1856                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1857                 # section or in the Makefile template.
1858                 if (! -f $d
1859                     || (grep { $d eq $_ }
1860                         map { cleanfile($srcdir, $_, $blddir) }
1861                         grep { /\.h$/ } keys %{$unified_info{generate}})) {
1862                     $d = cleanfile($buildd, $_, $blddir);
1863                 }
1864                 # Take note if the file to depend on is being renamed
1865                 # Take extra care with files ending with .a, they should
1866                 # be treated without that extension, and the extension
1867                 # should be added back after treatment.
1868                 $d =~ /(\.a)?$/;
1869                 my $e = $1 // "";
1870                 $d = $`;
1871                 if ($unified_info{rename}->{$d}) {
1872                     $d = $unified_info{rename}->{$d};
1873                 }
1874                 $d .= $e;
1875                 $unified_info{depends}->{$ddest}->{$d} = 1;
1876                 # If we depend on a header file or a perl module, let's make
1877                 # sure it can get included
1878                 if ($dest ne "" && $d =~ /\.(h|pm)$/) {
1879                     my $i = dirname($d);
1880                     push @{$unified_info{includes}->{$ddest}->{source}}, $i
1881                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}};
1882                 }
1883             }
1884         }
1885
1886         foreach (keys %includes) {
1887             my $dest = $_;
1888             my $ddest = cleanfile($sourced, $_, $blddir);
1889
1890             # If the destination doesn't exist in source, it can only be
1891             # a generated file in the build tree.
1892             if (! -f $ddest) {
1893                 $ddest = cleanfile($buildd, $_, $blddir);
1894                 if ($unified_info{rename}->{$ddest}) {
1895                     $ddest = $unified_info{rename}->{$ddest};
1896                 }
1897             }
1898             foreach (@{$includes{$dest}}) {
1899                 my $is = cleandir($sourced, $_, $blddir);
1900                 my $ib = cleandir($buildd, $_, $blddir);
1901                 push @{$unified_info{includes}->{$ddest}->{source}}, $is
1902                     unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
1903                 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
1904                     unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
1905             }
1906         }
1907     }
1908
1909     ### Make unified_info a bit more efficient
1910     # One level structures
1911     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1912         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1913     }
1914     # Two level structures
1915     foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
1916         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1917             $unified_info{$l1}->{$l2} =
1918                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1919         }
1920     }
1921     # Includes
1922     foreach my $dest (sort keys %{$unified_info{includes}}) {
1923         if (defined($unified_info{includes}->{$dest}->{build})) {
1924             my @source_includes =
1925                 ( @{$unified_info{includes}->{$dest}->{source}} );
1926             $unified_info{includes}->{$dest} =
1927                 [ @{$unified_info{includes}->{$dest}->{build}} ];
1928             foreach my $inc (@source_includes) {
1929                 push @{$unified_info{includes}->{$dest}}, $inc
1930                     unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
1931             }
1932         } else {
1933             $unified_info{includes}->{$dest} =
1934                 [ @{$unified_info{includes}->{$dest}->{source}} ];
1935         }
1936     }
1937 }
1938
1939 # For the schemes that need it, we provide the old *_obj configs
1940 # from the *_asm_obj ones
1941 foreach (grep /_(asm|aux)_src$/, keys %target) {
1942     my $src = $_;
1943     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1944     $target{$obj} = $target{$src};
1945     $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
1946     $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
1947 }
1948
1949 # Write down our configuration where it fits #########################
1950
1951 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1952 print OUT <<"EOF";
1953 package configdata;
1954
1955 use strict;
1956 use warnings;
1957
1958 use Exporter;
1959 #use vars qw(\@ISA \@EXPORT);
1960 our \@ISA = qw(Exporter);
1961 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
1962
1963 EOF
1964 print OUT "our %config = (\n";
1965 foreach (sort keys %config) {
1966     if (ref($config{$_}) eq "ARRAY") {
1967         print OUT "  ", $_, " => [ ", join(", ",
1968                                            map { quotify("perl", $_) }
1969                                            @{$config{$_}}), " ],\n";
1970     } else {
1971         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1972     }
1973 }
1974 print OUT <<"EOF";
1975 );
1976
1977 EOF
1978 print OUT "our %target = (\n";
1979 foreach (sort keys %target) {
1980     if (ref($target{$_}) eq "ARRAY") {
1981         print OUT "  ", $_, " => [ ", join(", ",
1982                                            map { quotify("perl", $_) }
1983                                            @{$target{$_}}), " ],\n";
1984     } else {
1985         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1986     }
1987 }
1988 print OUT <<"EOF";
1989 );
1990
1991 EOF
1992 print OUT "our \%available_protocols = (\n";
1993 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1994 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1995 print OUT <<"EOF";
1996 );
1997
1998 EOF
1999 print OUT "our \@disablables = (\n";
2000 foreach (@disablables) {
2001     print OUT "  ", quotify("perl", $_), ",\n";
2002 }
2003 print OUT <<"EOF";
2004 );
2005
2006 EOF
2007 print OUT "our \%disabled = (\n";
2008 foreach (sort keys %disabled) {
2009     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
2010 }
2011 print OUT <<"EOF";
2012 );
2013
2014 EOF
2015 print OUT "our %withargs = (\n";
2016 foreach (sort keys %withargs) {
2017     if (ref($withargs{$_}) eq "ARRAY") {
2018         print OUT "  ", $_, " => [ ", join(", ",
2019                                            map { quotify("perl", $_) }
2020                                            @{$withargs{$_}}), " ],\n";
2021     } else {
2022         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
2023     }
2024 }
2025 print OUT <<"EOF";
2026 );
2027
2028 EOF
2029 if ($builder eq "unified") {
2030     my $recurse;
2031     $recurse = sub {
2032         my $indent = shift;
2033         foreach (@_) {
2034             if (ref $_ eq "ARRAY") {
2035                 print OUT " "x$indent, "[\n";
2036                 foreach (@$_) {
2037                     $recurse->($indent + 4, $_);
2038                 }
2039                 print OUT " "x$indent, "],\n";
2040             } elsif (ref $_ eq "HASH") {
2041                 my %h = %$_;
2042                 print OUT " "x$indent, "{\n";
2043                 foreach (sort keys %h) {
2044                     if (ref $h{$_} eq "") {
2045                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
2046                     } else {
2047                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
2048                         $recurse->($indent + 8, $h{$_});
2049                     }
2050                 }
2051                 print OUT " "x$indent, "},\n";
2052             } else {
2053                 print OUT " "x$indent, quotify("perl", $_), ",\n";
2054             }
2055         }
2056     };
2057     print OUT "our %unified_info = (\n";
2058     foreach (sort keys %unified_info) {
2059         if (ref $unified_info{$_} eq "") {
2060             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
2061         } else {
2062             print OUT " "x4, quotify("perl", $_), " =>\n";
2063             $recurse->(8, $unified_info{$_});
2064         }
2065     }
2066     print OUT <<"EOF";
2067 );
2068
2069 EOF
2070 }
2071 print OUT "1;\n";
2072 close(OUT);
2073
2074 print "\n";
2075 print "PROCESSOR     =$config{processor}\n" if $config{processor};
2076 print "PERL          =$config{perl}\n";
2077 print "PERLVERSION   =$Config{version} for $Config{archname}\n";
2078 print "HASHBANGPERL  =$config{hashbangperl}\n";
2079 print "CC            =$config{cross_compile_prefix}$target{cc}\n";
2080 print "CFLAG         =$target{cflags} $config{cflags}\n";
2081 print "CXX           =$config{cross_compile_prefix}$target{cxx}\n"
2082     if defined $target{cxx};
2083 print "CXXFLAG       =$target{cxxflags} $config{cxxflags}\n"
2084     if defined $target{cxx};
2085 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
2086 #print "RANLIB        =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
2087 #                             "$config{cross_compile_prefix}ranlib" :
2088 #                             "$target{ranlib}", "\n";
2089 print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
2090
2091 my %builders = (
2092     unified => sub {
2093         run_dofile(catfile($blddir, $target{build_file}),
2094                    @{$config{build_file_templates}});
2095     },
2096     );
2097
2098 $builders{$builder}->($builder_platform, @builder_opts);
2099
2100 print <<"EOF" if ($disabled{threads} eq "unavailable");
2101
2102 The library could not be configured for supporting multi-threaded
2103 applications as the compiler options required on this system are not known.
2104 See file INSTALL for details if you need multi-threading.
2105 EOF
2106
2107 print <<"EOF" if ($no_shared_warn);
2108
2109 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2110 platform, so we will pretend you gave the option 'no-pic', which also disables
2111 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
2112 or position independent code, please let us know (but please first make sure
2113 you have tried with a current version of OpenSSL).
2114 EOF
2115
2116 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2117
2118 WARNING: there are indications that another build was made in the source
2119 directory.  This build may have picked up artifacts from that build, the
2120 safest course of action is to clean the source directory and redo this
2121 configuration.
2122 EOF
2123
2124 exit(0);
2125
2126 ######################################################################
2127 #
2128 # Helpers and utility functions
2129 #
2130
2131 # Configuration file reading #########################################
2132
2133 # Note: All of the helper functions are for lazy evaluation.  They all
2134 # return a CODE ref, which will return the intended value when evaluated.
2135 # Thus, whenever there's mention of a returned value, it's about that
2136 # intended value.
2137
2138 # Helper function to implement conditional inheritance depending on the
2139 # value of $disabled{asm}.  Used in inherit_from values as follows:
2140 #
2141 #      inherit_from => [ "template", asm("asm_tmpl") ]
2142 #
2143 sub asm {
2144     my @x = @_;
2145     sub {
2146         $disabled{asm} ? () : @x;
2147     }
2148 }
2149
2150 # Helper function to implement conditional value variants, with a default
2151 # plus additional values based on the value of $config{build_type}.
2152 # Arguments are given in hash table form:
2153 #
2154 #       picker(default => "Basic string: ",
2155 #              debug   => "debug",
2156 #              release => "release")
2157 #
2158 # When configuring with --debug, the resulting string will be
2159 # "Basic string: debug", and when not, it will be "Basic string: release"
2160 #
2161 # This can be used to create variants of sets of flags according to the
2162 # build type:
2163 #
2164 #       cflags => picker(default => "-Wall",
2165 #                        debug   => "-g -O0",
2166 #                        release => "-O3")
2167 #
2168 sub picker {
2169     my %opts = @_;
2170     return sub { add($opts{default} || (),
2171                      $opts{$config{build_type}} || ())->(); }
2172 }
2173
2174 # Helper function to combine several values of different types into one.
2175 # This is useful if you want to combine a string with the result of a
2176 # lazy function, such as:
2177 #
2178 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2179 #
2180 sub combine {
2181     my @stuff = @_;
2182     return sub { add(@stuff)->(); }
2183 }
2184
2185 # Helper function to implement conditional values depending on the value
2186 # of $disabled{threads}.  Can be used as follows:
2187 #
2188 #       cflags => combine("-Wall", threads("-pthread"))
2189 #
2190 sub threads {
2191     my @flags = @_;
2192     return sub { add($disabled{threads} ? () : @flags)->(); }
2193 }
2194
2195
2196
2197 our $add_called = 0;
2198 # Helper function to implement adding values to already existing configuration
2199 # values.  It handles elements that are ARRAYs, CODEs and scalars
2200 sub _add {
2201     my $separator = shift;
2202
2203     # If there's any ARRAY in the collection of values OR the separator
2204     # is undef, we will return an ARRAY of combined values, otherwise a
2205     # string of joined values with $separator as the separator.
2206     my $found_array = !defined($separator);
2207
2208     my @values =
2209         map {
2210             my $res = $_;
2211             while (ref($res) eq "CODE") {
2212                 $res = $res->();
2213             }
2214             if (defined($res)) {
2215                 if (ref($res) eq "ARRAY") {
2216                     $found_array = 1;
2217                     @$res;
2218                 } else {
2219                     $res;
2220                 }
2221             } else {
2222                 ();
2223             }
2224     } (@_);
2225
2226     $add_called = 1;
2227
2228     if ($found_array) {
2229         [ @values ];
2230     } else {
2231         join($separator, grep { defined($_) && $_ ne "" } @values);
2232     }
2233 }
2234 sub add_before {
2235     my $separator = " ";
2236     if (ref($_[$#_]) eq "HASH") {
2237         my $opts = pop;
2238         $separator = $opts->{separator};
2239     }
2240     my @x = @_;
2241     sub { _add($separator, @x, @_) };
2242 }
2243 sub add {
2244     my $separator = " ";
2245     if (ref($_[$#_]) eq "HASH") {
2246         my $opts = pop;
2247         $separator = $opts->{separator};
2248     }
2249     my @x = @_;
2250     sub { _add($separator, @_, @x) };
2251 }
2252
2253 # configuration reader, evaluates the input file as a perl script and expects
2254 # it to fill %targets with target configurations.  Those are then added to
2255 # %table.
2256 sub read_config {
2257     my $fname = shift;
2258     open(CONFFILE, "< $fname")
2259         or die "Can't open configuration file '$fname'!\n";
2260     my $x = $/;
2261     undef $/;
2262     my $content = <CONFFILE>;
2263     $/ = $x;
2264     close(CONFFILE);
2265     my %targets = ();
2266     {
2267         # Protect certain tables from tampering
2268         local %table = %::table;
2269
2270         eval $content;
2271         warn $@ if $@;
2272     }
2273
2274     # For each target, check that it's configured with a hash table.
2275     foreach (keys %targets) {
2276         if (ref($targets{$_}) ne "HASH") {
2277             if (ref($targets{$_}) eq "") {
2278                 warn "Deprecated target configuration for $_, ignoring...\n";
2279             } else {
2280                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2281             }
2282             delete $targets{$_};
2283         } else {
2284             $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2285         }
2286     }
2287
2288     %table = (%table, %targets);
2289
2290 }
2291
2292 # configuration resolver.  Will only resolve all the lazy evaluation
2293 # codeblocks for the chosen target and all those it inherits from,
2294 # recursively
2295 sub resolve_config {
2296     my $target = shift;
2297     my @breadcrumbs = @_;
2298
2299 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2300
2301     if (grep { $_ eq $target } @breadcrumbs) {
2302         die "inherit_from loop!  target backtrace:\n  "
2303             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2304     }
2305
2306     if (!defined($table{$target})) {
2307         warn "Warning! target $target doesn't exist!\n";
2308         return ();
2309     }
2310     # Recurse through all inheritances.  They will be resolved on the
2311     # fly, so when this operation is done, they will all just be a
2312     # bunch of attributes with string values.
2313     # What we get here, though, are keys with references to lists of
2314     # the combined values of them all.  We will deal with lists after
2315     # this stage is done.
2316     my %combined_inheritance = ();
2317     if ($table{$target}->{inherit_from}) {
2318         my @inherit_from =
2319             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2320         foreach (@inherit_from) {
2321             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2322
2323             # 'template' is a marker that's considered private to
2324             # the config that had it.
2325             delete $inherited_config{template};
2326
2327             foreach (keys %inherited_config) {
2328                 if (!$combined_inheritance{$_}) {
2329                     $combined_inheritance{$_} = [];
2330                 }
2331                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2332             }
2333         }
2334     }
2335
2336     # We won't need inherit_from in this target any more, since we've
2337     # resolved all the inheritances that lead to this
2338     delete $table{$target}->{inherit_from};
2339
2340     # Now is the time to deal with those lists.  Here's the place to
2341     # decide what shall be done with those lists, all based on the
2342     # values of the target we're currently dealing with.
2343     # - If a value is a coderef, it will be executed with the list of
2344     #   inherited values as arguments.
2345     # - If the corresponding key doesn't have a value at all or is the
2346     #   empty string, the inherited value list will be run through the
2347     #   default combiner (below), and the result becomes this target's
2348     #   value.
2349     # - Otherwise, this target's value is assumed to be a string that
2350     #   will simply override the inherited list of values.
2351     my $default_combiner = add();
2352
2353     my %all_keys =
2354         map { $_ => 1 } (keys %combined_inheritance,
2355                          keys %{$table{$target}});
2356
2357     sub process_values {
2358         my $object    = shift;
2359         my $inherited = shift;  # Always a [ list ]
2360         my $target    = shift;
2361         my $entry     = shift;
2362
2363         $add_called = 0;
2364
2365         while(ref($object) eq "CODE") {
2366             $object = $object->(@$inherited);
2367         }
2368         if (!defined($object)) {
2369             return ();
2370         }
2371         elsif (ref($object) eq "ARRAY") {
2372             local $add_called;  # To make sure recursive calls don't affect it
2373             return [ map { process_values($_, $inherited, $target, $entry) }
2374                      @$object ];
2375         } elsif (ref($object) eq "") {
2376             return $object;
2377         } else {
2378             die "cannot handle reference type ",ref($object)
2379                 ," found in target ",$target," -> ",$entry,"\n";
2380         }
2381     }
2382
2383     foreach (sort keys %all_keys) {
2384         my $previous = $combined_inheritance{$_};
2385
2386         # Current target doesn't have a value for the current key?
2387         # Assign it the default combiner, the rest of this loop body
2388         # will handle it just like any other coderef.
2389         if (!exists $table{$target}->{$_}) {
2390             $table{$target}->{$_} = $default_combiner;
2391         }
2392
2393         $table{$target}->{$_} = process_values($table{$target}->{$_},
2394                                                $combined_inheritance{$_},
2395                                                $target, $_);
2396         unless(defined($table{$target}->{$_})) {
2397             delete $table{$target}->{$_};
2398         }
2399 #        if ($extra_checks &&
2400 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2401 #            warn "$_ got replaced in $target\n";
2402 #        }
2403     }
2404
2405     # Finally done, return the result.
2406     return %{$table{$target}};
2407 }
2408
2409 sub usage
2410         {
2411         print STDERR $usage;
2412         print STDERR "\npick os/compiler from:\n";
2413         my $j=0;
2414         my $i;
2415         my $k=0;
2416         foreach $i (sort keys %table)
2417                 {
2418                 next if $table{$i}->{template};
2419                 next if $i =~ /^debug/;
2420                 $k += length($i) + 1;
2421                 if ($k > 78)
2422                         {
2423                         print STDERR "\n";
2424                         $k=length($i);
2425                         }
2426                 print STDERR $i . " ";
2427                 }
2428         foreach $i (sort keys %table)
2429                 {
2430                 next if $table{$i}->{template};
2431                 next if $i !~ /^debug/;
2432                 $k += length($i) + 1;
2433                 if ($k > 78)
2434                         {
2435                         print STDERR "\n";
2436                         $k=length($i);
2437                         }
2438                 print STDERR $i . " ";
2439                 }
2440         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2441         exit(1);
2442         }
2443
2444 sub run_dofile
2445 {
2446     my $out = shift;
2447     my @templates = @_;
2448
2449     unlink $out || warn "Can't remove $out, $!"
2450         if -f $out;
2451     foreach (@templates) {
2452         die "Can't open $_, $!" unless -f $_;
2453     }
2454     my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2455     my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2456     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2457     system($cmd);
2458     exit 1 if $? != 0;
2459     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2460 }
2461
2462 sub which
2463 {
2464     my ($name)=@_;
2465
2466     if (eval { require IPC::Cmd; 1; }) {
2467         IPC::Cmd->import();
2468         return scalar IPC::Cmd::can_run($name);
2469     } else {
2470         # if there is $directories component in splitpath,
2471         # then it's not something to test with $PATH...
2472         return $name if (File::Spec->splitpath($name))[1];
2473
2474         foreach (File::Spec->path()) {
2475             my $fullpath = catfile($_, "$name$target{exe_extension}");
2476             if (-f $fullpath and -x $fullpath) {
2477                 return $fullpath;
2478             }
2479         }
2480     }
2481 }
2482
2483 # Configuration printer ##############################################
2484
2485 sub print_table_entry
2486 {
2487     my $target = shift;
2488     my %target = resolve_config($target);
2489     my $type = shift;
2490
2491     # Don't print the templates
2492     return if $target{template};
2493
2494     my @sequence = (
2495         "sys_id",
2496         "cc",
2497         "cflags",
2498         "defines",
2499         "unistd",
2500         "ld",
2501         "lflags",
2502         "loutflag",
2503         "plib_lflags",
2504         "ex_libs",
2505         "bn_ops",
2506         "apps_aux_src",
2507         "cpuid_asm_src",
2508         "uplink_aux_src",
2509         "bn_asm_src",
2510         "ec_asm_src",
2511         "des_asm_src",
2512         "aes_asm_src",
2513         "bf_asm_src",
2514         "md5_asm_src",
2515         "cast_asm_src",
2516         "sha1_asm_src",
2517         "rc4_asm_src",
2518         "rmd160_asm_src",
2519         "rc5_asm_src",
2520         "wp_asm_src",
2521         "cmll_asm_src",
2522         "modes_asm_src",
2523         "padlock_asm_src",
2524         "chacha_asm_src",
2525         "poly1035_asm_src",
2526         "thread_scheme",
2527         "perlasm_scheme",
2528         "dso_scheme",
2529         "shared_target",
2530         "shared_cflag",
2531         "shared_defines",
2532         "shared_ldflag",
2533         "shared_rcflag",
2534         "shared_extension",
2535         "dso_extension",
2536         "obj_extension",
2537         "exe_extension",
2538         "ranlib",
2539         "ar",
2540         "arflags",
2541         "aroutflag",
2542         "rc",
2543         "rcflags",
2544         "rcoutflag",
2545         "mt",
2546         "mtflags",
2547         "mtinflag",
2548         "mtoutflag",
2549         "multilib",
2550         "build_scheme",
2551         );
2552
2553     if ($type eq "TABLE") {
2554         print "\n";
2555         print "*** $target\n";
2556         foreach (@sequence) {
2557             if (ref($target{$_}) eq "ARRAY") {
2558                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2559             } else {
2560                 printf "\$%-12s = %s\n", $_, $target{$_};
2561             }
2562         }
2563     } elsif ($type eq "HASH") {
2564         my $largest =
2565             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2566         print "    '$target' => {\n";
2567         foreach (@sequence) {
2568             if ($target{$_}) {
2569                 if (ref($target{$_}) eq "ARRAY") {
2570                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2571                 } else {
2572                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2573                 }
2574             }
2575         }
2576         print "    },\n";
2577     }
2578 }
2579
2580 # Utility routines ###################################################
2581
2582 # On VMS, if the given file is a logical name, File::Spec::Functions
2583 # will consider it an absolute path.  There are cases when we want a
2584 # purely syntactic check without checking the environment.
2585 sub isabsolute {
2586     my $file = shift;
2587
2588     # On non-platforms, we just use file_name_is_absolute().
2589     return file_name_is_absolute($file) unless $^O eq "VMS";
2590
2591     # If the file spec includes a device or a directpry spec,
2592     # file_name_is_absolute() is perfectly safe.
2593     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2594
2595     # Here, we know the given file spec isn't absolute
2596     return 0;
2597 }
2598
2599 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2600 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2601 # realpath() requires that at least all path components except the last is an
2602 # existing directory.  On VMS, the last component of the directory spec must
2603 # exist.
2604 sub absolutedir {
2605     my $dir = shift;
2606
2607     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2608     # will return the volume name for the device, no matter what.  Also,
2609     # it will return an incorrect directory spec if the argument is a
2610     # directory that doesn't exist.
2611     if ($^O eq "VMS") {
2612         return rel2abs($dir);
2613     }
2614
2615     # We use realpath() on Unix, since no other will properly clean out
2616     # a directory spec.
2617     use Cwd qw/realpath/;
2618
2619     return realpath($dir);
2620 }
2621
2622 sub quotify {
2623     my %processors = (
2624         perl    => sub { my $x = shift;
2625                          $x =~ s/([\\\$\@"])/\\$1/g;
2626                          return '"'.$x.'"'; },
2627         maybeshell => sub { my $x = shift;
2628                             (my $y = $x) =~ s/([\\\"])/\\$1/g;
2629                             if ($x ne $y || $x =~ m|\s|) {
2630                                 return '"'.$y.'"';
2631                             } else {
2632                                 return $x;
2633                             }
2634                         },
2635         );
2636     my $for = shift;
2637     my $processor =
2638         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2639
2640     return map { $processor->($_); } @_;
2641 }
2642
2643 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2644 # $filename is a file name to read from
2645 # $line_concat_cond_re is a regexp detecting a line continuation ending
2646 # $line_concat is a CODEref that takes care of concatenating two lines
2647 sub collect_from_file {
2648     my $filename = shift;
2649     my $line_concat_cond_re = shift;
2650     my $line_concat = shift;
2651
2652     open my $fh, $filename || die "unable to read $filename: $!\n";
2653     return sub {
2654         my $saved_line = "";
2655         $_ = "";
2656         while (<$fh>) {
2657             s|\R$||;
2658             if (defined $line_concat) {
2659                 $_ = $line_concat->($saved_line, $_);
2660                 $saved_line = "";
2661             }
2662             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2663                 $saved_line = $_;
2664                 next;
2665             }
2666             return $_;
2667         }
2668         die "$filename ending with continuation line\n" if $_;
2669         close $fh;
2670         return undef;
2671     }
2672 }
2673
2674 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2675 # $array is an ARRAYref of lines
2676 # $line_concat_cond_re is a regexp detecting a line continuation ending
2677 # $line_concat is a CODEref that takes care of concatenating two lines
2678 sub collect_from_array {
2679     my $array = shift;
2680     my $line_concat_cond_re = shift;
2681     my $line_concat = shift;
2682     my @array = (@$array);
2683
2684     return sub {
2685         my $saved_line = "";
2686         $_ = "";
2687         while (defined($_ = shift @array)) {
2688             s|\R$||;
2689             if (defined $line_concat) {
2690                 $_ = $line_concat->($saved_line, $_);
2691                 $saved_line = "";
2692             }
2693             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2694                 $saved_line = $_;
2695                 next;
2696             }
2697             return $_;
2698         }
2699         die "input text ending with continuation line\n" if $_;
2700         return undef;
2701     }
2702 }
2703
2704 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2705 # $lineiterator is a CODEref that delivers one line at a time.
2706 # All following arguments are regex/CODEref pairs, where the regexp detects a
2707 # line and the CODEref does something with the result of the regexp.
2708 sub collect_information {
2709     my $lineiterator = shift;
2710     my %collectors = @_;
2711
2712     while(defined($_ = $lineiterator->())) {
2713         s|\R$||;
2714         my $found = 0;
2715         if ($collectors{"BEFORE"}) {
2716             $collectors{"BEFORE"}->($_);
2717         }
2718         foreach my $re (keys %collectors) {
2719             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2720                 $collectors{$re}->($lineiterator);
2721                 $found = 1;
2722             };
2723         }
2724         if ($collectors{"OTHERWISE"}) {
2725             $collectors{"OTHERWISE"}->($lineiterator, $_)
2726                 unless $found || !defined $collectors{"OTHERWISE"};
2727         }
2728         if ($collectors{"AFTER"}) {
2729             $collectors{"AFTER"}->($_);
2730         }
2731     }
2732 }
2733
2734 # tokenize($line)
2735 # $line is a line of text to split up into tokens
2736 # returns a list of tokens
2737 #
2738 # Tokens are divided by spaces.  If the tokens include spaces, they
2739 # have to be quoted with single or double quotes.  Double quotes
2740 # inside a double quoted token must be escaped.  Escaping is done
2741 # with backslash.
2742 # Basically, the same quoting rules apply for " and ' as in any
2743 # Unix shell.
2744 sub tokenize {
2745     my $line = my $debug_line = shift;
2746     my @result = ();
2747
2748     while ($line =~ s|^\s+||, $line ne "") {
2749         my $token = "";
2750         while ($line ne "" && $line !~ m|^\s|) {
2751             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2752                 $token .= $1;
2753                 $line = $';
2754             } elsif ($line =~ m/^'([^']*)'/) {
2755                 $token .= $1;
2756                 $line = $';
2757             } elsif ($line =~ m/^(\S+)/) {
2758                 $token .= $1;
2759                 $line = $';
2760             }
2761         }
2762         push @result, $token;
2763     }
2764
2765     if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2766         print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2767         print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
2768     }
2769     return @result;
2770 }