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