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