Sort.
[openssl.git] / Configure
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3 # Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
4 #
5 # Licensed under the OpenSSL license (the "License").  You may not use
6 # this file except in compliance with the License.  You can obtain a copy
7 # in the file LICENSE in the source distribution or at
8 # https://www.openssl.org/source/license.html
9
10 ##  Configure -- OpenSSL source tree configuration script
11
12 require 5.10.0;
13 use strict;
14 use File::Basename;
15 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
16 use File::Path qw/mkpath/;
17 use if $^O ne "VMS", 'File::Glob' => qw/glob/;
18
19 # see INSTALL for instructions.
20
21 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
22
23 # Options:
24 #
25 # --config      add the given configuration file, which will be read after
26 #               any "Configurations*" files that are found in the same
27 #               directory as this script.
28 # --prefix      prefix for the OpenSSL installation, which includes the
29 #               directories bin, lib, include, share/man, share/doc/openssl
30 #               This becomes the value of INSTALLTOP in Makefile
31 #               (Default: /usr/local)
32 # --openssldir  OpenSSL data area, such as openssl.cnf, certificates and keys.
33 #               If it's a relative directory, it will be added on the directory
34 #               given with --prefix.
35 #               This becomes the value of OPENSSLDIR in Makefile and in C.
36 #               (Default: PREFIX/ssl)
37 #
38 # --cross-compile-prefix Add specified prefix to binutils components.
39 #
40 # --api         One of 0.9.8, 1.0.0 or 1.1.0.  Do not compile support for
41 #               interfaces deprecated as of the specified OpenSSL version.
42 #
43 # no-hw-xxx     do not compile support for specific crypto hardware.
44 #               Generic OpenSSL-style methods relating to this support
45 #               are always compiled but return NULL if the hardware
46 #               support isn't compiled.
47 # no-hw         do not compile support for any crypto hardware.
48 # [no-]threads  [don't] try to create a library that is suitable for
49 #               multithreaded applications (default is "threads" if we
50 #               know how to do it)
51 # [no-]shared   [don't] try to create shared libraries when supported.
52 # [no-]pic      [don't] try to build position independent code when supported.
53 #               If disabled, it also disables shared and dynamic-engine.
54 # no-asm        do not use assembler
55 # no-dso        do not compile in any native shared-library methods. This
56 #               will ensure that all methods just return NULL.
57 # no-egd        do not compile support for the entropy-gathering daemon APIs
58 # [no-]zlib     [don't] compile support for zlib compression.
59 # zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
60 #               library and will be loaded in run-time by the OpenSSL library.
61 # sctp          include SCTP support
62 # 386           generate 80386 code
63 # enable-weak-ssl-ciphers
64 #               Enable weak ciphers that are disabled by default. This currently
65 #               only includes RC4 based ciphers.
66 # no-sse2       disables IA-32 SSE2 code, above option implies no-sse2
67 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
68 # -<xxx> +<xxx> compiler options are passed through
69 #
70 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
71 #               provided to stack calls. Generates unique stack functions for
72 #               each possible stack type.
73 # BN_LLONG      use the type 'long long' in crypto/bn/bn.h
74 # RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
75 # Following are set automatically by this script
76 #
77 # MD5_ASM       use some extra md5 assembler,
78 # SHA1_ASM      use some extra sha1 assembler, must define L_ENDIAN for x86
79 # RMD160_ASM    use some extra ripemd160 assembler,
80 # SHA256_ASM    sha256_block is implemented in assembler
81 # SHA512_ASM    sha512_block is implemented in assembler
82 # AES_ASM       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                    (which("$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} = which('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     ### Make unified_info a bit more efficient
1736     # One level structures
1737     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1738         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1739     }
1740     # Two level structures
1741     foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) {
1742         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1743             $unified_info{$l1}->{$l2} =
1744                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1745         }
1746     }
1747 }
1748
1749 # For the schemes that need it, we provide the old *_obj configs
1750 # from the *_asm_obj ones
1751 foreach (grep /_(asm|aux)_src$/, keys %target) {
1752     my $src = $_;
1753     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1754     ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1755 }
1756
1757 # Write down our configuration where it fits #########################
1758
1759 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1760 print OUT <<"EOF";
1761 package configdata;
1762
1763 use strict;
1764 use warnings;
1765
1766 use Exporter;
1767 #use vars qw(\@ISA \@EXPORT);
1768 our \@ISA = qw(Exporter);
1769 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
1770
1771 EOF
1772 print OUT "our %config = (\n";
1773 foreach (sort keys %config) {
1774     if (ref($config{$_}) eq "ARRAY") {
1775         print OUT "  ", $_, " => [ ", join(", ",
1776                                            map { quotify("perl", $_) }
1777                                            @{$config{$_}}), " ],\n";
1778     } else {
1779         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1780     }
1781 }
1782 print OUT <<"EOF";
1783 );
1784
1785 EOF
1786 print OUT "our %target = (\n";
1787 foreach (sort keys %target) {
1788     if (ref($target{$_}) eq "ARRAY") {
1789         print OUT "  ", $_, " => [ ", join(", ",
1790                                            map { quotify("perl", $_) }
1791                                            @{$target{$_}}), " ],\n";
1792     } else {
1793         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1794     }
1795 }
1796 print OUT <<"EOF";
1797 );
1798
1799 EOF
1800 print OUT "our \%available_protocols = (\n";
1801 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1802 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1803 print OUT <<"EOF";
1804 );
1805
1806 EOF
1807 print OUT "our \@disablables = (\n";
1808 foreach (@disablables) {
1809     print OUT "  ", quotify("perl", $_), ",\n";
1810 }
1811 print OUT <<"EOF";
1812 );
1813
1814 EOF
1815 print OUT "our \%disabled = (\n";
1816 foreach (sort keys %disabled) {
1817     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1818 }
1819 print OUT <<"EOF";
1820 );
1821
1822 EOF
1823 print OUT "our %withargs = (\n";
1824 foreach (sort keys %withargs) {
1825     if (ref($withargs{$_}) eq "ARRAY") {
1826         print OUT "  ", $_, " => [ ", join(", ",
1827                                            map { quotify("perl", $_) }
1828                                            @{$withargs{$_}}), " ],\n";
1829     } else {
1830         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1831     }
1832 }
1833 print OUT <<"EOF";
1834 );
1835
1836 EOF
1837 if ($builder eq "unified") {
1838     my $recurse;
1839     $recurse = sub {
1840         my $indent = shift;
1841         foreach (@_) {
1842             if (ref $_ eq "ARRAY") {
1843                 print OUT " "x$indent, "[\n";
1844                 foreach (@$_) {
1845                     $recurse->($indent + 4, $_);
1846                 }
1847                 print OUT " "x$indent, "],\n";
1848             } elsif (ref $_ eq "HASH") {
1849                 my %h = %$_;
1850                 print OUT " "x$indent, "{\n";
1851                 foreach (sort keys %h) {
1852                     if (ref $h{$_} eq "") {
1853                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1854                     } else {
1855                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1856                         $recurse->($indent + 8, $h{$_});
1857                     }
1858                 }
1859                 print OUT " "x$indent, "},\n";
1860             } else {
1861                 print OUT " "x$indent, quotify("perl", $_), ",\n";
1862             }
1863         }
1864     };
1865     print OUT "our %unified_info = (\n";
1866     foreach (sort keys %unified_info) {
1867         if (ref $unified_info{$_} eq "") {
1868             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1869         } else {
1870             print OUT " "x4, quotify("perl", $_), " =>\n";
1871             $recurse->(8, $unified_info{$_});
1872         }
1873     }
1874     print OUT <<"EOF";
1875 );
1876
1877 EOF
1878 }
1879 print OUT "1;\n";
1880 close(OUT);
1881
1882
1883 print "CC            =$config{cross_compile_prefix}$target{cc}\n";
1884 print "CFLAG         =$target{cflags} $config{cflags}\n";
1885 print "SHARED_CFLAG  =$target{shared_cflag}\n";
1886 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
1887 print "LFLAG         =$target{lflags}\n";
1888 print "PLIB_LFLAG    =$target{plib_lflags}\n";
1889 print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
1890 print "APPS_OBJ      =$target{apps_obj}\n";
1891 print "CPUID_OBJ     =$target{cpuid_obj}\n";
1892 print "UPLINK_OBJ    =$target{uplink_obj}\n";
1893 print "BN_ASM        =$target{bn_obj}\n";
1894 print "EC_ASM        =$target{ec_obj}\n";
1895 print "DES_ENC       =$target{des_obj}\n";
1896 print "AES_ENC       =$target{aes_obj}\n";
1897 print "BF_ENC        =$target{bf_obj}\n";
1898 print "CAST_ENC      =$target{cast_obj}\n";
1899 print "RC4_ENC       =$target{rc4_obj}\n";
1900 print "RC5_ENC       =$target{rc5_obj}\n";
1901 print "MD5_OBJ_ASM   =$target{md5_obj}\n";
1902 print "SHA1_OBJ_ASM  =$target{sha1_obj}\n";
1903 print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
1904 print "CMLL_ENC      =$target{cmll_obj}\n";
1905 print "MODES_OBJ     =$target{modes_obj}\n";
1906 print "PADLOCK_OBJ   =$target{padlock_obj}\n";
1907 print "CHACHA_ENC    =$target{chacha_obj}\n";
1908 print "POLY1305_OBJ  =$target{poly1305_obj}\n";
1909 print "BLAKE2_OBJ    =$target{blake2_obj}\n";
1910 print "PROCESSOR     =$config{processor}\n";
1911 print "RANLIB        =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
1912                              "$config{cross_compile_prefix}ranlib" :
1913                              "$target{ranlib}", "\n";
1914 print "ARFLAGS       =$target{arflags}\n";
1915 print "PERL          =$config{perl}\n";
1916 print "\n";
1917 print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
1918 print "SIXTY_FOUR_BIT mode\n" if $config{b64};
1919 print "THIRTY_TWO_BIT mode\n" if $config{b32};
1920 print "BN_LLONG mode\n" if $config{bn_ll};
1921 print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int;
1922
1923 for (@generated_headers) {
1924     mkpath(catdir($blddir, dirname($_)));
1925     run_dofile(catfile($blddir, $_),
1926                catfile($srcdir, $_.".in"));
1927 }
1928
1929 ###
1930 ### When the old "unixmake" scheme goes away, so does this function
1931 ###
1932 sub build_Makefile {
1933     run_dofile("Makefile","Makefile.in");
1934
1935     # Copy all Makefile.in to Makefile (except top-level)
1936     use File::Find;
1937     use IO::File;
1938     find(
1939         {
1940             preprocess => sub {
1941                 grep(!/^\./, @_);
1942             },
1943             wanted => sub {
1944                 return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
1945                 my $in = IO::File->new($_, "r") or
1946                     die sprintf "Error reading Makefile.in in %s: !$\n",
1947                     $File::Find::dir;
1948                 my $out = IO::File->new("Makefile", "w") or
1949                     die sprintf "Error writing Makefile in %s: !$\n",
1950                     $File::Find::dir;
1951                 print $out "# Generated from $_, do not edit\n";
1952                 while (my $line = <$in>) { print $out $line }
1953                 $in->close() or
1954                     die sprintf "Error reading Makefile.in in %s: !$\n",
1955                     $File::Find::dir;
1956                 $out->close() or
1957                     die sprintf "Error writing Makefile in %s: !$\n",
1958                     $File::Find::dir;
1959             },
1960         },
1961         ".");
1962 }
1963
1964 my %builders = (
1965     unified => sub {
1966         run_dofile(catfile($blddir, $target{build_file}),
1967                    $config{build_file_template},
1968                    catfile($srcdir, "Configurations", "common.tmpl"));
1969     },
1970     unixmake => sub {
1971         build_Makefile();
1972
1973     },
1974     );
1975
1976 $builders{$builder}->($builder_platform, @builder_opts);
1977
1978 print <<"EOF";
1979
1980 Configured for $target.
1981 EOF
1982
1983 print <<"EOF" if ($disabled{threads} eq "unavailable");
1984
1985 The library could not be configured for supporting multi-threaded
1986 applications as the compiler options required on this system are not known.
1987 See file INSTALL for details if you need multi-threading.
1988 EOF
1989
1990 print <<"EOF" if ($no_shared_warn);
1991
1992 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
1993 platform, so we will pretend you gave the option 'no-pic', which also disables
1994 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
1995 or position independent code, please let us know (but please first make sure
1996 you have tried with a current version of OpenSSL).
1997 EOF
1998
1999 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2000
2001 WARNING: there are indications that another build was made in the source
2002 directory.  This build may have picked up artifacts from that build, the
2003 safest course of action is to clean the source directory and redo this
2004 configuration.
2005 EOF
2006
2007 exit(0);
2008
2009 ######################################################################
2010 #
2011 # Helpers and utility functions
2012 #
2013
2014 # Configuration file reading #########################################
2015
2016 # Note: All of the helper functions are for lazy evaluation.  They all
2017 # return a CODE ref, which will return the intended value when evaluated.
2018 # Thus, whenever there's mention of a returned value, it's about that
2019 # intended value.
2020
2021 # Helper function to implement conditional inheritance depending on the
2022 # value of $disabled{asm}.  Used in inherit_from values as follows:
2023 #
2024 #      inherit_from => [ "template", asm("asm_tmpl") ]
2025 #
2026 sub asm {
2027     my @x = @_;
2028     sub {
2029         $disabled{asm} ? () : @x;
2030     }
2031 }
2032
2033 # Helper function to implement conditional value variants, with a default
2034 # plus additional values based on the value of $config{build_type}.
2035 # Arguments are given in hash table form:
2036 #
2037 #       picker(default => "Basic string: ",
2038 #              debug   => "debug",
2039 #              release => "release")
2040 #
2041 # When configuring with --debug, the resulting string will be
2042 # "Basic string: debug", and when not, it will be "Basic string: release"
2043 #
2044 # This can be used to create variants of sets of flags according to the
2045 # build type:
2046 #
2047 #       cflags => picker(default => "-Wall",
2048 #                        debug   => "-g -O0",
2049 #                        release => "-O3")
2050 #
2051 sub picker {
2052     my %opts = @_;
2053     return sub { add($opts{default} || (),
2054                      $opts{$config{build_type}} || ())->(); }
2055 }
2056
2057 # Helper function to combine several values of different types into one.
2058 # This is useful if you want to combine a string with the result of a
2059 # lazy function, such as:
2060 #
2061 #       cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2062 #
2063 sub combine {
2064     my @stuff = @_;
2065     return sub { add(@stuff)->(); }
2066 }
2067
2068 # Helper function to implement conditional values depending on the value
2069 # of $disabled{threads}.  Can be used as follows:
2070 #
2071 #       cflags => combine("-Wall", threads("-pthread"))
2072 #
2073 sub threads {
2074     my @flags = @_;
2075     return sub { add($disabled{threads} ? () : @flags)->(); }
2076 }
2077
2078
2079
2080 our $add_called = 0;
2081 # Helper function to implement adding values to already existing configuration
2082 # values.  It handles elements that are ARRAYs, CODEs and scalars
2083 sub _add {
2084     my $separator = shift;
2085
2086     # If there's any ARRAY in the collection of values OR the separator
2087     # is undef, we will return an ARRAY of combined values, otherwise a
2088     # string of joined values with $separator as the separator.
2089     my $found_array = !defined($separator);
2090
2091     my @values =
2092         map {
2093             my $res = $_;
2094             while (ref($res) eq "CODE") {
2095                 $res = $res->();
2096             }
2097             if (defined($res)) {
2098                 if (ref($res) eq "ARRAY") {
2099                     $found_array = 1;
2100                     @$res;
2101                 } else {
2102                     $res;
2103                 }
2104             } else {
2105                 ();
2106             }
2107     } (@_);
2108
2109     $add_called = 1;
2110
2111     if ($found_array) {
2112         [ @values ];
2113     } else {
2114         join($separator, grep { defined($_) && $_ ne "" } @values);
2115     }
2116 }
2117 sub add_before {
2118     my $separator = " ";
2119     if (ref($_[$#_]) eq "HASH") {
2120         my $opts = pop;
2121         $separator = $opts->{separator};
2122     }
2123     my @x = @_;
2124     sub { _add($separator, @x, @_) };
2125 }
2126 sub add {
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
2136 # configuration reader, evaluates the input file as a perl script and expects
2137 # it to fill %targets with target configurations.  Those are then added to
2138 # %table.
2139 sub read_config {
2140     my $fname = shift;
2141     open(CONFFILE, "< $fname")
2142         or die "Can't open configuration file '$fname'!\n";
2143     my $x = $/;
2144     undef $/;
2145     my $content = <CONFFILE>;
2146     $/ = $x;
2147     close(CONFFILE);
2148     my %targets = ();
2149     {
2150         local %table = %::table;    # Protect %table from tampering
2151
2152         eval $content;
2153         warn $@ if $@;
2154     }
2155
2156     # For each target, check that it's configured with a hash table.
2157     foreach (keys %targets) {
2158         if (ref($targets{$_}) ne "HASH") {
2159             if (ref($targets{$_}) eq "") {
2160                 warn "Deprecated target configuration for $_, ignoring...\n";
2161             } else {
2162                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2163             }
2164             delete $targets{$_};
2165         }
2166     }
2167
2168     %table = (%table, %targets);
2169
2170 }
2171
2172 # configuration resolver.  Will only resolve all the lazy evaluation
2173 # codeblocks for the chosen target and all those it inherits from,
2174 # recursively
2175 sub resolve_config {
2176     my $target = shift;
2177     my @breadcrumbs = @_;
2178
2179 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2180
2181     if (grep { $_ eq $target } @breadcrumbs) {
2182         die "inherit_from loop!  target backtrace:\n  "
2183             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2184     }
2185
2186     if (!defined($table{$target})) {
2187         warn "Warning! target $target doesn't exist!\n";
2188         return ();
2189     }
2190     # Recurse through all inheritances.  They will be resolved on the
2191     # fly, so when this operation is done, they will all just be a
2192     # bunch of attributes with string values.
2193     # What we get here, though, are keys with references to lists of
2194     # the combined values of them all.  We will deal with lists after
2195     # this stage is done.
2196     my %combined_inheritance = ();
2197     if ($table{$target}->{inherit_from}) {
2198         my @inherit_from =
2199             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2200         foreach (@inherit_from) {
2201             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2202
2203             # 'template' is a marker that's considered private to
2204             # the config that had it.
2205             delete $inherited_config{template};
2206
2207             foreach (keys %inherited_config) {
2208                 if (!$combined_inheritance{$_}) {
2209                     $combined_inheritance{$_} = [];
2210                 }
2211                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2212             }
2213         }
2214     }
2215
2216     # We won't need inherit_from in this target any more, since we've
2217     # resolved all the inheritances that lead to this
2218     delete $table{$target}->{inherit_from};
2219
2220     # Now is the time to deal with those lists.  Here's the place to
2221     # decide what shall be done with those lists, all based on the
2222     # values of the target we're currently dealing with.
2223     # - If a value is a coderef, it will be executed with the list of
2224     #   inherited values as arguments.
2225     # - If the corresponding key doesn't have a value at all or is the
2226     #   empty string, the inherited value list will be run through the
2227     #   default combiner (below), and the result becomes this target's
2228     #   value.
2229     # - Otherwise, this target's value is assumed to be a string that
2230     #   will simply override the inherited list of values.
2231     my $default_combiner = add();
2232
2233     my %all_keys =
2234         map { $_ => 1 } (keys %combined_inheritance,
2235                          keys %{$table{$target}});
2236
2237     sub process_values {
2238         my $object    = shift;
2239         my $inherited = shift;  # Always a [ list ]
2240         my $target    = shift;
2241         my $entry     = shift;
2242
2243         $add_called = 0;
2244
2245         while(ref($object) eq "CODE") {
2246             $object = $object->(@$inherited);
2247         }
2248         if (!defined($object)) {
2249             return ();
2250         }
2251         elsif (ref($object) eq "ARRAY") {
2252             local $add_called;  # To make sure recursive calls don't affect it
2253             return [ map { process_values($_, $inherited, $target, $entry) }
2254                      @$object ];
2255         } elsif (ref($object) eq "") {
2256             return $object;
2257         } else {
2258             die "cannot handle reference type ",ref($object)
2259                 ," found in target ",$target," -> ",$entry,"\n";
2260         }
2261     }
2262
2263     foreach (sort keys %all_keys) {
2264         my $previous = $combined_inheritance{$_};
2265
2266         # Current target doesn't have a value for the current key?
2267         # Assign it the default combiner, the rest of this loop body
2268         # will handle it just like any other coderef.
2269         if (!exists $table{$target}->{$_}) {
2270             $table{$target}->{$_} = $default_combiner;
2271         }
2272
2273         $table{$target}->{$_} = process_values($table{$target}->{$_},
2274                                                $combined_inheritance{$_},
2275                                                $target, $_);
2276         unless(defined($table{$target}->{$_})) {
2277             delete $table{$target}->{$_};
2278         }
2279 #        if ($extra_checks &&
2280 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2281 #            warn "$_ got replaced in $target\n";
2282 #        }
2283     }
2284
2285     # Finally done, return the result.
2286     return %{$table{$target}};
2287 }
2288
2289 sub usage
2290         {
2291         print STDERR $usage;
2292         print STDERR "\npick os/compiler from:\n";
2293         my $j=0;
2294         my $i;
2295         my $k=0;
2296         foreach $i (sort keys %table)
2297                 {
2298                 next if $table{$i}->{template};
2299                 next if $i =~ /^debug/;
2300                 $k += length($i) + 1;
2301                 if ($k > 78)
2302                         {
2303                         print STDERR "\n";
2304                         $k=length($i);
2305                         }
2306                 print STDERR $i . " ";
2307                 }
2308         foreach $i (sort keys %table)
2309                 {
2310                 next if $table{$i}->{template};
2311                 next if $i !~ /^debug/;
2312                 $k += length($i) + 1;
2313                 if ($k > 78)
2314                         {
2315                         print STDERR "\n";
2316                         $k=length($i);
2317                         }
2318                 print STDERR $i . " ";
2319                 }
2320         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2321         exit(1);
2322         }
2323
2324 sub run_dofile
2325 {
2326     my $out = shift;
2327     my @templates = @_;
2328
2329     unlink $out || warn "Can't remove $out, $!"
2330         if -f $out;
2331     foreach (@templates) {
2332         die "Can't open $_, $!" unless -f $_;
2333     }
2334     my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2335     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2336     system($cmd);
2337     exit 1 if $? != 0;
2338     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2339 }
2340
2341 sub which
2342 {
2343     my ($name)=@_;
2344
2345     if (eval { require IPC::Cmd; 1; }) {
2346         IPC::Cmd->import();
2347         return scalar IPC::Cmd::can_run($name);
2348     } else {
2349         # if there is $directories component in splitpath,
2350         # then it's not something to test with $PATH...
2351         return $name if (File::Spec->splitpath($name))[1];
2352
2353         foreach (File::Spec->path()) {
2354             my $fullpath = catfile($_, "$name$target{exe_extension}");
2355             if (-f $fullpath and -x $fullpath) {
2356                 return $fullpath;
2357             }
2358         }
2359     }
2360 }
2361
2362 # Configuration printer ##############################################
2363
2364 sub print_table_entry
2365 {
2366     my $target = shift;
2367     my %target = resolve_config($target);
2368     my $type = shift;
2369
2370     # Don't print the templates
2371     return if $target{template};
2372
2373     my @sequence = (
2374         "sys_id",
2375         "cc",
2376         "cflags",
2377         "defines",
2378         "unistd",
2379         "ld",
2380         "lflags",
2381         "plib_lflags",
2382         "ex_libs",
2383         "bn_ops",
2384         "cpuid_obj",
2385         "bn_obj",
2386         "ec_obj",
2387         "des_obj",
2388         "aes_obj",
2389         "bf_obj",
2390         "md5_obj",
2391         "sha1_obj",
2392         "cast_obj",
2393         "rc4_obj",
2394         "rmd160_obj",
2395         "rc5_obj",
2396         "wp_obj",
2397         "cmll_obj",
2398         "modes_obj",
2399         "padlock_obj",
2400         "thread_scheme",
2401         "perlasm_scheme",
2402         "dso_scheme",
2403         "shared_target",
2404         "shared_cflag",
2405         "shared_ldflag",
2406         "shared_rcflag",
2407         "shared_extension",
2408         "shared_extension_simple",
2409         "shared_import_extension",
2410         "dso_extension",
2411         "obj_extension",
2412         "exe_extension",
2413         "ranlib",
2414         "ar",
2415         "arflags",
2416         "multilib",
2417         "build_scheme",
2418         );
2419
2420     if ($type eq "TABLE") {
2421         print "\n";
2422         print "*** $target\n";
2423         foreach (@sequence) {
2424             if (ref($target{$_}) eq "ARRAY") {
2425                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2426             } else {
2427                 printf "\$%-12s = %s\n", $_, $target{$_};
2428             }
2429         }
2430     } elsif ($type eq "HASH") {
2431         my $largest =
2432             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2433         print "    '$target' => {\n";
2434         foreach (@sequence) {
2435             if ($target{$_}) {
2436                 if (ref($target{$_}) eq "ARRAY") {
2437                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2438                 } else {
2439                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2440                 }
2441             }
2442         }
2443         print "    },\n";
2444     }
2445 }
2446
2447 # Utility routines ###################################################
2448
2449 # On VMS, if the given file is a logical name, File::Spec::Functions
2450 # will consider it an absolute path.  There are cases when we want a
2451 # purely syntactic check without checking the environment.
2452 sub isabsolute {
2453     my $file = shift;
2454
2455     # On non-platforms, we just use file_name_is_absolute().
2456     return file_name_is_absolute($file) unless $^O eq "VMS";
2457
2458     # If the file spec includes a device or a directpry spec,
2459     # file_name_is_absolute() is perfectly safe.
2460     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2461
2462     # Here, we know the given file spec isn't absolute
2463     return 0;
2464 }
2465
2466 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2467 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2468 # realpath() requires that at least all path components except the last is an
2469 # existing directory.  On VMS, the last component of the directory spec must
2470 # exist.
2471 sub absolutedir {
2472     my $dir = shift;
2473
2474     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2475     # will return the volume name for the device, no matter what.  Also,
2476     # it will return an incorrect directory spec if the argument is a
2477     # directory that doesn't exist.
2478     if ($^O eq "VMS") {
2479         return rel2abs($dir);
2480     }
2481
2482     # We use realpath() on Unix, since no other will properly clean out
2483     # a directory spec.
2484     use Cwd qw/realpath/;
2485
2486     return realpath($dir);
2487 }
2488
2489 sub quotify {
2490     my %processors = (
2491         perl    => sub { my $x = shift;
2492                          $x =~ s/([\\\$\@"])/\\$1/g;
2493                          return '"'.$x.'"'; },
2494         );
2495     my $for = shift;
2496     my $processor =
2497         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2498
2499     return map { $processor->($_); } @_;
2500 }
2501
2502 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2503 # $filename is a file name to read from
2504 # $line_concat_cond_re is a regexp detecting a line continuation ending
2505 # $line_concat is a CODEref that takes care of concatenating two lines
2506 sub collect_from_file {
2507     my $filename = shift;
2508     my $line_concat_cond_re = shift;
2509     my $line_concat = shift;
2510
2511     open my $fh, $filename || die "unable to read $filename: $!\n";
2512     return sub {
2513         my $saved_line = "";
2514         $_ = "";
2515         while (<$fh>) {
2516             s|\R$||;
2517             if (defined $line_concat) {
2518                 $_ = $line_concat->($saved_line, $_);
2519                 $saved_line = "";
2520             }
2521             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2522                 $saved_line = $_;
2523                 next;
2524             }
2525             return $_;
2526         }
2527         die "$filename ending with continuation line\n" if $_;
2528         close $fh;
2529         return undef;
2530     }
2531 }
2532
2533 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2534 # $array is an ARRAYref of lines
2535 # $line_concat_cond_re is a regexp detecting a line continuation ending
2536 # $line_concat is a CODEref that takes care of concatenating two lines
2537 sub collect_from_array {
2538     my $array = shift;
2539     my $line_concat_cond_re = shift;
2540     my $line_concat = shift;
2541     my @array = (@$array);
2542
2543     return sub {
2544         my $saved_line = "";
2545         $_ = "";
2546         while (defined($_ = shift @array)) {
2547             s|\R$||;
2548             if (defined $line_concat) {
2549                 $_ = $line_concat->($saved_line, $_);
2550                 $saved_line = "";
2551             }
2552             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2553                 $saved_line = $_;
2554                 next;
2555             }
2556             return $_;
2557         }
2558         die "input text ending with continuation line\n" if $_;
2559         return undef;
2560     }
2561 }
2562
2563 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2564 # $lineiterator is a CODEref that delivers one line at a time.
2565 # All following arguments are regex/CODEref pairs, where the regexp detects a
2566 # line and the CODEref does something with the result of the regexp.
2567 sub collect_information {
2568     my $lineiterator = shift;
2569     my %collectors = @_;
2570
2571     while(defined($_ = $lineiterator->())) {
2572         s|\R$||;
2573         my $found = 0;
2574         if ($collectors{"BEFORE"}) {
2575             $collectors{"BEFORE"}->($_);
2576         }
2577         foreach my $re (keys %collectors) {
2578             if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2579                 $collectors{$re}->($lineiterator);
2580                 $found = 1;
2581             };
2582         }
2583         if ($collectors{"OTHERWISE"}) {
2584             $collectors{"OTHERWISE"}->($lineiterator, $_)
2585                 unless $found || !defined $collectors{"OTHERWISE"};
2586         }
2587         if ($collectors{"AFTER"}) {
2588             $collectors{"AFTER"}->($_);
2589         }
2590     }
2591 }
2592
2593 # tokenize($line)
2594 # $line is a line of text to split up into tokens
2595 # returns a list of tokens
2596 #
2597 # Tokens are divided by spaces.  If the tokens include spaces, they
2598 # have to be quoted with single or double quotes.  Double quotes
2599 # inside a double quoted token must be escaped.  Escaping is done
2600 # with backslash.
2601 # Basically, the same quoting rules apply for " and ' as in any
2602 # Unix shell.
2603 sub tokenize {
2604     my $line = my $debug_line = shift;
2605     my @result = ();
2606
2607     while ($line =~ s|^\s+||, $line ne "") {
2608         my $token = "";
2609         while ($line ne "" && $line !~ m|^\s|) {
2610             if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2611                 $token .= $1;
2612                 $line = $';
2613             } elsif ($line =~ m/^'([^']*)'/) {
2614                 $token .= $1;
2615                 $line = $';
2616             } elsif ($line =~ m/^(\S+)/) {
2617                 $token .= $1;
2618                 $line = $';
2619             }
2620         }
2621         push @result, $token;
2622     }
2623
2624     if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2625         print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2626         print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
2627     }
2628     return @result;
2629 }