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