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