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