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