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