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