Fix OCSP Status Request extension unbounded memory growth
[openssl.git] / Configure
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3 # Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
4 #
5 # Licensed under the OpenSSL license (the "License").  You may not use
6 # this file except in compliance with the License.  You can obtain a copy
7 # in the file LICENSE in the source distribution or at
8 # https://www.openssl.org/source/license.html
9
10 ##  Configure -- OpenSSL source tree configuration script
11
12 require 5.10.0;
13 use strict;
14 use File::Basename;
15 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
16 use File::Path qw/mkpath/;
17 use if $^O ne "VMS", 'File::Glob' => qw/glob/;
18
19 # see INSTALL for instructions.
20
21 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
22
23 # Options:
24 #
25 # --config      add the given configuration file, which will be read after
26 #               any "Configurations*" files that are found in the same
27 #               directory as this script.
28 # --prefix      prefix for the OpenSSL installation, which includes the
29 #               directories bin, lib, include, share/man, share/doc/openssl
30 #               This becomes the value of INSTALLTOP in Makefile
31 #               (Default: /usr/local)
32 # --openssldir  OpenSSL data area, such as openssl.cnf, certificates and keys.
33 #               If it's a relative directory, it will be added on the directory
34 #               given with --prefix.
35 #               This becomes the value of OPENSSLDIR in Makefile and in C.
36 #               (Default: PREFIX/ssl)
37 #
38 # --cross-compile-prefix Add specified prefix to binutils components.
39 #
40 # --api         One of 0.9.8, 1.0.0 or 1.1.0.  Do not compile support for
41 #               interfaces deprecated as of the specified OpenSSL version.
42 #
43 # no-hw-xxx     do not compile support for specific crypto hardware.
44 #               Generic OpenSSL-style methods relating to this support
45 #               are always compiled but return NULL if the hardware
46 #               support isn't compiled.
47 # no-hw         do not compile support for any crypto hardware.
48 # [no-]threads  [don't] try to create a library that is suitable for
49 #               multithreaded applications (default is "threads" if we
50 #               know how to do it)
51 # [no-]shared   [don't] try to create shared libraries when supported.
52 # [no-]pic      [don't] try to build position independent code when supported.
53 #               If disabled, it also disables shared and dynamic-engine.
54 # no-asm        do not use assembler
55 # no-dso        do not compile in any native shared-library methods. This
56 #               will ensure that all methods just return NULL.
57 # no-egd        do not compile support for the entropy-gathering daemon APIs
58 # [no-]zlib     [don't] compile support for zlib compression.
59 # zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
60 #               library and will be loaded in run-time by the OpenSSL library.
61 # sctp          include SCTP support
62 # 386           generate 80386 code
63 # enable-weak-ssl-ciphers
64 #               Enable weak ciphers that are disabled by default. This currently
65 #               only includes RC4 based ciphers.
66 # no-sse2       disables IA-32 SSE2 code, above option implies no-sse2
67 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
68 # -<xxx> +<xxx> compiler options are passed through
69 # -static       while -static is also a pass-through compiler option (and
70 #               as such is limited to environments where it's actually
71 #               meaningful), it triggers a number configuration options,
72 #               namely no-dso, no-pic, no-shared and no-threads. It is
73 #               argued that the only reason to produce statically linked
74 #               binaries (and in context it means executables linked with
75 #               -static flag, and not just executables linked with static
76 #               libcrypto.a) is to eliminate dependency on specific run-time,
77 #               a.k.a. libc version. The mentioned config options are meant
78 #               to achieve just that. Unfortunately on Linux it's impossible
79 #               to eliminate the dependency completely for openssl executable
80 #               because of getaddrinfo and gethostbyname calls, which can
81 #               invoke dynamically loadable library facility anyway to meet
82 #               the lookup requests. For this reason on Linux statically
83 #               linked openssl executable has rather debugging value than
84 #               production quality.
85 #
86 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
87 #               provided to stack calls. Generates unique stack functions for
88 #               each possible stack type.
89 # BN_LLONG      use the type 'long long' in crypto/bn/bn.h
90 # RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
91 # Following are set automatically by this script
92 #
93 # MD5_ASM       use some extra md5 assembler,
94 # SHA1_ASM      use some extra sha1 assembler, must define L_ENDIAN for x86
95 # RMD160_ASM    use some extra ripemd160 assembler,
96 # SHA256_ASM    sha256_block is implemented in assembler
97 # SHA512_ASM    sha512_block is implemented in assembler
98 # AES_ASM       AES_[en|de]crypt is implemented in assembler
99
100 # Minimum warning options... any contributions to OpenSSL should at least get
101 # past these.
102
103 # DEBUG_UNUSED enables __owur (warn unused result) checks.
104 my $gcc_devteam_warn = "-DDEBUG_UNUSED"
105         # -DPEDANTIC complements -pedantic and is meant to mask code that
106         # is not strictly standard-compliant and/or implementation-specific,
107         # e.g. inline assembly, disregards to alignment requirements, such
108         # that -pedantic would complain about. Incidentally -DPEDANTIC has
109         # to be used even in sanitized builds, because sanitizer too is
110         # supposed to and does take notice of non-standard behaviour. Then
111         # -pedantic with pre-C9x compiler would also complain about 'long
112         # long' not being supported. As 64-bit algorithms are common now,
113         # it grew impossible to resolve this without sizeable additional
114         # code, so we just tell compiler to be pedantic about everything
115         # but 'long long' type.
116         . " -DPEDANTIC -pedantic -Wno-long-long"
117         . " -Wall"
118         . " -Wsign-compare"
119         . " -Wmissing-prototypes"
120         . " -Wshadow"
121         . " -Wformat"
122         . " -Wtype-limits"
123         . " -Werror"
124         ;
125
126 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
127 # TODO(openssl-team): fix problems and investigate if (at least) the
128 # following warnings can also be enabled:
129 #       -Wswitch-enum
130 #       -Wcast-align
131 #       -Wunreachable-code
132 #       -Wlanguage-extension-token -- no, we use asm()
133 #       -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
134 #       -Wextended-offsetof -- no, needed in CMS ASN1 code
135 my $clang_devteam_warn = ""
136         . " -Qunused-arguments"
137         . " -Wextra"
138         . " -Wno-unused-parameter"
139         . " -Wno-missing-field-initializers"
140         . " -Wno-language-extension-token"
141         . " -Wno-extended-offsetof"
142         . " -Wconditional-uninitialized"
143         . " -Wincompatible-pointer-types-discards-qualifiers"
144         . " -Wmissing-variable-declarations"
145         ;
146
147 # This adds backtrace information to the memory leak info.  Is only used
148 # when crypto-mdebug-backtrace is enabled.
149 my $memleak_devteam_backtrace = "-rdynamic";
150
151 my $strict_warnings = 0;
152
153 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
154 # which would cover all BSD flavors. -pthread applies to them all,
155 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
156 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
157 # which has to be accompanied by explicit -D_THREAD_SAFE and
158 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
159 # seems to be sufficient?
160 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
161
162 #
163 # API compatibility name to version number mapping.
164 #
165 my $maxapi = "1.1.0";           # API for "no-deprecated" builds
166 my $apitable = {
167     "1.1.0" => "0x10100000L",
168     "1.0.0" => "0x10000000L",
169     "0.9.8" => "0x00908000L",
170 };
171
172 our %table = ();
173 our %config = ();
174 our %withargs = ();
175
176 # Forward declarations ###############################################
177
178 # read_config(filename)
179 #
180 # Reads a configuration file and populates %table with the contents
181 # (which the configuration file places in %targets).
182 sub read_config;
183
184 # resolve_config(target)
185 #
186 # Resolves all the late evaluations, inheritances and so on for the
187 # chosen target and any target it inherits from.
188 sub resolve_config;
189
190
191 # Information collection #############################################
192
193 # Unified build supports separate build dir
194 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
195 my $blddir = catdir(absolutedir("."));         # catdir ensures local syntax
196 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
197
198 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
199
200 $config{sourcedir} = abs2rel($srcdir);
201 $config{builddir} = abs2rel($blddir);
202
203 # Collect reconfiguration information if needed
204 my @argvcopy=@ARGV;
205
206 if (grep /^reconf(igure)?$/, @argvcopy) {
207     if (-f "./configdata.pm") {
208         my $file = "./configdata.pm";
209         unless (my $return = do $file) {
210             die "couldn't parse $file: $@" if $@;
211             die "couldn't do $file: $!"    unless defined $return;
212             die "couldn't run $file"       unless $return;
213         }
214
215         @argvcopy = defined($configdata::config{perlargv}) ?
216             @{$configdata::config{perlargv}} : ();
217         die "Incorrect data to reconfigure, please do a normal configuration\n"
218             if (grep(/^reconf/,@argvcopy));
219         $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
220             if defined($configdata::config{cross_compile_prefix});
221         $ENV{CC} = $configdata::config{cc}
222             if defined($configdata::config{cc});
223         $ENV{BUILDFILE} = $configdata::config{build_file}
224             if defined($configdata::config{build_file});
225         $ENV{$local_config_envname} = $configdata::config{local_config_dir}
226             if defined($configdata::config{local_config_dir});
227
228         print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
229         print "    CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
230             if $ENV{CROSS_COMPILE};
231         print "    CC = ",$ENV{CC},"\n" if $ENV{CC};
232         print "    BUILDFILE = ",$ENV{BUILDFILE},"\n" if $ENV{BUILDFILE};
233         print "    $local_config_envname = ",$ENV{$local_config_envname},"\n"
234             if $ENV{$local_config_envname};
235     } else {
236         die "Insufficient data to reconfigure, please do a normal configuration\n";
237     }
238 }
239
240 $config{perlargv} = [ @argvcopy ];
241
242 # Collect version numbers
243 $config{version} = "unknown";
244 $config{version_num} = "unknown";
245 $config{shlib_version_number} = "unknown";
246 $config{shlib_version_history} = "unknown";
247
248 collect_information(
249     collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
250     qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
251     qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/      => sub { $config{version_num}=$1 },
252     qr/SHLIB_VERSION_NUMBER *"([^"]+)"/      => sub { $config{shlib_version_number}=$1 },
253     qr/SHLIB_VERSION_HISTORY *"([^"]*)"/     => sub { $config{shlib_version_history}=$1 }
254     );
255 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
256
257 ($config{major}, $config{minor})
258     = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
259 ($config{shlib_major}, $config{shlib_minor})
260     = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
261 die "erroneous version information in opensslv.h: ",
262     "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
263     if ($config{major} eq "" || $config{minor} eq ""
264         || $config{shlib_major} eq "" ||  $config{shlib_minor} eq "");
265
266 # Collect target configurations
267
268 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
269 foreach (sort glob($pattern)) {
270     &read_config($_);
271 }
272
273 if (defined $ENV{$local_config_envname}) {
274     if ($^O eq 'VMS') {
275         # VMS environment variables are logical names,
276         # which can be used as is
277         $pattern = $local_config_envname . ':' . '*.conf';
278     } else {
279         $pattern = catfile($ENV{$local_config_envname}, '*.conf');
280     }
281
282     foreach (sort glob($pattern)) {
283         &read_config($_);
284     }
285 }
286
287
288 print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n";
289
290 $config{prefix}="";
291 $config{openssldir}="";
292 $config{processor}="";
293 $config{libdir}="";
294 $config{cross_compile_prefix}="";
295 $config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
296 my $nofipscanistercheck=0;
297 $config{baseaddr}="0xFB00000";
298 my $auto_threads=1;    # enable threads automatically? true by default
299 my $default_ranlib;
300 $config{fips}=0;
301
302 # Top level directories to build
303 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
304 # crypto/ subdirectories to build
305 $config{sdirs} = [
306     "objects",
307     "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2",
308     "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes",
309     "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
310     "buffer", "bio", "stack", "lhash", "rand", "err",
311     "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
312     "cms", "ts", "srp", "cmac", "ct", "async", "kdf"
313     ];
314
315 # Known TLS and DTLS protocols
316 my @tls = qw(ssl3 tls1 tls1_1 tls1_2);
317 my @dtls = qw(dtls1 dtls1_2);
318
319 # Explicitly known options that are possible to disable.  They can
320 # be regexps, and will be used like this: /^no-${option}$/
321 # For developers: keep it sorted alphabetically
322
323 my @disablables = (
324     "afalgeng",
325     "asan",
326     "asm",
327     "async",
328     "autoalginit",
329     "autoerrinit",
330     "bf",
331     "blake2",
332     "camellia",
333     "capieng",
334     "cast",
335     "chacha",
336     "cmac",
337     "cms",
338     "comp",
339     "crypto-mdebug",
340     "crypto-mdebug-backtrace",
341     "ct",
342     "deprecated",
343     "des",
344     "dgram",
345     "dh",
346     "dsa",
347     "dso",
348     "dtls",
349     "dynamic-engine",
350     "ec",
351     "ec2m",
352     "ecdh",
353     "ecdsa",
354     "ec_nistp_64_gcc_128",
355     "egd",
356     "engine",
357     "err",
358     "filenames",
359     "fuzz-libfuzzer",
360     "fuzz-afl",
361     "gost",
362     "heartbeats",
363     "hw(-.+)?",
364     "idea",
365     "makedepend",
366     "md2",
367     "md4",
368     "mdc2",
369     "msan",
370     "multiblock",
371     "nextprotoneg",
372     "ocb",
373     "ocsp",
374     "pic",
375     "poly1305",
376     "posix-io",
377     "psk",
378     "rc2",
379     "rc4",
380     "rc5",
381     "rdrand",
382     "rfc3779",
383     "rmd160",
384     "scrypt",
385     "sctp",
386     "seed",
387     "shared",
388     "sock",
389     "srp",
390     "srtp",
391     "sse2",
392     "ssl",
393     "ssl-trace",
394     "static-engine",
395     "stdio",
396     "threads",
397     "tls",
398     "ts",
399     "ubsan",
400     "ui",
401     "unit-test",
402     "whirlpool",
403     "weak-ssl-ciphers",
404     "zlib",
405     "zlib-dynamic",
406     );
407 foreach my $proto ((@tls, @dtls))
408         {
409         push(@disablables, $proto);
410         push(@disablables, "$proto-method");
411         }
412
413 my %deprecated_disablables = (
414     "ssl2" => undef,
415     "buf-freelists" => undef,
416     "ripemd" => "rmd160"
417     );
418
419 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
420
421 our %disabled = ( # "what"         => "comment"
422                   "asan"                => "default",
423                   "crypto-mdebug"       => "default",
424                   "crypto-mdebug-backtrace" => "default",
425                   "ec_nistp_64_gcc_128" => "default",
426                   "egd"                 => "default",
427                   "fuzz-libfuzzer"      => "default",
428                   "fuzz-afl"            => "default",
429                   "heartbeats"          => "default",
430                   "md2"                 => "default",
431                   "msan"                => "default",
432                   "rc5"                 => "default",
433                   "sctp"                => "default",
434                   "ssl-trace"           => "default",
435                   "ssl3"                => "default",
436                   "ssl3-method"         => "default",
437                   "ubsan"               => "default",
438                   "unit-test"           => "default",
439                   "weak-ssl-ciphers"    => "default",
440                   "zlib"                => "default",
441                   "zlib-dynamic"        => "default",
442                 );
443
444 # Note: => pair form used for aesthetics, not to truly make a hash table
445 my @disable_cascades = (
446     # "what"            => [ "cascade", ... ]
447     sub { $config{processor} eq "386" }
448                         => [ "sse2" ],
449     "ssl"               => [ "ssl3" ],
450     "ssl3-method"       => [ "ssl3" ],
451     "zlib"              => [ "zlib-dynamic" ],
452     "des"               => [ "mdc2" ],
453     "ec"                => [ "ecdsa", "ecdh" ],
454
455     "dgram"             => [ "dtls", "sctp" ],
456     "sock"              => [ "dgram" ],
457     "dtls"              => [ @dtls ],
458
459     # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
460     "md5"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
461     "sha"               => [ "ssl", "tls1", "tls1_1", "dtls1" ],
462
463     # Additionally, SSL 3.0 requires either RSA or DSA+DH
464     sub { $disabled{rsa}
465           && ($disabled{dsa} || $disabled{dh}); }
466                         => [ "ssl" ],
467
468     # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
469     # or ECDSA + ECDH.  (D)TLS 1.2 has this requirement as well.
470     # (XXX: We don't support PSK-only builds).
471     sub { $disabled{rsa}
472           && ($disabled{dsa} || $disabled{dh})
473           && ($disabled{ecdsa} || $disabled{ecdh}); }
474                         => [ "tls1", "tls1_1", "tls1_2",
475                              "dtls1", "dtls1_2" ],
476
477     "tls"               => [ @tls ],
478
479     # SRP and HEARTBEATS require TLSEXT
480     "tlsext"            => [ "srp", "heartbeats" ],
481
482     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
483
484     # Without DSO, we can't load dynamic engines, so don't build them dynamic
485     "dso"               => [ "dynamic-engine" ],
486
487     # Without position independent code, there can be no shared libraries or DSOs
488     "pic"               => [ "shared" ],
489     "shared"            => [ "dynamic-engine" ],
490     "engine"            => [ "afalgeng" ],
491
492     # no-autoalginit is only useful when building non-shared
493     "autoalginit"       => [ "shared", "apps" ],
494
495     "stdio"             => [ "apps", "capieng" ],
496     "apps"              => [ "tests" ],
497     "comp"              => [ "zlib" ],
498     sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
499
500     sub { !$disabled{"msan"} } => [ "asm" ],
501     );
502
503 # Avoid protocol support holes.  Also disable all versions below N, if version
504 # N is disabled while N+1 is enabled.
505 #
506 my @list = (reverse @tls);
507 while ((my $first, my $second) = (shift @list, shift @list)) {
508     last unless @list;
509     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
510                               => [ @list ] );
511     unshift @list, $second;
512 }
513 my @list = (reverse @dtls);
514 while ((my $first, my $second) = (shift @list, shift @list)) {
515     last unless @list;
516     push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
517                               => [ @list ] );
518     unshift @list, $second;
519 }
520
521 # Explicit "no-..." options will be collected in %disabled along with the defaults.
522 # To remove something from %disabled, use "enable-foo".
523 # For symmetry, "disable-foo" is a synonym for "no-foo".
524
525 my $no_sse2=0;
526
527 &usage if ($#ARGV < 0);
528
529 my $user_cflags="";
530 my @user_defines=();
531 $config{openssl_api_defines}=[];
532 $config{openssl_algorithm_defines}=[];
533 $config{openssl_thread_defines}=[];
534 $config{openssl_sys_defines}=[];
535 $config{openssl_other_defines}=[];
536 my $libs="";
537 my $target="";
538 $config{options}="";
539 $config{build_type} = "release";
540
541 my %unsupported_options = ();
542 my %deprecated_options = ();
543 foreach (@argvcopy)
544         {
545         # VMS is a case insensitive environment, and depending on settings
546         # out of our control, we may receive options uppercased.  Let's
547         # downcase at least the part before any equal sign.
548         if ($^O eq "VMS")
549                 {
550                 s/^([^=]*)/lc($1)/e;
551                 }
552         s /^-no-/no-/; # some people just can't read the instructions
553
554         # rewrite some options in "enable-..." form
555         s /^-?-?shared$/enable-shared/;
556         s /^sctp$/enable-sctp/;
557         s /^threads$/enable-threads/;
558         s /^zlib$/enable-zlib/;
559         s /^zlib-dynamic$/enable-zlib-dynamic/;
560
561         if (/^(no|disable|enable)-(.+)$/)
562                 {
563                 my $word = $2;
564                 if (!exists $deprecated_disablables{$word}
565                         && !grep { $word =~ /^${_}$/ } @disablables)
566                         {
567                         $unsupported_options{$_} = 1;
568                         next;
569                         }
570                 }
571         if (/^no-(.+)$/ || /^disable-(.+)$/)
572                 {
573                 foreach my $proto ((@tls, @dtls))
574                         {
575                         if ($1 eq "$proto-method")
576                                 {
577                                 $disabled{"$proto"} = "option($proto-method)";
578                                 last;
579                                 }
580                         }
581                 if ($1 eq "dtls")
582                         {
583                         foreach my $proto (@dtls)
584                                 {
585                                 $disabled{$proto} = "option(dtls)";
586                                 }
587                         $disabled{"dtls"} = "option(dtls)";
588                         }
589                 elsif ($1 eq "ssl")
590                         {
591                         # Last one of its kind
592                         $disabled{"ssl3"} = "option(ssl)";
593                         }
594                 elsif ($1 eq "tls")
595                         {
596                         # XXX: Tests will fail if all SSL/TLS
597                         # protocols are disabled.
598                         foreach my $proto (@tls)
599                                 {
600                                 $disabled{$proto} = "option(tls)";
601                                 }
602                         }
603                 elsif ($1 eq "static-engine")
604                         {
605                         delete $disabled{"dynamic-engine"};
606                         }
607                 elsif ($1 eq "dynamic-engine")
608                         {
609                         $disabled{"dynamic-engine"} = "option";
610                         }
611                 elsif (exists $deprecated_disablables{$1})
612                         {
613                         $deprecated_options{$_} = 1;
614                         if (defined $deprecated_disablables{$1})
615                                 {
616                                 $disabled{$deprecated_disablables{$1}} = "option";
617                                 }
618                         }
619                 else
620                         {
621                         $disabled{$1} = "option";
622                         }
623                 # No longer an automatic choice
624                 $auto_threads = 0 if ($1 eq "threads");
625                 }
626         elsif (/^enable-(.+)$/)
627                 {
628                 if ($1 eq "static-engine")
629                         {
630                         $disabled{"dynamic-engine"} = "option";
631                         }
632                 elsif ($1 eq "dynamic-engine")
633                         {
634                         delete $disabled{"dynamic-engine"};
635                         }
636                 elsif ($1 eq "zlib-dynamic")
637                         {
638                         delete $disabled{"zlib"};
639                         }
640                 my $algo = $1;
641                 delete $disabled{$algo};
642
643                 # No longer an automatic choice
644                 $auto_threads = 0 if ($1 eq "threads");
645                 }
646         elsif (/^--strict-warnings$/)
647                 {
648                 $strict_warnings = 1;
649                 }
650         elsif (/^--debug$/)
651                 {
652                 $config{build_type} = "debug";
653                 }
654         elsif (/^--release$/)
655                 {
656                 $config{build_type} = "release";
657                 }
658         elsif (/^386$/)
659                 { $config{processor}=386; }
660         elsif (/^fips$/)
661                 {
662                 $config{fips}=1;
663                 }
664         elsif (/^rsaref$/)
665                 {
666                 # No RSAref support any more since it's not needed.
667                 # The check for the option is there so scripts aren't
668                 # broken
669                 }
670         elsif (/^nofipscanistercheck$/)
671                 {
672                 $config{fips} = 1;
673                 $nofipscanistercheck = 1;
674                 }
675         elsif (/^[-+]/)
676                 {
677                 if (/^--prefix=(.*)$/)
678                         {
679                         $config{prefix}=$1;
680                         die "Directory given with --prefix MUST be absolute\n"
681                                 unless file_name_is_absolute($config{prefix});
682                         }
683                 elsif (/^--api=(.*)$/)
684                         {
685                         $config{api}=$1;
686                         }
687                 elsif (/^--libdir=(.*)$/)
688                         {
689                         $config{libdir}=$1;
690                         }
691                 elsif (/^--openssldir=(.*)$/)
692                         {
693                         $config{openssldir}=$1;
694                         }
695                 elsif (/^--with-zlib-lib=(.*)$/)
696                         {
697                         $withargs{zlib_lib}=$1;
698                         }
699                 elsif (/^--with-zlib-include=(.*)$/)
700                         {
701                         $withargs{zlib_include}=$1;
702                         }
703                 elsif (/^--with-fuzzer-lib=(.*)$/)
704                         {
705                         $withargs{fuzzer_lib}=$1;
706                         }
707                 elsif (/^--with-fuzzer-include=(.*)$/)
708                         {
709                         $withargs{fuzzer_include}=$1;
710                         }
711                 elsif (/^--with-fipslibdir=(.*)$/)
712                         {
713                         $config{fipslibdir}="$1/";
714                         }
715                 elsif (/^--with-baseaddr=(.*)$/)
716                         {
717                         $config{baseaddr}="$1";
718                         }
719                 elsif (/^--cross-compile-prefix=(.*)$/)
720                         {
721                         $config{cross_compile_prefix}=$1;
722                         }
723                 elsif (/^--config=(.*)$/)
724                         {
725                         read_config $1;
726                         }
727                 elsif (/^-[lL](.*)$/ or /^-Wl,/)
728                         {
729                         $libs.=$_." ";
730                         }
731                 elsif (/^-static$/)
732                         {
733                         $libs.=$_." ";
734                         $disabled{"dso"} = "forced";
735                         $disabled{"pic"} = "forced";
736                         $disabled{"shared"} = "forced";
737                         $disabled{"threads"} = "forced";
738                         }
739                 elsif (/^-D(.*)$/)
740                         {
741                         push @user_defines, $1;
742                         }
743                 else    # common if (/^[-+]/), just pass down...
744                         {
745                         $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
746                         $user_cflags.=" ".$_;
747                         }
748                 }
749         else
750                 {
751                 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
752                 $target=$_;
753                 }
754         unless ($_ eq $target || /^no-/ || /^disable-/)
755                 {
756                 # "no-..." follows later after implied disactivations
757                 # have been derived.  (Don't take this too seriously,
758                 # we really only write OPTIONS to the Makefile out of
759                 # nostalgia.)
760
761                 if ($config{options} eq "")
762                         { $config{options} = $_; }
763                 else
764                         { $config{options} .= " ".$_; }
765                 }
766
767         if (defined($config{api}) && !exists $apitable->{$config{api}}) {
768                 die "***** Unsupported api compatibility level: $config{api}\n",
769         }
770
771         if (keys %deprecated_options)
772                 {
773                 warn "***** Deprecated options: ",
774                         join(", ", keys %deprecated_options), "\n";
775                 }
776         if (keys %unsupported_options)
777                 {
778                 die "***** Unsupported options: ",
779                         join(", ", keys %unsupported_options), "\n";
780                 }
781         }
782
783 if ($libs =~ /(^|\s)-Wl,-rpath,/
784     && !$disabled{shared}
785     && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
786     die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
787         "***** any of asan, msan or ubsan\n";
788 }
789
790 if ($config{fips})
791         {
792         delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/);
793         }
794 else
795         {
796         @{$config{dirs}} = grep !/^fips$/, @{$config{dirs}};
797         }
798
799 my @tocheckfor = (keys %disabled);
800 while (@tocheckfor) {
801     my %new_tocheckfor = ();
802     my @cascade_copy = (@disable_cascades);
803     while (@cascade_copy) {
804         my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
805         if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
806             foreach(grep { !defined($disabled{$_}) } @$descendents) {
807                 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
808             }
809         }
810     }
811     @tocheckfor = (keys %new_tocheckfor);
812 }
813
814 our $die = sub { die @_; };
815 if ($target eq "TABLE") {
816     local $die = sub { warn @_; };
817     foreach (sort keys %table) {
818         print_table_entry($_, "TABLE");
819     }
820     exit 0;
821 }
822
823 if ($target eq "LIST") {
824     foreach (sort keys %table) {
825         print $_,"\n" unless $table{$_}->{template};
826     }
827     exit 0;
828 }
829
830 if ($target eq "HASH") {
831     local $die = sub { warn @_; };
832     print "%table = (\n";
833     foreach (sort keys %table) {
834         print_table_entry($_, "HASH");
835     }
836     exit 0;
837 }
838
839 # Backward compatibility?
840 if ($target =~ m/^CygWin32(-.*)$/) {
841     $target = "Cygwin".$1;
842 }
843
844 foreach (sort (keys %disabled))
845         {
846         $config{options} .= " no-$_";
847
848         printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
849
850         if (/^dso$/)
851                 { }
852         elsif (/^threads$/)
853                 { }
854         elsif (/^shared$/)
855                 { }
856         elsif (/^pic$/)
857                 { }
858         elsif (/^zlib$/)
859                 { }
860         elsif (/^dynamic-engine$/)
861                 { }
862         elsif (/^makedepend$/)
863                 { }
864         elsif (/^zlib-dynamic$/)
865                 { }
866         elsif (/^sse2$/)
867                 { $no_sse2 = 1; }
868         elsif (/^engine$/)
869                 {
870                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
871                 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
872                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
873                 print " OPENSSL_NO_ENGINE (skip engines)";
874                 }
875         else
876                 {
877                 my ($WHAT, $what);
878
879                 ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/;
880
881                 # Fix up C macro end names
882                 $WHAT = "RMD160" if $what eq "ripemd";
883
884                 # fix-up crypto/directory name(s)
885                 $what = "ripemd" if $what eq "rmd160";
886                 $what = "whrlpool" if $what eq "whirlpool";
887
888                 if ($what ne "async" && $what ne "err"
889                     && grep { $_ eq $what } @{$config{sdirs}})
890                         {
891                         push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT";
892                         @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}};
893
894                         print " OPENSSL_NO_$WHAT (skip dir)";
895                         }
896                 else
897                         {
898                         push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
899                         print " OPENSSL_NO_$WHAT";
900
901                         if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
902                         }
903                 }
904
905         print "\n";
906         }
907
908 print "Configuring for $target\n";
909
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} =    $ENV{'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
2029 print "CC            =$config{cross_compile_prefix}$target{cc}\n";
2030 print "CFLAG         =$target{cflags} $config{cflags}\n";
2031 print "SHARED_CFLAG  =$target{shared_cflag}\n";
2032 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
2033 print "LFLAG         =$target{lflags}\n";
2034 print "PLIB_LFLAG    =$target{plib_lflags}\n";
2035 print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
2036 print "APPS_OBJ      =$target{apps_obj}\n";
2037 print "CPUID_OBJ     =$target{cpuid_obj}\n";
2038 print "UPLINK_OBJ    =$target{uplink_obj}\n";
2039 print "BN_ASM        =$target{bn_obj}\n";
2040 print "EC_ASM        =$target{ec_obj}\n";
2041 print "DES_ENC       =$target{des_obj}\n";
2042 print "AES_ENC       =$target{aes_obj}\n";
2043 print "BF_ENC        =$target{bf_obj}\n";
2044 print "CAST_ENC      =$target{cast_obj}\n";
2045 print "RC4_ENC       =$target{rc4_obj}\n";
2046 print "RC5_ENC       =$target{rc5_obj}\n";
2047 print "MD5_OBJ_ASM   =$target{md5_obj}\n";
2048 print "SHA1_OBJ_ASM  =$target{sha1_obj}\n";
2049 print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
2050 print "CMLL_ENC      =$target{cmll_obj}\n";
2051 print "MODES_OBJ     =$target{modes_obj}\n";
2052 print "PADLOCK_OBJ   =$target{padlock_obj}\n";
2053 print "CHACHA_ENC    =$target{chacha_obj}\n";
2054 print "POLY1305_OBJ  =$target{poly1305_obj}\n";
2055 print "BLAKE2_OBJ    =$target{blake2_obj}\n";
2056 print "PROCESSOR     =$config{processor}\n";
2057 print "RANLIB        =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
2058                              "$config{cross_compile_prefix}ranlib" :
2059                              "$target{ranlib}", "\n";
2060 print "ARFLAGS       =$target{arflags}\n";
2061 print "PERL          =$config{perl}\n";
2062 print "\n";
2063 print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
2064 print "SIXTY_FOUR_BIT mode\n" if $config{b64};
2065 print "THIRTY_TWO_BIT mode\n" if $config{b32};
2066 print "BN_LLONG mode\n" if $config{bn_ll};
2067 print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int;
2068
2069 my %builders = (
2070     unified => sub {
2071         run_dofile(catfile($blddir, $target{build_file}),
2072                    @{$config{build_file_templates}});
2073     },
2074     );
2075
2076 $builders{$builder}->($builder_platform, @builder_opts);
2077
2078 print <<"EOF";
2079
2080 Configured for $target.
2081 EOF
2082
2083 print <<"EOF" if ($disabled{threads} eq "unavailable");
2084
2085 The library could not be configured for supporting multi-threaded
2086 applications as the compiler options required on this system are not known.
2087 See file INSTALL for details if you need multi-threading.
2088 EOF
2089
2090 print <<"EOF" if ($no_shared_warn);
2091
2092 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2093 platform, so we will pretend you gave the option 'no-pic', which also disables
2094 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
2095 or position independent code, please let us know (but please first make sure
2096 you have tried with a current version of OpenSSL).
2097 EOF
2098
2099 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2100
2101 WARNING: there are indications that another build was made in the source
2102 directory.  This build may have picked up artifacts from that build, the
2103 safest course of action is to clean the source directory and redo this
2104 configuration.
2105 EOF
2106
2107 exit(0);
2108
2109 ######################################################################
2110 #
2111 # Helpers and utility functions
2112 #
2113
2114 # Configuration file reading #########################################
2115
2116 # Note: All of the helper functions are for lazy evaluation.  They all
2117 # return a CODE ref, which will return the intended value when evaluated.
2118 # Thus, whenever there's mention of a returned value, it's about that
2119 # intended value.
2120
2121 # Helper function to implement conditional inheritance depending on the
2122 # value of $disabled{asm}.  Used in inherit_from values as follows:
2123 #
2124 #      inherit_from => [ "template", asm("asm_tmpl") ]
2125 #
2126 sub asm {
2127     my @x = @_;
2128     sub {
2129         $disabled{asm} ? () : @x;
2130     }
2131 }
2132
2133 # Helper function to implement conditional value variants, with a default
2134 # plus additional values based on the value of $config{build_type}.
2135 # Arguments are given in hash table form:
2136 #
2137 #       picker(default => "Basic string: ",
2138 #              debug   => "debug",
2139 #              release => "release")
2140 #
2141 # When configuring with --debug, the resulting string will be
2142 # "Basic string: debug", and when not, it will be "Basic string: release"
2143 #
2144 # This can be used to create variants of sets of flags according to the
2145 # build type:
2146 #
2147 #       cflags => picker(default => "-Wall",
2148 #                        debug   => "-g -O0",
2149 #                        release => "-O3")
2150 #
2151 sub picker {
2152     my %opts = @_;
2153     return sub { add($opts{default} || (),
2154                      $opts{$config{build_type}} || ())->(); }
2155 }
2156
2157 # Helper function to combine several values of different types into one.
2158 # This is useful if you want to combine a string with the result of a
2159 # lazy function, such as:
2160 #
2161 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2162 #
2163 sub combine {
2164     my @stuff = @_;
2165     return sub { add(@stuff)->(); }
2166 }
2167
2168 # Helper function to implement conditional values depending on the value
2169 # of $disabled{threads}.  Can be used as follows:
2170 #
2171 #       cflags => combine("-Wall", threads("-pthread"))
2172 #
2173 sub threads {
2174     my @flags = @_;
2175     return sub { add($disabled{threads} ? () : @flags)->(); }
2176 }
2177
2178
2179
2180 our $add_called = 0;
2181 # Helper function to implement adding values to already existing configuration
2182 # values.  It handles elements that are ARRAYs, CODEs and scalars
2183 sub _add {
2184     my $separator = shift;
2185
2186     # If there's any ARRAY in the collection of values OR the separator
2187     # is undef, we will return an ARRAY of combined values, otherwise a
2188     # string of joined values with $separator as the separator.
2189     my $found_array = !defined($separator);
2190
2191     my @values =
2192         map {
2193             my $res = $_;
2194             while (ref($res) eq "CODE") {
2195                 $res = $res->();
2196             }
2197             if (defined($res)) {
2198                 if (ref($res) eq "ARRAY") {
2199                     $found_array = 1;
2200                     @$res;
2201                 } else {
2202                     $res;
2203                 }
2204             } else {
2205                 ();
2206             }
2207     } (@_);
2208
2209     $add_called = 1;
2210
2211     if ($found_array) {
2212         [ @values ];
2213     } else {
2214         join($separator, grep { defined($_) && $_ ne "" } @values);
2215     }
2216 }
2217 sub add_before {
2218     my $separator = " ";
2219     if (ref($_[$#_]) eq "HASH") {
2220         my $opts = pop;
2221         $separator = $opts->{separator};
2222     }
2223     my @x = @_;
2224     sub { _add($separator, @x, @_) };
2225 }
2226 sub add {
2227     my $separator = " ";
2228     if (ref($_[$#_]) eq "HASH") {
2229         my $opts = pop;
2230         $separator = $opts->{separator};
2231     }
2232     my @x = @_;
2233     sub { _add($separator, @_, @x) };
2234 }
2235
2236 # configuration reader, evaluates the input file as a perl script and expects
2237 # it to fill %targets with target configurations.  Those are then added to
2238 # %table.
2239 sub read_config {
2240     my $fname = shift;
2241     open(CONFFILE, "< $fname")
2242         or die "Can't open configuration file '$fname'!\n";
2243     my $x = $/;
2244     undef $/;
2245     my $content = <CONFFILE>;
2246     $/ = $x;
2247     close(CONFFILE);
2248     my %targets = ();
2249     {
2250         # Protect certain tables from tampering
2251         local %table = %::table;
2252
2253         eval $content;
2254         warn $@ if $@;
2255     }
2256
2257     # For each target, check that it's configured with a hash table.
2258     foreach (keys %targets) {
2259         if (ref($targets{$_}) ne "HASH") {
2260             if (ref($targets{$_}) eq "") {
2261                 warn "Deprecated target configuration for $_, ignoring...\n";
2262             } else {
2263                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2264             }
2265             delete $targets{$_};
2266         } else {
2267             $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2268         }
2269     }
2270
2271     %table = (%table, %targets);
2272
2273 }
2274
2275 # configuration resolver.  Will only resolve all the lazy evaluation
2276 # codeblocks for the chosen target and all those it inherits from,
2277 # recursively
2278 sub resolve_config {
2279     my $target = shift;
2280     my @breadcrumbs = @_;
2281
2282 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2283
2284     if (grep { $_ eq $target } @breadcrumbs) {
2285         die "inherit_from loop!  target backtrace:\n  "
2286             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2287     }
2288
2289     if (!defined($table{$target})) {
2290         warn "Warning! target $target doesn't exist!\n";
2291         return ();
2292     }
2293     # Recurse through all inheritances.  They will be resolved on the
2294     # fly, so when this operation is done, they will all just be a
2295     # bunch of attributes with string values.
2296     # What we get here, though, are keys with references to lists of
2297     # the combined values of them all.  We will deal with lists after
2298     # this stage is done.
2299     my %combined_inheritance = ();
2300     if ($table{$target}->{inherit_from}) {
2301         my @inherit_from =
2302             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2303         foreach (@inherit_from) {
2304             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2305
2306             # 'template' is a marker that's considered private to
2307             # the config that had it.
2308             delete $inherited_config{template};
2309
2310             foreach (keys %inherited_config) {
2311                 if (!$combined_inheritance{$_}) {
2312                     $combined_inheritance{$_} = [];
2313                 }
2314                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2315             }
2316         }
2317     }
2318
2319     # We won't need inherit_from in this target any more, since we've
2320     # resolved all the inheritances that lead to this
2321     delete $table{$target}->{inherit_from};
2322
2323     # Now is the time to deal with those lists.  Here's the place to
2324     # decide what shall be done with those lists, all based on the
2325     # values of the target we're currently dealing with.
2326     # - If a value is a coderef, it will be executed with the list of
2327     #   inherited values as arguments.
2328     # - If the corresponding key doesn't have a value at all or is the
2329     #   empty string, the inherited value list will be run through the
2330     #   default combiner (below), and the result becomes this target's
2331     #   value.
2332     # - Otherwise, this target's value is assumed to be a string that
2333     #   will simply override the inherited list of values.
2334     my $default_combiner = add();
2335
2336     my %all_keys =
2337         map { $_ => 1 } (keys %combined_inheritance,
2338                          keys %{$table{$target}});
2339
2340     sub process_values {
2341         my $object    = shift;
2342         my $inherited = shift;  # Always a [ list ]
2343         my $target    = shift;
2344         my $entry     = shift;
2345
2346         $add_called = 0;
2347
2348         while(ref($object) eq "CODE") {
2349             $object = $object->(@$inherited);
2350         }
2351         if (!defined($object)) {
2352             return ();
2353         }
2354         elsif (ref($object) eq "ARRAY") {
2355             local $add_called;  # To make sure recursive calls don't affect it
2356             return [ map { process_values($_, $inherited, $target, $entry) }
2357                      @$object ];
2358         } elsif (ref($object) eq "") {
2359             return $object;
2360         } else {
2361             die "cannot handle reference type ",ref($object)
2362                 ," found in target ",$target," -> ",$entry,"\n";
2363         }
2364     }
2365
2366     foreach (sort keys %all_keys) {
2367         my $previous = $combined_inheritance{$_};
2368
2369         # Current target doesn't have a value for the current key?
2370         # Assign it the default combiner, the rest of this loop body
2371         # will handle it just like any other coderef.
2372         if (!exists $table{$target}->{$_}) {
2373             $table{$target}->{$_} = $default_combiner;
2374         }
2375
2376         $table{$target}->{$_} = process_values($table{$target}->{$_},
2377                                                $combined_inheritance{$_},
2378                                                $target, $_);
2379         unless(defined($table{$target}->{$_})) {
2380             delete $table{$target}->{$_};
2381         }
2382 #        if ($extra_checks &&
2383 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2384 #            warn "$_ got replaced in $target\n";
2385 #        }
2386     }
2387
2388     # Finally done, return the result.
2389     return %{$table{$target}};
2390 }
2391
2392 sub usage
2393         {
2394         print STDERR $usage;
2395         print STDERR "\npick os/compiler from:\n";
2396         my $j=0;
2397         my $i;
2398         my $k=0;
2399         foreach $i (sort keys %table)
2400                 {
2401                 next if $table{$i}->{template};
2402                 next if $i =~ /^debug/;
2403                 $k += length($i) + 1;
2404                 if ($k > 78)
2405                         {
2406                         print STDERR "\n";
2407                         $k=length($i);
2408                         }
2409                 print STDERR $i . " ";
2410                 }
2411         foreach $i (sort keys %table)
2412                 {
2413                 next if $table{$i}->{template};
2414                 next if $i !~ /^debug/;
2415                 $k += length($i) + 1;
2416                 if ($k > 78)
2417                         {
2418                         print STDERR "\n";
2419                         $k=length($i);
2420                         }
2421                 print STDERR $i . " ";
2422                 }
2423         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2424         exit(1);
2425         }
2426
2427 sub run_dofile
2428 {
2429     my $out = shift;
2430     my @templates = @_;
2431
2432     unlink $out || warn "Can't remove $out, $!"
2433         if -f $out;
2434     foreach (@templates) {
2435         die "Can't open $_, $!" unless -f $_;
2436     }
2437     my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2438     my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2439     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2440     system($cmd);
2441     exit 1 if $? != 0;
2442     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2443 }
2444
2445 sub which
2446 {
2447     my ($name)=@_;
2448
2449     if (eval { require IPC::Cmd; 1; }) {
2450         IPC::Cmd->import();
2451         return scalar IPC::Cmd::can_run($name);
2452     } else {
2453         # if there is $directories component in splitpath,
2454         # then it's not something to test with $PATH...
2455         return $name if (File::Spec->splitpath($name))[1];
2456
2457         foreach (File::Spec->path()) {
2458             my $fullpath = catfile($_, "$name$target{exe_extension}");
2459             if (-f $fullpath and -x $fullpath) {
2460                 return $fullpath;
2461             }
2462         }
2463     }
2464 }
2465
2466 # Configuration printer ##############################################
2467
2468 sub print_table_entry
2469 {
2470     my $target = shift;
2471     my %target = resolve_config($target);
2472     my $type = shift;
2473
2474     # Don't print the templates
2475     return if $target{template};
2476
2477     my @sequence = (
2478         "sys_id",
2479         "cc",
2480         "cflags",
2481         "defines",
2482         "unistd",
2483         "ld",
2484         "lflags",
2485         "loutflag",
2486         "plib_lflags",
2487         "ex_libs",
2488         "bn_ops",
2489         "apps_aux_src",
2490         "cpuid_asm_src",
2491         "uplink_aux_src",
2492         "bn_asm_src",
2493         "ec_asm_src",
2494         "des_asm_src",
2495         "aes_asm_src",
2496         "bf_asm_src",
2497         "md5_asm_src",
2498         "cast_asm_src",
2499         "sha1_asm_src",
2500         "rc4_asm_src",
2501         "rmd160_asm_src",
2502         "rc5_asm_src",
2503         "wp_asm_src",
2504         "cmll_asm_src",
2505         "modes_asm_src",
2506         "padlock_asm_src",
2507         "chacha_asm_src",
2508         "poly1035_asm_src",
2509         "thread_scheme",
2510         "perlasm_scheme",
2511         "dso_scheme",
2512         "shared_target",
2513         "shared_cflag",
2514         "shared_defines",
2515         "shared_ldflag",
2516         "shared_rcflag",
2517         "shared_extension",
2518         "dso_extension",
2519         "obj_extension",
2520         "exe_extension",
2521         "ranlib",
2522         "ar",
2523         "arflags",
2524         "aroutflag",
2525         "rc",
2526         "rcflags",
2527         "rcoutflag",
2528         "mt",
2529         "mtflags",
2530         "mtinflag",
2531         "mtoutflag",
2532         "multilib",
2533         "build_scheme",
2534         );
2535
2536     if ($type eq "TABLE") {
2537         print "\n";
2538         print "*** $target\n";
2539         foreach (@sequence) {
2540             if (ref($target{$_}) eq "ARRAY") {
2541                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2542             } else {
2543                 printf "\$%-12s = %s\n", $_, $target{$_};
2544             }
2545         }
2546     } elsif ($type eq "HASH") {
2547         my $largest =
2548             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2549         print "    '$target' => {\n";
2550         foreach (@sequence) {
2551             if ($target{$_}) {
2552                 if (ref($target{$_}) eq "ARRAY") {
2553                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2554                 } else {
2555                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2556                 }
2557             }
2558         }
2559         print "    },\n";
2560     }
2561 }
2562
2563 # Utility routines ###################################################
2564
2565 # On VMS, if the given file is a logical name, File::Spec::Functions
2566 # will consider it an absolute path.  There are cases when we want a
2567 # purely syntactic check without checking the environment.
2568 sub isabsolute {
2569     my $file = shift;
2570
2571     # On non-platforms, we just use file_name_is_absolute().
2572     return file_name_is_absolute($file) unless $^O eq "VMS";
2573
2574     # If the file spec includes a device or a directpry spec,
2575     # file_name_is_absolute() is perfectly safe.
2576     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2577
2578     # Here, we know the given file spec isn't absolute
2579     return 0;
2580 }
2581
2582 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2583 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2584 # realpath() requires that at least all path components except the last is an
2585 # existing directory.  On VMS, the last component of the directory spec must
2586 # exist.
2587 sub absolutedir {
2588     my $dir = shift;
2589
2590     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2591     # will return the volume name for the device, no matter what.  Also,
2592     # it will return an incorrect directory spec if the argument is a
2593     # directory that doesn't exist.
2594     if ($^O eq "VMS") {
2595         return rel2abs($dir);
2596     }
2597
2598     # We use realpath() on Unix, since no other will properly clean out
2599     # a directory spec.
2600     use Cwd qw/realpath/;
2601
2602     return realpath($dir);
2603 }
2604
2605 sub quotify {
2606     my %processors = (
2607         perl    => sub { my $x = shift;
2608                          $x =~ s/([\\\$\@"])/\\$1/g;
2609                          return '"'.$x.'"'; },
2610         maybeshell => sub { my $x = shift;
2611                             (my $y = $x) =~ s/([\\\"])/\\$1/g;
2612                             if ($x ne $y || $x =~ m|\s|) {
2613                                 return '"'.$y.'"';
2614                             } else {
2615                                 return $x;
2616                             }
2617                         },
2618         );
2619     my $for = shift;
2620     my $processor =
2621         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2622
2623     return map { $processor->($_); } @_;
2624 }
2625
2626 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2627 # $filename is a file name to read from
2628 # $line_concat_cond_re is a regexp detecting a line continuation ending
2629 # $line_concat is a CODEref that takes care of concatenating two lines
2630 sub collect_from_file {
2631     my $filename = shift;
2632     my $line_concat_cond_re = shift;
2633     my $line_concat = shift;
2634
2635     open my $fh, $filename || die "unable to read $filename: $!\n";
2636     return sub {
2637         my $saved_line = "";
2638         $_ = "";
2639         while (<$fh>) {
2640             s|\R$||;
2641             if (defined $line_concat) {
2642                 $_ = $line_concat->($saved_line, $_);
2643                 $saved_line = "";
2644             }
2645             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2646                 $saved_line = $_;
2647                 next;
2648             }
2649             return $_;
2650         }
2651         die "$filename ending with continuation line\n" if $_;
2652         close $fh;
2653         return undef;
2654     }
2655 }
2656
2657 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2658 # $array is an ARRAYref of lines
2659 # $line_concat_cond_re is a regexp detecting a line continuation ending
2660 # $line_concat is a CODEref that takes care of concatenating two lines
2661 sub collect_from_array {
2662     my $array = shift;
2663     my $line_concat_cond_re = shift;
2664     my $line_concat = shift;
2665     my @array = (@$array);
2666
2667     return sub {
2668         my $saved_line = "";
2669         $_ = "";
2670         while (defined($_ = shift @array)) {
2671             s|\R$||;
2672             if (defined $line_concat) {
2673                 $_ = $line_concat->($saved_line, $_);
2674                 $saved_line = "";
2675             }
2676             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2677                 $saved_line = $_;
2678                 next;
2679             }
2680             return $_;
2681         }
2682         die "input text ending with continuation line\n" if $_;
2683         return undef;
2684     }
2685 }
2686
2687 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2688 # $lineiterator is a CODEref that delivers one line at a time.
2689 # All following arguments are regex/CODEref pairs, where the regexp detects a
2690 # line and the CODEref does something with the result of the regexp.
2691 sub collect_information {
2692     my $lineiterator = shift;
2693     my %collectors = @_;
2694
2695     while(defined($_ = $lineiterator->())) {
2696         s|\R$||;
2697         my $found = 0;
2698         if ($collectors{"BEFORE"}) {
2699             $collectors{"BEFORE"}->($_);
2700         }
2701         foreach my $re (keys %collectors) {
2702             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2703                 $collectors{$re}->($lineiterator);
2704                 $found = 1;
2705             };
2706         }
2707         if ($collectors{"OTHERWISE"}) {
2708             $collectors{"OTHERWISE"}->($lineiterator, $_)
2709                 unless $found || !defined $collectors{"OTHERWISE"};
2710         }
2711         if ($collectors{"AFTER"}) {
2712             $collectors{"AFTER"}->($_);
2713         }
2714     }
2715 }
2716
2717 # tokenize($line)
2718 # $line is a line of text to split up into tokens
2719 # returns a list of tokens
2720 #
2721 # Tokens are divided by spaces.  If the tokens include spaces, they
2722 # have to be quoted with single or double quotes.  Double quotes
2723 # inside a double quoted token must be escaped.  Escaping is done
2724 # with backslash.
2725 # Basically, the same quoting rules apply for " and ' as in any
2726 # Unix shell.
2727 sub tokenize {
2728     my $line = my $debug_line = shift;
2729     my @result = ();
2730
2731     while ($line =~ s|^\s+||, $line ne "") {
2732         my $token = "";
2733         while ($line ne "" && $line !~ m|^\s|) {
2734             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2735                 $token .= $1;
2736                 $line = $';
2737             } elsif ($line =~ m/^'([^']*)'/) {
2738                 $token .= $1;
2739                 $line = $';
2740             } elsif ($line =~ m/^(\S+)/) {
2741                 $token .= $1;
2742                 $line = $';
2743             }
2744         }
2745         push @result, $token;
2746     }
2747
2748     if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2749         print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2750         print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
2751     }
2752     return @result;
2753 }