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