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