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