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