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