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