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