Clean up references to FIPS
[openssl.git] / Configure
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3 # Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
4 #
5 # Licensed under the OpenSSL license (the "License").  You may not use
6 # this file except in compliance with the License.  You can obtain a copy
7 # in the file LICENSE in the source distribution or at
8 # https://www.openssl.org/source/license.html
9
10 ##  Configure -- OpenSSL source tree configuration script
11
12 require 5.10.0;
13 use strict;
14 use Config;
15 use File::Basename;
16 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
17 use File::Path qw/mkpath/;
18 use if $^O ne "VMS", 'File::Glob' => qw/glob/;
19
20 # see INSTALL for instructions.
21
22 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
23
24 # Options:
25 #
26 # --config      add the given configuration file, which will be read after
27 #               any "Configurations*" files that are found in the same
28 #               directory as this script.
29 # --prefix      prefix for the OpenSSL installation, which includes the
30 #               directories bin, lib, include, share/man, share/doc/openssl
31 #               This becomes the value of INSTALLTOP in Makefile
32 #               (Default: /usr/local)
33 # --openssldir  OpenSSL data area, such as openssl.cnf, certificates and keys.
34 #               If it's a relative directory, it will be added on the directory
35 #               given with --prefix.
36 #               This becomes the value of OPENSSLDIR in Makefile and in C.
37 #               (Default: PREFIX/ssl)
38 #
39 # --cross-compile-prefix Add specified prefix to binutils components.
40 #
41 # --api         One of 0.9.8, 1.0.0 or 1.1.0.  Do not compile support for
42 #               interfaces deprecated as of the specified OpenSSL version.
43 #
44 # no-hw-xxx     do not compile support for specific crypto hardware.
45 #               Generic OpenSSL-style methods relating to this support
46 #               are always compiled but return NULL if the hardware
47 #               support isn't compiled.
48 # no-hw         do not compile support for any crypto hardware.
49 # [no-]threads  [don't] try to create a library that is suitable for
50 #               multithreaded applications (default is "threads" if we
51 #               know how to do it)
52 # [no-]shared   [don't] try to create shared libraries when supported.
53 # [no-]pic      [don't] try to build position independent code when supported.
54 #               If disabled, it also disables shared and dynamic-engine.
55 # no-asm        do not use assembler
56 # no-dso        do not compile in any native shared-library methods. This
57 #               will ensure that all methods just return NULL.
58 # no-egd        do not compile support for the entropy-gathering daemon APIs
59 # [no-]zlib     [don't] compile support for zlib compression.
60 # zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
61 #               library and will be loaded in run-time by the OpenSSL library.
62 # sctp          include SCTP support
63 # enable-weak-ssl-ciphers
64 #               Enable weak ciphers that are disabled by default. This currently
65 #               only includes RC4 based ciphers.
66 # 386           generate 80386 code in assembly modules
67 # no-sse2       disables IA-32 SSE2 code in assembly modules, the above
68 #               mentioned '386' option implies this one
69 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
70 # -<xxx> +<xxx> compiler options are passed through
71 # -static       while -static is also a pass-through compiler option (and
72 #               as such is limited to environments where it's actually
73 #               meaningful), it triggers a number configuration options,
74 #               namely no-dso, no-pic, no-shared and no-threads. It is
75 #               argued that the only reason to produce statically linked
76 #               binaries (and in context it means executables linked with
77 #               -static flag, and not just executables linked with static
78 #               libcrypto.a) is to eliminate dependency on specific run-time,
79 #               a.k.a. libc version. The mentioned config options are meant
80 #               to achieve just that. Unfortunately on Linux it's impossible
81 #               to eliminate the dependency completely for openssl executable
82 #               because of getaddrinfo and gethostbyname calls, which can
83 #               invoke dynamically loadable library facility anyway to meet
84 #               the lookup requests. For this reason on Linux statically
85 #               linked openssl executable has rather debugging value than
86 #               production quality.
87 #
88 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
89 #               provided to stack calls. Generates unique stack functions for
90 #               each possible stack type.
91 # BN_LLONG      use the type 'long long' in crypto/bn/bn.h
92 # RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
93 # Following are set automatically by this script
94 #
95 # MD5_ASM       use some extra md5 assembler,
96 # SHA1_ASM      use some extra sha1 assembler, must define L_ENDIAN for x86
97 # RMD160_ASM    use some extra ripemd160 assembler,
98 # SHA256_ASM    sha256_block is implemented in assembler
99 # SHA512_ASM    sha512_block is implemented in assembler
100 # AES_ASM       AES_[en|de]crypt is implemented in assembler
101
102 # Minimum warning options... any contributions to OpenSSL should at least get
103 # past these.
104
105 # DEBUG_UNUSED enables __owur (warn unused result) checks.
106 # -DPEDANTIC complements -pedantic and is meant to mask code that
107 # is not strictly standard-compliant and/or implementation-specific,
108 # e.g. inline assembly, disregards to alignment requirements, such
109 # that -pedantic would complain about. Incidentally -DPEDANTIC has
110 # to be used even in sanitized builds, because sanitizer too is
111 # supposed to and does take notice of non-standard behaviour. Then
112 # -pedantic with pre-C9x compiler would also complain about 'long
113 # long' not being supported. As 64-bit algorithms are common now,
114 # it grew impossible to resolve this without sizeable additional
115 # code, so we just tell compiler to be pedantic about everything
116 # but 'long long' type.
117
118 my $gcc_devteam_warn = "-DDEBUG_UNUSED"
119         . " -Wswitch"
120         . " -DPEDANTIC -pedantic -Wno-long-long"
121         . " -Wall"
122         . " -Wsign-compare"
123         . " -Wmissing-prototypes"
124         . " -Wshadow"
125         . " -Wformat"
126         . " -Wtype-limits"
127         . " -Wundef"
128         . " -Werror"
129         ;
130
131 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
132 # TODO(openssl-team): fix problems and investigate if (at least) the
133 # following warnings can also be enabled:
134 #       -Wcast-align
135 #       -Wunreachable-code -- no, too ugly/compiler-specific
136 #       -Wlanguage-extension-token -- no, we use asm()
137 #       -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
138 #       -Wextended-offsetof -- no, needed in CMS ASN1 code
139 my $clang_devteam_warn = ""
140         . " -Qunused-arguments"
141         . " -Wextra"
142         . " -Wswitch -Wswitch-default"
143         . " -Wno-unused-parameter"
144         . " -Wno-parentheses-equality"
145         . " -Wno-missing-field-initializers"
146         . " -Wno-language-extension-token"
147         . " -Wno-extended-offsetof"
148         . " -Wconditional-uninitialized"
149         . " -Wincompatible-pointer-types-discards-qualifiers"
150         . " -Wmissing-variable-declarations"
151         . " -Wundef"
152         ;
153
154 # This adds backtrace information to the memory leak info.  Is only used
155 # when crypto-mdebug-backtrace is enabled.
156 my $memleak_devteam_backtrace = "-rdynamic";
157
158 my $strict_warnings = 0;
159
160 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
161 # which would cover all BSD flavors. -pthread applies to them all,
162 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
163 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
164 # which has to be accompanied by explicit -D_THREAD_SAFE and
165 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
166 # seems to be sufficient?
167 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
168
169 #
170 # API compatibility name to version number mapping.
171 #
172 my $maxapi = "1.1.0";           # API for "no-deprecated" builds
173 my $apitable = {
174     "1.1.0" => "0x10100000L",
175     "1.0.0" => "0x10000000L",
176     "0.9.8" => "0x00908000L",
177 };
178
179 our %table = ();
180 our %config = ();
181 our %withargs = ();
182
183 # Forward declarations ###############################################
184
185 # read_config(filename)
186 #
187 # Reads a configuration file and populates %table with the contents
188 # (which the configuration file places in %targets).
189 sub read_config;
190
191 # resolve_config(target)
192 #
193 # Resolves all the late evaluations, inheritances and so on for the
194 # chosen target and any target it inherits from.
195 sub resolve_config;
196
197
198 # Information collection #############################################
199
200 # Unified build supports separate build dir
201 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
202 my $blddir = catdir(absolutedir("."));         # catdir ensures local syntax
203 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
204
205 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
206
207 $config{sourcedir} = abs2rel($srcdir);
208 $config{builddir} = abs2rel($blddir);
209
210 # Collect reconfiguration information if needed
211 my @argvcopy=@ARGV;
212
213 if (grep /^reconf(igure)?$/, @argvcopy) {
214     if (-f "./configdata.pm") {
215         my $file = "./configdata.pm";
216         unless (my $return = do $file) {
217             die "couldn't parse $file: $@" if $@;
218             die "couldn't do $file: $!"    unless defined $return;
219             die "couldn't run $file"       unless $return;
220         }
221
222         @argvcopy = defined($configdata::config{perlargv}) ?
223             @{$configdata::config{perlargv}} : ();
224         die "Incorrect data to reconfigure, please do a normal configuration\n"
225             if (grep(/^reconf/,@argvcopy));
226         $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
227             if defined($configdata::config{cross_compile_prefix});
228         $ENV{CC} = $configdata::config{cc}
229             if defined($configdata::config{cc});
230         $ENV{CXX} = $configdata::config{cxx}
231             if defined($configdata::config{cxx});
232         $ENV{BUILDFILE} = $configdata::config{build_file}
233             if defined($configdata::config{build_file});
234         $ENV{$local_config_envname} = $configdata::config{local_config_dir}
235             if defined($configdata::config{local_config_dir});
236
237         print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
238         print "    CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
239             if $ENV{CROSS_COMPILE};
240         print "    CC = ",$ENV{CC},"\n" if $ENV{CC};
241         print "    CXX = ",$ENV{CXX},"\n" if $ENV{CXX};
242         print "    BUILDFILE = ",$ENV{BUILDFILE},"\n" if $ENV{BUILDFILE};
243         print "    $local_config_envname = ",$ENV{$local_config_envname},"\n"
244             if $ENV{$local_config_envname};
245     } else {
246         die "Insufficient data to reconfigure, please do a normal configuration\n";
247     }
248 }
249
250 $config{perlargv} = [ @argvcopy ];
251
252 # Collect version numbers
253 $config{version} = "unknown";
254 $config{version_num} = "unknown";
255 $config{shlib_version_number} = "unknown";
256 $config{shlib_version_history} = "unknown";
257
258 collect_information(
259     collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
260     qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
261     qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/      => sub { $config{version_num}=$1 },
262     qr/SHLIB_VERSION_NUMBER *"([^"]+)"/      => sub { $config{shlib_version_number}=$1 },
263     qr/SHLIB_VERSION_HISTORY *"([^"]*)"/     => sub { $config{shlib_version_history}=$1 }
264     );
265 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
266
267 ($config{major}, $config{minor})
268     = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
269 ($config{shlib_major}, $config{shlib_minor})
270     = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
271 die "erroneous version information in opensslv.h: ",
272     "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
273     if ($config{major} eq "" || $config{minor} eq ""
274         || $config{shlib_major} eq "" ||  $config{shlib_minor} eq "");
275
276 # Collect target configurations
277
278 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
279 foreach (sort glob($pattern)) {
280     &read_config($_);
281 }
282
283 if (defined $ENV{$local_config_envname}) {
284     if ($^O eq 'VMS') {
285         # VMS environment variables are logical names,
286         # which can be used as is
287         $pattern = $local_config_envname . ':' . '*.conf';
288     } else {
289         $pattern = catfile($ENV{$local_config_envname}, '*.conf');
290     }
291
292     foreach (sort glob($pattern)) {
293         &read_config($_);
294     }
295 }
296
297
298 print "Configuring OpenSSL version $config{version} ($config{version_num})\n";
299
300 $config{prefix}="";
301 $config{openssldir}="";
302 $config{processor}="";
303 $config{libdir}="";
304 $config{cross_compile_prefix}="";
305 $config{baseaddr}="0xFB00000";
306 my $auto_threads=1;    # enable threads automatically? true by default
307 my $default_ranlib;
308
309 # Top level directories to build
310 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
311 # crypto/ subdirectories to build
312 $config{sdirs} = [
313     "objects",
314     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash",
315     "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "chacha", "modes",
316     "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
317     "buffer", "bio", "stack", "lhash", "rand", "err",
318     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
319     "cms", "ts", "srp", "cmac", "ct", "async", "kdf"
320     ];
321 # test/ subdirectories to build
322 $config{tdirs} = [ "ossl_shim" ];
323
324 # Known TLS and DTLS protocols
325 my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
326 my @dtls = qw(dtls1 dtls1_2);
327
328 # Explicitly known options that are possible to disable.  They can
329 # be regexps, and will be used like this: /^no-${option}$/
330 # For developers: keep it sorted alphabetically
331
332 my @disablables = (
333     "afalgeng",
334     "aria",
335     "asan",
336     "asm",
337     "async",
338     "autoalginit",
339     "autoerrinit",
340     "bf",
341     "blake2",
342     "camellia",
343     "capieng",
344     "cast",
345     "chacha",
346     "cmac",
347     "cms",
348     "comp",
349     "crypto-mdebug",
350     "crypto-mdebug-backtrace",
351     "ct",
352     "deprecated",
353     "des",
354     "dgram",
355     "dh",
356     "dsa",
357     "dso",
358     "dtls",
359     "dynamic-engine",
360     "ec",
361     "ec2m",
362     "ecdh",
363     "ecdsa",
364     "ec_nistp_64_gcc_128",
365     "egd",
366     "engine",
367     "err",
368     "external-tests",
369     "filenames",
370     "fuzz-libfuzzer",
371     "fuzz-afl",
372     "gost",
373     "heartbeats",
374     "hw(-.+)?",
375     "idea",
376     "makedepend",
377     "md2",
378     "md4",
379     "mdc2",
380     "msan",
381     "multiblock",
382     "nextprotoneg",
383     "ocb",
384     "ocsp",
385     "pic",
386     "poly1305",
387     "posix-io",
388     "psk",
389     "rc2",
390     "rc4",
391     "rc5",
392     "rdrand",
393     "rfc3779",
394     "rmd160",
395     "scrypt",
396     "sctp",
397     "seed",
398     "shared",
399     "siphash",
400     "sock",
401     "srp",
402     "srtp",
403     "sse2",
404     "ssl",
405     "ssl-trace",
406     "static-engine",
407     "stdio",
408     "tests",
409     "threads",
410     "tls",
411     "ts",
412     "ubsan",
413     "ui",
414     "unit-test",
415     "whirlpool",
416     "weak-ssl-ciphers",
417     "zlib",
418     "zlib-dynamic",
419     );
420 foreach my $proto ((@tls, @dtls))
421         {
422         push(@disablables, $proto);
423         push(@disablables, "$proto-method");
424         }
425
426 my %deprecated_disablables = (
427     "ssl2" => undef,
428     "buf-freelists" => undef,
429     "ripemd" => "rmd160"
430     );
431
432 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
433
434 our %disabled = ( # "what"         => "comment"
435                   "aria"                => "default",
436                   "asan"                => "default",
437                   "crypto-mdebug"       => "default",
438                   "crypto-mdebug-backtrace" => "default",
439                   "ec_nistp_64_gcc_128" => "default",
440                   "egd"                 => "default",
441                   "external-tests"      => "default",
442                   "fuzz-libfuzzer"      => "default",
443                   "fuzz-afl"            => "default",
444                   "heartbeats"          => "default",
445                   "md2"                 => "default",
446                   "msan"                => "default",
447                   "rc5"                 => "default",
448                   "sctp"                => "default",
449                   "ssl-trace"           => "default",
450                   "ssl3"                => "default",
451                   "ssl3-method"         => "default",
452                   "ubsan"               => "default",
453           #TODO(TLS1.3): Temporarily disabled while this is a WIP
454                   "tls1_3"              => "default",
455                   "unit-test"           => "default",
456                   "weak-ssl-ciphers"    => "default",
457                   "zlib"                => "default",
458                   "zlib-dynamic"        => "default",
459                 );
460
461 # Note: => pair form used for aesthetics, not to truly make a hash table
462 my @disable_cascades = (
463     # "what"            => [ "cascade", ... ]
464     sub { $config{processor} eq "386" }
465                         => [ "sse2" ],
466     "ssl"               => [ "ssl3" ],
467     "ssl3-method"       => [ "ssl3" ],
468     "zlib"              => [ "zlib-dynamic" ],
469     "des"               => [ "mdc2" ],
470     "ec"                => [ "ecdsa", "ecdh" ],
471
472     "dgram"             => [ "dtls", "sctp" ],
473     "sock"              => [ "dgram" ],
474     "dtls"              => [ @dtls ],
475     sub { 0 == scalar grep { !$disabled{$_} } @dtls }
476                         => [ "dtls" ],
477
478     # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
479     "md5"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
480     "sha"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
481
482     # Additionally, SSL 3.0 requires either RSA or DSA+DH
483     sub { $disabled{rsa}
484           && ($disabled{dsa} || $disabled{dh}); }
485                         => [ "ssl" ],
486
487     # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
488     # or ECDSA + ECDH.  (D)TLS 1.2 has this requirement as well.
489     # (XXX: We don't support PSK-only builds).
490     sub { $disabled{rsa}
491           && ($disabled{dsa} || $disabled{dh})
492           && ($disabled{ecdsa} || $disabled{ecdh}); }
493                         => [ "tls1", "tls1_1", "tls1_2", "tls1_3",
494                              "dtls1", "dtls1_2" ],
495
496     "tls"               => [ @tls ],
497     sub { 0 == scalar grep { !$disabled{$_} } @tls }
498                         => [ "tls" ],
499
500     # SRP and HEARTBEATS require TLSEXT
501     "tlsext"            => [ "srp", "heartbeats" ],
502
503     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
504
505     # Without DSO, we can't load dynamic engines, so don't build them dynamic
506     "dso"               => [ "dynamic-engine" ],
507
508     # Without position independent code, there can be no shared libraries or DSOs
509     "pic"               => [ "shared" ],
510     "shared"            => [ "dynamic-engine" ],
511     "engine"            => [ "afalgeng" ],
512
513     # no-autoalginit is only useful when building non-shared
514     "autoalginit"       => [ "shared", "apps" ],
515
516     "stdio"             => [ "apps", "capieng" ],
517     "apps"              => [ "tests" ],
518     "comp"              => [ "zlib" ],
519     "ec"                => [ "tls1_3" ],
520     sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
521
522     sub { !$disabled{"msan"} } => [ "asm" ],
523     );
524
525 # Avoid protocol support holes.  Also disable all versions below N, if version
526 # N is disabled while N+1 is enabled.
527 #
528 my @list = (reverse @tls);
529 while ((my $first, my $second) = (shift @list, shift @list)) {
530     last unless @list;
531     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
532                               => [ @list ] );
533     unshift @list, $second;
534 }
535 my @list = (reverse @dtls);
536 while ((my $first, my $second) = (shift @list, shift @list)) {
537     last unless @list;
538     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
539                               => [ @list ] );
540     unshift @list, $second;
541 }
542
543 # Explicit "no-..." options will be collected in %disabled along with the defaults.
544 # To remove something from %disabled, use "enable-foo".
545 # For symmetry, "disable-foo" is a synonym for "no-foo".
546
547 my $no_sse2=0;
548
549 &usage if ($#ARGV < 0);
550
551 my $user_cflags="";
552 my @user_defines=();
553 $config{openssl_api_defines}=[];
554 $config{openssl_algorithm_defines}=[];
555 $config{openssl_thread_defines}=[];
556 $config{openssl_sys_defines}=[];
557 $config{openssl_other_defines}=[];
558 my $libs="";
559 my $target="";
560 $config{options}="";
561 $config{build_type} = "release";
562
563 my %unsupported_options = ();
564 my %deprecated_options = ();
565 while (@argvcopy)
566         {
567         $_ = shift @argvcopy;
568         # VMS is a case insensitive environment, and depending on settings
569         # out of our control, we may receive options uppercased.  Let's
570         # downcase at least the part before any equal sign.
571         if ($^O eq "VMS")
572                 {
573                 s/^([^=]*)/lc($1)/e;
574                 }
575         s /^-no-/no-/; # some people just can't read the instructions
576
577         # rewrite some options in "enable-..." form
578         s /^-?-?shared$/enable-shared/;
579         s /^sctp$/enable-sctp/;
580         s /^threads$/enable-threads/;
581         s /^zlib$/enable-zlib/;
582         s /^zlib-dynamic$/enable-zlib-dynamic/;
583
584         if (/^(no|disable|enable)-(.+)$/)
585                 {
586                 my $word = $2;
587                 if (!exists $deprecated_disablables{$word}
588                         && !grep { $word =~ /^${_}$/ } @disablables)
589                         {
590                         $unsupported_options{$_} = 1;
591                         next;
592                         }
593                 }
594         if (/^no-(.+)$/ || /^disable-(.+)$/)
595                 {
596                 foreach my $proto ((@tls, @dtls))
597                         {
598                         if ($1 eq "$proto-method")
599                                 {
600                                 $disabled{"$proto"} = "option($proto-method)";
601                                 last;
602                                 }
603                         }
604                 if ($1 eq "dtls")
605                         {
606                         foreach my $proto (@dtls)
607                                 {
608                                 $disabled{$proto} = "option(dtls)";
609                                 }
610                         $disabled{"dtls"} = "option(dtls)";
611                         }
612                 elsif ($1 eq "ssl")
613                         {
614                         # Last one of its kind
615                         $disabled{"ssl3"} = "option(ssl)";
616                         }
617                 elsif ($1 eq "tls")
618                         {
619                         # XXX: Tests will fail if all SSL/TLS
620                         # protocols are disabled.
621                         foreach my $proto (@tls)
622                                 {
623                                 $disabled{$proto} = "option(tls)";
624                                 }
625                         }
626                 elsif ($1 eq "static-engine")
627                         {
628                         delete $disabled{"dynamic-engine"};
629                         }
630                 elsif ($1 eq "dynamic-engine")
631                         {
632                         $disabled{"dynamic-engine"} = "option";
633                         }
634                 elsif (exists $deprecated_disablables{$1})
635                         {
636                         $deprecated_options{$_} = 1;
637                         if (defined $deprecated_disablables{$1})
638                                 {
639                                 $disabled{$deprecated_disablables{$1}} = "option";
640                                 }
641                         }
642                 else
643                         {
644                         $disabled{$1} = "option";
645                         }
646                 # No longer an automatic choice
647                 $auto_threads = 0 if ($1 eq "threads");
648                 }
649         elsif (/^enable-(.+)$/)
650                 {
651                 if ($1 eq "static-engine")
652                         {
653                         $disabled{"dynamic-engine"} = "option";
654                         }
655                 elsif ($1 eq "dynamic-engine")
656                         {
657                         delete $disabled{"dynamic-engine"};
658                         }
659                 elsif ($1 eq "zlib-dynamic")
660                         {
661                         delete $disabled{"zlib"};
662                         }
663                 my $algo = $1;
664                 delete $disabled{$algo};
665
666                 # No longer an automatic choice
667                 $auto_threads = 0 if ($1 eq "threads");
668                 }
669         elsif (/^--strict-warnings$/)
670                 {
671                 $strict_warnings = 1;
672                 }
673         elsif (/^--debug$/)
674                 {
675                 $config{build_type} = "debug";
676                 }
677         elsif (/^--release$/)
678                 {
679                 $config{build_type} = "release";
680                 }
681         elsif (/^386$/)
682                 { $config{processor}=386; }
683         elsif (/^fips$/)
684                 {
685                 die "FIPS mode not supported\n";
686                 }
687         elsif (/^rsaref$/)
688                 {
689                 # No RSAref support any more since it's not needed.
690                 # The check for the option is there so scripts aren't
691                 # broken
692                 }
693         elsif (/^nofipscanistercheck$/)
694                 {
695                 die "FIPS mode not supported\n";
696                 }
697         elsif (/^[-+]/)
698                 {
699                 if (/^--prefix=(.*)$/)
700                         {
701                         $config{prefix}=$1;
702                         die "Directory given with --prefix MUST be absolute\n"
703                                 unless file_name_is_absolute($config{prefix});
704                         }
705                 elsif (/^--api=(.*)$/)
706                         {
707                         $config{api}=$1;
708                         }
709                 elsif (/^--libdir=(.*)$/)
710                         {
711                         $config{libdir}=$1;
712                         }
713                 elsif (/^--openssldir=(.*)$/)
714                         {
715                         $config{openssldir}=$1;
716                         }
717                 elsif (/^--with-zlib-lib=(.*)$/)
718                         {
719                         $withargs{zlib_lib}=$1;
720                         }
721                 elsif (/^--with-zlib-include=(.*)$/)
722                         {
723                         $withargs{zlib_include}=$1;
724                         }
725                 elsif (/^--with-fuzzer-lib=(.*)$/)
726                         {
727                         $withargs{fuzzer_lib}=$1;
728                         }
729                 elsif (/^--with-fuzzer-include=(.*)$/)
730                         {
731                         $withargs{fuzzer_include}=$1;
732                         }
733                 elsif (/^--with-baseaddr=(.*)$/)
734                         {
735                         $config{baseaddr}="$1";
736                         }
737                 elsif (/^--cross-compile-prefix=(.*)$/)
738                         {
739                         $config{cross_compile_prefix}=$1;
740                         }
741                 elsif (/^--config=(.*)$/)
742                         {
743                         read_config $1;
744                         }
745                 elsif (/^-[lL](.*)$/ or /^-Wl,/)
746                         {
747                         $libs.=$_." ";
748                         }
749                 elsif (/^-rpath$/ or /^-R$/)
750                         # -rpath is the OSF1 rpath flag
751                         # -R is the old Solaris rpath flag
752                         {
753                         my $rpath = shift(@argvcopy) || "";
754                         $rpath .= " " if $rpath ne "";
755                         $libs.=$_." ".$rpath;
756                         }
757                 elsif (/^-static$/)
758                         {
759                         $libs.=$_." ";
760                         $disabled{"dso"} = "forced";
761                         $disabled{"pic"} = "forced";
762                         $disabled{"shared"} = "forced";
763                         $disabled{"threads"} = "forced";
764                         }
765                 elsif (/^-D(.*)$/)
766                         {
767                         push @user_defines, $1;
768                         }
769                 else    # common if (/^[-+]/), just pass down...
770                         {
771                         $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
772                         $user_cflags.=" ".$_;
773                         }
774                 }
775         else
776                 {
777                 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
778                 $target=$_;
779                 }
780         unless ($_ eq $target || /^no-/ || /^disable-/)
781                 {
782                 # "no-..." follows later after implied disactivations
783                 # have been derived.  (Don't take this too seriously,
784                 # we really only write OPTIONS to the Makefile out of
785                 # nostalgia.)
786
787                 if ($config{options} eq "")
788                         { $config{options} = $_; }
789                 else
790                         { $config{options} .= " ".$_; }
791                 }
792
793         if (defined($config{api}) && !exists $apitable->{$config{api}}) {
794                 die "***** Unsupported api compatibility level: $config{api}\n",
795         }
796
797         if (keys %deprecated_options)
798                 {
799                 warn "***** Deprecated options: ",
800                         join(", ", keys %deprecated_options), "\n";
801                 }
802         if (keys %unsupported_options)
803                 {
804                 die "***** Unsupported options: ",
805                         join(", ", keys %unsupported_options), "\n";
806                 }
807         }
808
809 if ($libs =~ /(^|\s)-Wl,-rpath,/
810     && !$disabled{shared}
811     && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
812     die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
813         "***** any of asan, msan or ubsan\n";
814 }
815
816 my @tocheckfor = (keys %disabled);
817 while (@tocheckfor) {
818     my %new_tocheckfor = ();
819     my @cascade_copy = (@disable_cascades);
820     while (@cascade_copy) {
821         my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
822         if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
823             foreach(grep { !defined($disabled{$_}) } @$descendents) {
824                 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
825             }
826         }
827     }
828     @tocheckfor = (keys %new_tocheckfor);
829 }
830
831 our $die = sub { die @_; };
832 if ($target eq "TABLE") {
833     local $die = sub { warn @_; };
834     foreach (sort keys %table) {
835         print_table_entry($_, "TABLE");
836     }
837     exit 0;
838 }
839
840 if ($target eq "LIST") {
841     foreach (sort keys %table) {
842         print $_,"\n" unless $table{$_}->{template};
843     }
844     exit 0;
845 }
846
847 if ($target eq "HASH") {
848     local $die = sub { warn @_; };
849     print "%table = (\n";
850     foreach (sort keys %table) {
851         print_table_entry($_, "HASH");
852     }
853     exit 0;
854 }
855
856 # Backward compatibility?
857 if ($target =~ m/^CygWin32(-.*)$/) {
858     $target = "Cygwin".$1;
859 }
860
861 foreach (sort (keys %disabled))
862         {
863         $config{options} .= " no-$_";
864
865         printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
866
867         if (/^dso$/)
868                 { }
869         elsif (/^threads$/)
870                 { }
871         elsif (/^shared$/)
872                 { }
873         elsif (/^pic$/)
874                 { }
875         elsif (/^zlib$/)
876                 { }
877         elsif (/^dynamic-engine$/)
878                 { }
879         elsif (/^makedepend$/)
880                 { }
881         elsif (/^zlib-dynamic$/)
882                 { }
883         elsif (/^sse2$/)
884                 { $no_sse2 = 1; }
885         elsif (/^engine$/)
886                 {
887                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
888                 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
889                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
890                 print " OPENSSL_NO_ENGINE (skip engines)";
891                 }
892         else
893                 {
894                 my ($WHAT, $what);
895
896                 ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/;
897
898                 # Fix up C macro end names
899                 $WHAT = "RMD160" if $what eq "ripemd";
900
901                 # fix-up crypto/directory name(s)
902                 $what = "ripemd" if $what eq "rmd160";
903                 $what = "whrlpool" if $what eq "whirlpool";
904
905                 if ($what ne "async" && $what ne "err"
906                     && grep { $_ eq $what } @{$config{sdirs}})
907                         {
908                         push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT";
909                         @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}};
910
911                         print " OPENSSL_NO_$WHAT (skip dir)";
912                         }
913                 else
914                         {
915                         push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
916                         print " OPENSSL_NO_$WHAT";
917
918                         if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
919                         }
920                 }
921
922         print "\n";
923         }
924
925 print "Configuring for $target\n";
926 # Support for legacy targets having a name starting with 'debug-'
927 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
928 if ($d) {
929     $config{build_type} = "debug";
930
931     # If we do not find debug-foo in the table, the target is set to foo.
932     if (!$table{$target}) {
933         $target = $t;
934     }
935 }
936 $config{target} = $target;
937 my %target = resolve_config($target);
938
939 &usage if (!%target || $target{template});
940
941 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
942 $config{conf_files} = [ sort keys %conf_files ];
943 %target = ( %{$table{DEFAULTS}}, %target );
944
945 $target{cxxflags}=$target{cflags} unless defined $target{cxxflags};
946 $target{exe_extension}="";
947 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
948                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
949 $target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
950
951 ($target{shared_extension_simple}=$target{shared_extension})
952     =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||;
953 $target{dso_extension}=$target{shared_extension_simple};
954 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
955     if ($config{target} =~ /^(?:Cygwin|mingw)/);
956
957
958 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
959     if $config{cross_compile_prefix} eq "";
960
961 # Allow overriding the names of some tools.  USE WITH CARE
962 # Note: only Unix cares about HASHBANGPERL...  that explains
963 # the default string.
964 $config{perl} =    ($^O ne "VMS" ? $^X : "perl");
965 $config{hashbangperl} =
966     $ENV{'HASHBANGPERL'}           || $ENV{'PERL'}     || "/usr/bin/env perl";
967 $target{cc} =      $ENV{'CC'}      || $target{cc}      || "cc";
968 $target{cxx} =     $ENV{'CXX'}     || $target{cxx}     || "c++";
969 $target{ranlib} =  $ENV{'RANLIB'}  || $target{ranlib}  ||
970                    (which("$config{cross_compile_prefix}ranlib") ?
971                           "\$(CROSS_COMPILE)ranlib" : "true");
972 $target{ar} =      $ENV{'AR'}      || $target{ar}      || "ar";
973 $target{nm} =      $ENV{'NM'}      || $target{nm}      || "nm";
974 $target{rc} =
975     $ENV{'RC'}  || $ENV{'WINDRES'} || $target{rc}      || "windres";
976
977 # Allow overriding the build file name
978 $target{build_file} = $ENV{BUILDFILE} || $target{build_file} || "Makefile";
979
980 # Cache information necessary for reconfiguration
981 $config{cc} = $target{cc};
982 $config{cxx} = $target{cxx};
983 $config{build_file} = $target{build_file};
984
985 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
986 # or release_ attributes.
987 # Do it in such a way that no spurious space is appended (hence the grep).
988 $config{defines} = [];
989 $config{cflags} = "";
990 $config{cxxflags} = "";
991 $config{ex_libs} = "";
992 $config{shared_ldflag} = "";
993
994 # Make sure build_scheme is consistent.
995 $target{build_scheme} = [ $target{build_scheme} ]
996     if ref($target{build_scheme}) ne "ARRAY";
997
998 my ($builder, $builder_platform, @builder_opts) =
999     @{$target{build_scheme}};
1000
1001 push @{$config{defines}}, "NDEBUG"    if $config{build_type} eq "release";
1002
1003 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
1004         {
1005         $config{cflags} .= " -mno-cygwin";
1006         $config{shared_ldflag} .= " -mno-cygwin";
1007         }
1008
1009 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
1010         # minimally required architecture flags for assembly modules
1011         $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
1012         $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
1013 }
1014
1015 my $no_shared_warn=0;
1016 my $no_user_cflags=0;
1017 my $no_user_defines=0;
1018
1019 # The DSO code currently always implements all functions so that no
1020 # applications will have to worry about that from a compilation point
1021 # of view. However, the "method"s may return zero unless that platform
1022 # has support compiled in for them. Currently each method is enabled
1023 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
1024 # string entry into using the following logic;
1025 if (!$disabled{dso} && $target{dso_scheme} ne "")
1026         {
1027         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
1028         if ($target{dso_scheme} eq "DLFCN")
1029                 {
1030                 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
1031                 }
1032         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
1033                 {
1034                 unshift @{$config{defines}}, "DSO_DLFCN";
1035                 }
1036         else
1037                 {
1038                 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
1039                 }
1040         }
1041
1042 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
1043
1044 # If threads aren't disabled, check how possible they are
1045 unless ($disabled{threads}) {
1046     if ($auto_threads) {
1047         # Enabled by default, disable it forcibly if unavailable
1048         if ($target{thread_scheme} eq "(unknown)") {
1049             $disabled{threads} = "unavailable";
1050         }
1051     } else {
1052         # The user chose to enable threads explicitly, let's see
1053         # if there's a chance that's possible
1054         if ($target{thread_scheme} eq "(unknown)") {
1055             # If the user asked for "threads" and we don't have internal
1056             # knowledge how to do it, [s]he is expected to provide any
1057             # system-dependent compiler options that are necessary.  We
1058             # can't truly check that the given options are correct, but
1059             # we expect the user to know what [s]He is doing.
1060             if ($no_user_cflags && $no_user_defines) {
1061                 die "You asked for multi-threading support, but didn't\n"
1062                     ,"provide any system-specific compiler options\n";
1063             }
1064         }
1065     }
1066 }
1067
1068 # If threads still aren't disabled, add a C macro to ensure the source
1069 # code knows about it.  Any other flag is taken care of by the configs.
1070 unless($disabled{threads}) {
1071     foreach (("defines", "openssl_thread_defines")) {
1072         push @{$config{$_}}, "OPENSSL_THREADS";
1073     }
1074 }
1075
1076 # With "deprecated" disable all deprecated features.
1077 if (defined($disabled{"deprecated"})) {
1078         $config{api} = $maxapi;
1079 }
1080
1081 if ($target{shared_target} eq "")
1082         {
1083         $no_shared_warn = 1
1084             if (!$disabled{shared} || !$disabled{"dynamic-engine"});
1085         $disabled{shared} = "no-shared-target";
1086         $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1087             "no-shared-target";
1088         }
1089
1090 if ($disabled{"dynamic-engine"}) {
1091         push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1092         $config{dynamic_engines} = 0;
1093 } else {
1094         push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1095         $config{dynamic_engines} = 1;
1096 }
1097
1098 unless ($disabled{asan}) {
1099     $config{cflags} .= "-fsanitize=address ";
1100 }
1101
1102 unless ($disabled{ubsan}) {
1103     # -DPEDANTIC or -fnosanitize=alignment may also be required on some
1104     # platforms.
1105     $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
1106 }
1107
1108 unless ($disabled{msan}) {
1109   $config{cflags} .= "-fsanitize=memory ";
1110 }
1111
1112 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1113         && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1114     $config{cflags} .= "-fno-omit-frame-pointer -g ";
1115 }
1116 #
1117 # Platform fix-ups
1118 #
1119
1120 # This saves the build files from having to check
1121 if ($disabled{pic})
1122         {
1123         $target{shared_cflag} = $target{shared_ldflag} =
1124                 $target{shared_rcflag} = "";
1125         }
1126 else
1127         {
1128         push @{$config{defines}}, "OPENSSL_PIC";
1129         }
1130
1131 if ($target{sys_id} ne "")
1132         {
1133         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1134         }
1135
1136 unless ($disabled{asm}) {
1137     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1138     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1139
1140     # bn-586 is the only one implementing bn_*_part_words
1141     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1142     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1143
1144     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1145     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1146     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1147
1148     if ($target{sha1_asm_src}) {
1149         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1150         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1151         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1152     }
1153     if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
1154         push @{$config{defines}}, "RC4_ASM";
1155     }
1156     if ($target{md5_asm_src}) {
1157         push @{$config{defines}}, "MD5_ASM";
1158     }
1159     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1160     if ($target{rmd160_asm_src}) {
1161         push @{$config{defines}}, "RMD160_ASM";
1162     }
1163     if ($target{aes_asm_src}) {
1164         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1165         # aes-ctr.fake is not a real file, only indication that assembler
1166         # module implements AES_ctr32_encrypt...
1167         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1168         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1169         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1170         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1171         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1172         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1173     }
1174     if ($target{wp_asm_src} =~ /mmx/) {
1175         if ($config{processor} eq "386") {
1176             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1177         } elsif (!$disabled{"whirlpool"}) {
1178             push @{$config{defines}}, "WHIRLPOOL_ASM";
1179         }
1180     }
1181     if ($target{modes_asm_src} =~ /ghash-/) {
1182         push @{$config{defines}}, "GHASH_ASM";
1183     }
1184     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1185         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1186     }
1187     if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
1188         push @{$config{defines}}, "PADLOCK_ASM";
1189     }
1190     if ($target{poly1305_asm_src} ne "") {
1191         push @{$config{defines}}, "POLY1305_ASM";
1192     }
1193 }
1194
1195 my $ecc = $target{cc};
1196 if ($^O ne "VMS" && !$disabled{makedepend}) {
1197     # Is the compiler gcc or clang?  $ecc is used below to see if
1198     # error-checking can be turned on.
1199     my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1200     open(PIPE, "$ccpcc --version 2>&1 |");
1201     my $lines = 2;
1202     while ( <PIPE> ) {
1203         # Find the version number and save the major.
1204         m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
1205         my $compiler_major = $1;
1206         # We know that GNU C version 3 and up as well as all clang
1207         # versions support dependency generation
1208         $config{makedepprog} = $ccpcc
1209             if (/clang/ || (/gcc/ && $compiler_major >= 3));
1210         $ecc = "clang" if /clang/;
1211         $ecc = "gcc" if /gcc/;
1212         last if ($config{makedepprog} || !$lines--);
1213     }
1214     close(PIPE);
1215
1216     $config{makedepprog} = which('makedepend') unless $config{makedepprog};
1217     $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1218 }
1219
1220
1221
1222 # Deal with bn_ops ###################################################
1223
1224 $config{bn_ll}                  =0;
1225 $config{export_var_as_fn}       =0;
1226 my $def_int="unsigned int";
1227 $config{rc4_int}                =$def_int;
1228 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1229
1230 my $count = 0;
1231 foreach (sort split(/\s+/,$target{bn_ops})) {
1232     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1233     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1234     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1235     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1236     ($config{b64l},$config{b64},$config{b32})
1237         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1238     ($config{b64l},$config{b64},$config{b32})
1239         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1240     ($config{b64l},$config{b64},$config{b32})
1241         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1242 }
1243 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1244     if $count > 1;
1245
1246
1247 # Hack cflags for better warnings (dev option) #######################
1248
1249 # "Stringify" the C flags string.  This permits it to be made part of a string
1250 # and works as well on command lines.
1251 $config{cflags} =~ s/([\\\"])/\\$1/g;
1252
1253 if (defined($config{api})) {
1254     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1255     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1256     push @{$config{defines}}, $apiflag;
1257 }
1258
1259 if ($strict_warnings)
1260         {
1261         my $wopt;
1262         die "ERROR --strict-warnings requires gcc or clang"
1263             unless $ecc eq 'gcc' || $ecc eq 'clang';
1264         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1265                 {
1266                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1267                 }
1268         if ($ecc eq "clang")
1269                 {
1270                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1271                         {
1272                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1273                         }
1274                 }
1275         }
1276
1277 unless ($disabled{"crypto-mdebug-backtrace"})
1278         {
1279         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1280                 {
1281                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1282                 }
1283         if ($target =~ /^BSD-/)
1284                 {
1285                 $config{ex_libs} .= " -lexecinfo";
1286                 }
1287         }
1288
1289 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; $config{cxxflags}="$config{cxxflags}$user_cflags";}
1290 else                    { $no_user_cflags=1;  }
1291 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1292 else               { $no_user_defines=1;    }
1293
1294 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1295
1296 unless ($disabled{afalgeng}) {
1297     $config{afalgeng}="";
1298     if ($target =~ m/^linux/) {
1299         my $minver = 4*10000 + 1*100 + 0;
1300         if ($config{cross_compile_prefix} eq "") {
1301             my $verstr = `uname -r`;
1302             my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1303             ($mi2) = $mi2 =~ /(\d+)/;
1304             my $ver = $ma*10000 + $mi1*100 + $mi2;
1305             if ($ver < $minver) {
1306                 $disabled{afalgeng} = "too-old-kernel";
1307             } else {
1308                 push @{$config{engdirs}}, "afalg";
1309             }
1310         } else {
1311             $disabled{afalgeng} = "cross-compiling";
1312         }
1313     } else {
1314         $disabled{afalgeng}  = "not-linux";
1315     }
1316 }
1317
1318 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1319
1320 # If we use the unified build, collect information from build.info files
1321 my %unified_info = ();
1322
1323 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1324 if ($builder eq "unified") {
1325     use lib catdir(dirname(__FILE__),"util");
1326     use with_fallback qw(Text::Template);
1327
1328     sub cleandir {
1329         my $base = shift;
1330         my $dir = shift;
1331         my $relativeto = shift || ".";
1332
1333         $dir = catdir($base,$dir) unless isabsolute($dir);
1334
1335         # Make sure the directories we're building in exists
1336         mkpath($dir);
1337
1338         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1339         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1340         return $res;
1341     }
1342
1343     sub cleanfile {
1344         my $base = shift;
1345         my $file = shift;
1346         my $relativeto = shift || ".";
1347
1348         $file = catfile($base,$file) unless isabsolute($file);
1349
1350         my $d = dirname($file);
1351         my $f = basename($file);
1352
1353         # Make sure the directories we're building in exists
1354         mkpath($d);
1355
1356         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1357         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1358         return $res;
1359     }
1360
1361     # Store the name of the template file we will build the build file from
1362     # in %config.  This may be useful for the build file itself.
1363     my @build_file_template_names =
1364         ( $builder_platform."-".$target{build_file}.".tmpl",
1365           $target{build_file}.".tmpl" );
1366     my @build_file_templates = ();
1367
1368     # First, look in the user provided directory, if given
1369     if (defined $ENV{$local_config_envname}) {
1370         @build_file_templates =
1371             map {
1372                 if ($^O eq 'VMS') {
1373                     # VMS environment variables are logical names,
1374                     # which can be used as is
1375                     $local_config_envname . ':' . $_;
1376                 } else {
1377                     catfile($ENV{$local_config_envname}, $_);
1378                 }
1379             }
1380             @build_file_template_names;
1381     }
1382     # Then, look in our standard directory
1383     push @build_file_templates,
1384         ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1385           @build_file_template_names );
1386
1387     my $build_file_template;
1388     for $_ (@build_file_templates) {
1389         $build_file_template = $_;
1390         last if -f $build_file_template;
1391
1392         $build_file_template = undef;
1393     }
1394     if (!defined $build_file_template) {
1395         die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1396     }
1397     $config{build_file_templates}
1398       = [ $build_file_template,
1399           cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1400                     $blddir) ];
1401
1402     my @build_infos = ( [ ".", "build.info" ] );
1403     foreach (@{$config{dirs}}) {
1404         push @build_infos, [ $_, "build.info" ]
1405             if (-f catfile($srcdir, $_, "build.info"));
1406     }
1407     foreach (@{$config{sdirs}}) {
1408         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1409             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1410     }
1411     foreach (@{$config{engdirs}}) {
1412         push @build_infos, [ catdir("engines", $_), "build.info" ]
1413             if (-f catfile($srcdir, "engines", $_, "build.info"));
1414     }
1415     foreach (@{$config{tdirs}}) {
1416         push @build_infos, [ catdir("test", $_), "build.info" ]
1417             if (-f catfile($srcdir, "test", $_, "build.info"));
1418     }
1419
1420     $config{build_infos} = [ ];
1421
1422     foreach (@build_infos) {
1423         my $sourced = catdir($srcdir, $_->[0]);
1424         my $buildd = catdir($blddir, $_->[0]);
1425
1426         mkpath($buildd);
1427
1428         my $f = $_->[1];
1429         # The basic things we're trying to build
1430         my @programs = ();
1431         my @programs_install = ();
1432         my @libraries = ();
1433         my @libraries_install = ();
1434         my @engines = ();
1435         my @engines_install = ();
1436         my @scripts = ();
1437         my @scripts_install = ();
1438         my @extra = ();
1439         my @overrides = ();
1440         my @intermediates = ();
1441         my @rawlines = ();
1442
1443         my %ordinals = ();
1444         my %sources = ();
1445         my %shared_sources = ();
1446         my %includes = ();
1447         my %depends = ();
1448         my %renames = ();
1449         my %sharednames = ();
1450         my %generate = ();
1451
1452         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1453         my $template = Text::Template->new(TYPE => 'FILE',
1454                                            SOURCE => catfile($sourced, $f));
1455         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1456         my @text =
1457             split /^/m,
1458             $template->fill_in(HASH => { config => \%config,
1459                                          target => \%target,
1460                                          disabled => \%disabled,
1461                                          withargs => \%withargs,
1462                                          builddir => abs2rel($buildd, $blddir),
1463                                          sourcedir => abs2rel($sourced, $blddir),
1464                                          buildtop => abs2rel($blddir, $blddir),
1465                                          sourcetop => abs2rel($srcdir, $blddir) },
1466                                DELIMITERS => [ "{-", "-}" ]);
1467
1468         # The top item of this stack has the following values
1469         # -2 positive already run and we found ELSE (following ELSIF should fail)
1470         # -1 positive already run (skip until ENDIF)
1471         # 0 negatives so far (if we're at a condition, check it)
1472         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1473         # 2 positive ELSE (following ELSIF should fail)
1474         my @skip = ();
1475         collect_information(
1476             collect_from_array([ @text ],
1477                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1478                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1479             # Info we're looking for
1480             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1481             => sub {
1482                 if (! @skip || $skip[$#skip] > 0) {
1483                     push @skip, !! $1;
1484                 } else {
1485                     push @skip, -1;
1486                 }
1487             },
1488             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1489             => sub { die "ELSIF out of scope" if ! @skip;
1490                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1491                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1492                      $skip[$#skip] = !! $1
1493                          if $skip[$#skip] == 0; },
1494             qr/^\s*ELSE\s*$/
1495             => sub { die "ELSE out of scope" if ! @skip;
1496                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1497                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1498             qr/^\s*ENDIF\s*$/
1499             => sub { die "ENDIF out of scope" if ! @skip;
1500                      pop @skip; },
1501             qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1502             => sub {
1503                 if (!@skip || $skip[$#skip] > 0) {
1504                     my $install = $1;
1505                     my @x = tokenize($2);
1506                     push @programs, @x;
1507                     push @programs_install, @x unless $install;
1508                 }
1509             },
1510             qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1511             => sub {
1512                 if (!@skip || $skip[$#skip] > 0) {
1513                     my $install = $1;
1514                     my @x = tokenize($2);
1515                     push @libraries, @x;
1516                     push @libraries_install, @x unless $install;
1517                 }
1518             },
1519             qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1520             => sub {
1521                 if (!@skip || $skip[$#skip] > 0) {
1522                     my $install = $1;
1523                     my @x = tokenize($2);
1524                     push @engines, @x;
1525                     push @engines_install, @x unless $install;
1526                 }
1527             },
1528             qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1529             => sub {
1530                 if (!@skip || $skip[$#skip] > 0) {
1531                     my $install = $1;
1532                     my @x = tokenize($2);
1533                     push @scripts, @x;
1534                     push @scripts_install, @x unless $install;
1535                 }
1536             },
1537             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1538             => sub { push @extra, tokenize($1)
1539                          if !@skip || $skip[$#skip] > 0 },
1540             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1541             => sub { push @overrides, tokenize($1)
1542                          if !@skip || $skip[$#skip] > 0 },
1543
1544             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1545             => sub { push @{$ordinals{$1}}, tokenize($2)
1546                          if !@skip || $skip[$#skip] > 0 },
1547             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1548             => sub { push @{$sources{$1}}, tokenize($2)
1549                          if !@skip || $skip[$#skip] > 0 },
1550             qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1551             => sub { push @{$shared_sources{$1}}, tokenize($2)
1552                          if !@skip || $skip[$#skip] > 0 },
1553             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1554             => sub { push @{$includes{$1}}, tokenize($2)
1555                          if !@skip || $skip[$#skip] > 0 },
1556             qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
1557             => sub { push @{$depends{$1}}, tokenize($2)
1558                          if !@skip || $skip[$#skip] > 0 },
1559             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1560             => sub { push @{$generate{$1}}, $2
1561                          if !@skip || $skip[$#skip] > 0 },
1562             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1563             => sub { push @{$renames{$1}}, tokenize($2)
1564                          if !@skip || $skip[$#skip] > 0 },
1565             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1566             => sub { push @{$sharednames{$1}}, tokenize($2)
1567                          if !@skip || $skip[$#skip] > 0 },
1568             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1569             => sub {
1570                 my $lineiterator = shift;
1571                 my $target_kind = $1;
1572                 while (defined $lineiterator->()) {
1573                     s|\R$||;
1574                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1575                         die "ENDRAW doesn't match BEGINRAW"
1576                             if $1 ne $target_kind;
1577                         last;
1578                     }
1579                     next if @skip && $skip[$#skip] <= 0;
1580                     push @rawlines,  $_
1581                         if ($target_kind eq $target{build_file}
1582                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1583                 }
1584             },
1585             qr/^\s*(?:#.*)?$/ => sub { },
1586             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1587             "BEFORE" => sub {
1588                 if ($buildinfo_debug) {
1589                     print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1590                     print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1591                 }
1592             },
1593             "AFTER" => sub {
1594                 if ($buildinfo_debug) {
1595                     print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1596                 }
1597             },
1598             );
1599         die "runaway IF?" if (@skip);
1600
1601         foreach (keys %renames) {
1602             die "$_ renamed to more than one thing: "
1603                 ,join(" ", @{$renames{$_}}),"\n"
1604                 if scalar @{$renames{$_}} > 1;
1605             my $dest = cleanfile($buildd, $_, $blddir);
1606             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1607             die "$dest renamed to more than one thing: "
1608                 ,$unified_info{rename}->{$dest}, $to
1609                 unless !defined($unified_info{rename}->{$dest})
1610                 or $unified_info{rename}->{$dest} eq $to;
1611             $unified_info{rename}->{$dest} = $to;
1612         }
1613
1614         foreach (@programs) {
1615             my $program = cleanfile($buildd, $_, $blddir);
1616             if ($unified_info{rename}->{$program}) {
1617                 $program = $unified_info{rename}->{$program};
1618             }
1619             $unified_info{programs}->{$program} = 1;
1620         }
1621
1622         foreach (@programs_install) {
1623             my $program = cleanfile($buildd, $_, $blddir);
1624             if ($unified_info{rename}->{$program}) {
1625                 $program = $unified_info{rename}->{$program};
1626             }
1627             $unified_info{install}->{programs}->{$program} = 1;
1628         }
1629
1630         foreach (@libraries) {
1631             my $library = cleanfile($buildd, $_, $blddir);
1632             if ($unified_info{rename}->{$library}) {
1633                 $library = $unified_info{rename}->{$library};
1634             }
1635             $unified_info{libraries}->{$library} = 1;
1636         }
1637
1638         foreach (@libraries_install) {
1639             my $library = cleanfile($buildd, $_, $blddir);
1640             if ($unified_info{rename}->{$library}) {
1641                 $library = $unified_info{rename}->{$library};
1642             }
1643             $unified_info{install}->{libraries}->{$library} = 1;
1644         }
1645
1646         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1647 ENGINES can only be used if configured with 'dynamic-engine'.
1648 This is usually a fault in a build.info file.
1649 EOF
1650         foreach (@engines) {
1651             my $library = cleanfile($buildd, $_, $blddir);
1652             if ($unified_info{rename}->{$library}) {
1653                 $library = $unified_info{rename}->{$library};
1654             }
1655             $unified_info{engines}->{$library} = 1;
1656         }
1657
1658         foreach (@engines_install) {
1659             my $library = cleanfile($buildd, $_, $blddir);
1660             if ($unified_info{rename}->{$library}) {
1661                 $library = $unified_info{rename}->{$library};
1662             }
1663             $unified_info{install}->{engines}->{$library} = 1;
1664         }
1665
1666         foreach (@scripts) {
1667             my $script = cleanfile($buildd, $_, $blddir);
1668             if ($unified_info{rename}->{$script}) {
1669                 $script = $unified_info{rename}->{$script};
1670             }
1671             $unified_info{scripts}->{$script} = 1;
1672         }
1673
1674         foreach (@scripts_install) {
1675             my $script = cleanfile($buildd, $_, $blddir);
1676             if ($unified_info{rename}->{$script}) {
1677                 $script = $unified_info{rename}->{$script};
1678             }
1679             $unified_info{install}->{scripts}->{$script} = 1;
1680         }
1681
1682         foreach (@extra) {
1683             my $extra = cleanfile($buildd, $_, $blddir);
1684             $unified_info{extra}->{$extra} = 1;
1685         }
1686
1687         foreach (@overrides) {
1688             my $override = cleanfile($buildd, $_, $blddir);
1689             $unified_info{overrides}->{$override} = 1;
1690         }
1691
1692         push @{$unified_info{rawlines}}, @rawlines;
1693
1694         unless ($disabled{shared}) {
1695             # Check sharednames.
1696             foreach (keys %sharednames) {
1697                 my $dest = cleanfile($buildd, $_, $blddir);
1698                 if ($unified_info{rename}->{$dest}) {
1699                     $dest = $unified_info{rename}->{$dest};
1700                 }
1701                 die "shared_name for $dest with multiple values: "
1702                     ,join(" ", @{$sharednames{$_}}),"\n"
1703                     if scalar @{$sharednames{$_}} > 1;
1704                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1705                 die "shared_name found for a library $dest that isn't defined\n"
1706                     unless $unified_info{libraries}->{$dest};
1707                 die "shared_name for $dest with multiple values: "
1708                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1709                     unless !defined($unified_info{sharednames}->{$dest})
1710                     or $unified_info{sharednames}->{$dest} eq $to;
1711                 $unified_info{sharednames}->{$dest} = $to;
1712             }
1713
1714             # Additionally, we set up sharednames for libraries that don't
1715             # have any, as themselves.
1716             foreach (keys %{$unified_info{libraries}}) {
1717                 if (!defined $unified_info{sharednames}->{$_}) {
1718                     $unified_info{sharednames}->{$_} = $_
1719                 }
1720             }
1721         }
1722
1723         foreach (keys %ordinals) {
1724             my $dest = $_;
1725             my $ddest = cleanfile($buildd, $_, $blddir);
1726             if ($unified_info{rename}->{$ddest}) {
1727                 $ddest = $unified_info{rename}->{$ddest};
1728             }
1729             foreach (@{$ordinals{$dest}}) {
1730                 my %known_ordinals =
1731                     (
1732                      crypto =>
1733                      cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1734                      ssl =>
1735                      cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1736                     );
1737                 my $o = $known_ordinals{$_};
1738                 die "Ordinals for $ddest defined more than once\n"
1739                     if $unified_info{ordinals}->{$ddest};
1740                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1741             }
1742         }
1743
1744         foreach (keys %sources) {
1745             my $dest = $_;
1746             my $ddest = cleanfile($buildd, $_, $blddir);
1747             if ($unified_info{rename}->{$ddest}) {
1748                 $ddest = $unified_info{rename}->{$ddest};
1749             }
1750             foreach (@{$sources{$dest}}) {
1751                 my $s = cleanfile($sourced, $_, $blddir);
1752
1753                 # If it isn't in the source tree, we assume it's generated
1754                 # in the build tree
1755                 if (! -f $s) {
1756                     $s = cleanfile($buildd, $_, $blddir);
1757                 }
1758                 # We recognise C++, C and asm files
1759                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1760                     my $o = $_;
1761                     $o =~ s/\.[csS]$/.o/; # C and assembler
1762                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1763                     $o = cleanfile($buildd, $o, $blddir);
1764                     $unified_info{sources}->{$ddest}->{$o} = 1;
1765                     $unified_info{sources}->{$o}->{$s} = 1;
1766                 } else {
1767                     $unified_info{sources}->{$ddest}->{$s} = 1;
1768                 }
1769             }
1770         }
1771
1772         foreach (keys %shared_sources) {
1773             my $dest = $_;
1774             my $ddest = cleanfile($buildd, $_, $blddir);
1775             if ($unified_info{rename}->{$ddest}) {
1776                 $ddest = $unified_info{rename}->{$ddest};
1777             }
1778             foreach (@{$shared_sources{$dest}}) {
1779                 my $s = cleanfile($sourced, $_, $blddir);
1780
1781                 # If it isn't in the source tree, we assume it's generated
1782                 # in the build tree
1783                 if (! -f $s) {
1784                     $s = cleanfile($buildd, $_, $blddir);
1785                 }
1786                 # We recognise C++, C and asm files
1787                 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1788                     my $o = $_;
1789                     $o =~ s/\.[csS]$/.o/; # C and assembler
1790                     $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1791                     $o = cleanfile($buildd, $o, $blddir);
1792                     $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1793                     $unified_info{sources}->{$o}->{$s} = 1;
1794                 } else {
1795                     die "unrecognised source file type for shared library: $s\n";
1796                 }
1797             }
1798         }
1799
1800         foreach (keys %generate) {
1801             my $dest = $_;
1802             my $ddest = cleanfile($buildd, $_, $blddir);
1803             if ($unified_info{rename}->{$ddest}) {
1804                 $ddest = $unified_info{rename}->{$ddest};
1805             }
1806             die "more than one generator for $dest: "
1807                     ,join(" ", @{$generate{$_}}),"\n"
1808                     if scalar @{$generate{$_}} > 1;
1809             my @generator = split /\s+/, $generate{$dest}->[0];
1810             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1811             $unified_info{generate}->{$ddest} = [ @generator ];
1812         }
1813
1814         foreach (keys %depends) {
1815             my $dest = $_;
1816             my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
1817
1818             # If the destination doesn't exist in source, it can only be
1819             # a generated file in the build tree.
1820             if ($ddest ne "" && ! -f $ddest) {
1821                 $ddest = cleanfile($buildd, $_, $blddir);
1822                 if ($unified_info{rename}->{$ddest}) {
1823                     $ddest = $unified_info{rename}->{$ddest};
1824                 }
1825             }
1826             foreach (@{$depends{$dest}}) {
1827                 my $d = cleanfile($sourced, $_, $blddir);
1828
1829                 # If we know it's generated, or assume it is because we can't
1830                 # find it in the source tree, we set file we depend on to be
1831                 # in the build tree rather than the source tree, and assume
1832                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1833                 # section or in the Makefile template.
1834                 if (! -f $d
1835                     || (grep { $d eq $_ }
1836                         map { cleanfile($srcdir, $_, $blddir) }
1837                         grep { /\.h$/ } keys %{$unified_info{generate}})) {
1838                     $d = cleanfile($buildd, $_, $blddir);
1839                 }
1840                 # Take note if the file to depend on is being renamed
1841                 # Take extra care with files ending with .a, they should
1842                 # be treated without that extension, and the extension
1843                 # should be added back after treatment.
1844                 $d =~ /(\.a)?$/;
1845                 my $e = $1 // "";
1846                 $d = $`;
1847                 if ($unified_info{rename}->{$d}) {
1848                     $d = $unified_info{rename}->{$d};
1849                 }
1850                 $d .= $e;
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 }