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