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