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