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