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