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