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