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