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