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