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