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