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