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