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