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