When someone configures an out-of-source build, switch to unified
[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", "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",
273     "heartbeats",
274     "hmac",
275     "hw(-.+)?",
276     "idea",
277     "locking",
278     "md2",
279     "md4",
280     "md5",
281     "mdc2",
282     "md[-_]ghost94",
283     "nextprotoneg",
284     "ocb",
285     "ocsp",
286     "poly1305",
287     "posix-io",
288     "psk",
289     "rc2",
290     "rc4",
291     "rc5",
292     "rdrand",
293     "rfc3779",
294     "rijndael",                 # Old AES name
295     "ripemd",
296     "rmd160",
297     "rsa",
298     "scrypt",
299     "sct",
300     "sctp",
301     "seed",
302     "sha",
303     "shared",
304     "sock",
305     "srp",
306     "srtp",
307     "sse2",
308     "ssl",
309     "ssl-trace",
310     "static-engine",
311     "stdio",
312     "threads",
313     "tls",
314     "ts",
315     "ui",
316     "unit-test",
317     "whirlpool",
318     "zlib",
319     "zlib-dynamic",
320     );
321 foreach my $proto ((@tls, @dtls))
322         {
323         push(@disablables, $proto);
324         push(@disablables, "$proto-method");
325         }
326
327 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
328
329 my %disabled = ( # "what"         => "comment" [or special keyword "experimental"]
330                  "ec_nistp_64_gcc_128" => "default",
331                  "egd"            => "default",
332                  "md2"            => "default",
333                  "rc5"            => "default",
334                  "sctp"           => "default",
335                  "shared"         => "default",
336                  "ssl-trace"      => "default",
337                  "unit-test"      => "default",
338                  "zlib"           => "default",
339                  "crypto-mdebug"  => "default",
340                  "heartbeats"     => "default",
341                );
342 my @experimental = ();
343
344 # Note: => pair form used for aesthetics, not to truly make a hash table
345 my @disable_cascades = (
346     # "what"            => [ "cascade", ... ]
347     sub { $config{processor} eq "386" }
348                         => [ "sse2" ],
349     "ssl"               => [ "ssl3" ],
350     "ssl3-method"       => [ "ssl3" ],
351     "zlib"              => [ "zlib-dynamic" ],
352     "rijndael"          => [ "aes" ],
353     "des"               => [ "mdc2" ],
354     "ec"                => [ "ecdsa", "ecdh" ],
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                 {
779                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
780                 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
781                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
782                 }
783         else
784                 {
785                 my ($ALGO, $algo);
786                 ($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
787
788                 if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/
789                                 || /^autoalginit/ || /^autoerrinit/)
790                         {
791                         push @{$config{openssl_other_defines}}, "OPENSSL_NO_$ALGO";
792                         print " OPENSSL_NO_$ALGO";
793
794                         if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
795                         elsif (/^asm$/) { $no_asm = 1; }
796                         }
797                 else
798                         {
799                         ($ALGO,$algo) = ("RMD160","rmd160") if ($algo eq "ripemd");
800
801                         push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$ALGO";
802                         push @{$config{depdefines}}, "OPENSSL_NO_$ALGO";
803                         print " OPENSSL_NO_$ALGO";
804
805                         # fix-up crypto/directory name(s)
806                         $algo="whrlpool" if $algo eq "whirlpool";
807                         $algo="ripemd" if $algo eq "rmd160";
808                         @{$config{sdirs}} = grep { $_ ne $algo} @{$config{sdirs}};
809
810                         print " (skip dir)";
811                         }
812                 }
813
814         print "\n";
815         }
816
817 foreach (sort @experimental)
818         {
819         my $ALGO;
820         ($ALGO = $_) =~ tr/[a-z]/[A-Z]/;
821
822         # opensslconf.h will set OPENSSL_NO_... unless OPENSSL_EXPERIMENTAL_... is defined
823         push @{$config{openssl_experimental_defines}}, "OPENSSL_NO_$ALGO";
824         }
825
826 print "Configuring for $target\n";
827
828 # Support for legacy targets having a name starting with 'debug-'
829 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
830 if ($d) {
831     $build_prefix = "debug_";
832
833     # If we do not find debug-foo in the table, the target is set to foo.
834     if (!$table{$target}) {
835         $target = $t;
836     }
837 }
838 $config{target} = $target;
839 delete $table{$base_target}->{template}; # or the next test will fail.
840 my %target = ( %{$table{$base_target}}, resolve_config($target) );
841
842 &usage if (!%target || $target{template});
843
844 $target{exe_extension}="";
845 $target{exe_extension}=".exe" if ($config{target} eq "Cygwin" || $config{target} eq "DJGPP" || $config{target} =~ /^mingw/);
846 $target{exe_extension}=".nlm" if ($config{target} =~ /netware/);
847 $target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
848
849 $default_ranlib = which("ranlib") || "true";
850 $config{perl}   = $ENV{'PERL'} || which("perl5") || which("perl") || "perl";
851 my $make        = $ENV{'MAKE'} || "make";
852
853 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
854     if $config{cross_compile_prefix} eq "";
855
856 # Allow environment CC to override compiler...
857 $target{cc} = $ENV{CC} || $target{cc};
858
859 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
860 # or release_ attributes.
861 # Do it in such a way that no spurious space is appended (hence the grep).
862 $config{defines} = [ @{$target{defines}},
863                      @{$target{$build_prefix."defines"}} ];
864 $config{cflags} = join(" ",
865                        grep { $_ ne "" } ($target{cflags},
866                                           $target{$build_prefix."cflags"}));
867 $config{lflags} = join(" ",
868                        grep { $_ ne "" } ($target{lflags},
869                                           $target{$build_prefix."lflags"}));
870 $config{plib_lflags} = join(" ",
871                             grep { $_  ne "" } ($target{plib_lflags},
872                                                 $target{$build_prefix."plib_lflags"}));
873 $config{ex_libs} = join(" ",
874                         grep { $_  ne "" } ($target{ex_libs},
875                                             $target{$build_prefix."ex_libs"}));
876
877 $target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} || $default_ranlib;
878 $target{ar} = $ENV{'AR'} || "ar";
879 $target{arflags} = "" if !defined($target{arflags});
880 $target{nm} = "nm";
881 # Make sure build_scheme is consistent.
882 $target{build_scheme} = [ $target{build_scheme} ]
883     if ref($target{build_scheme}) ne "ARRAY";
884
885 ###### TO BE REMOVED BEFORE FINAL RELEASE
886 ######
887 ###### If the user has chosen --unified, we give it to them.
888 ###### The same happens if we detect that they try to build out-of-source.
889 if ($target{build_file} eq "Makefile"
890     && $target{build_scheme}->[0] eq "unixmake"
891     && ($unified || $srcdir ne $blddir)) {
892     $target{build_scheme} = [ "unified", "unix" ];
893 }
894
895 my ($builder, $builder_platform, @builder_opts) =
896     @{$target{build_scheme}};
897
898 push @{$config{defines}},
899     map { (my $x = $_) =~ s/^OPENSSL_NO_/OPENSSL_EXPERIMENTAL_/; $x }
900         @{$config{openssl_experimental_defines}};
901
902 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
903         {
904         $config{cflags} .= " -mno-cygwin";
905         $target{shared_ldflag} .= " -mno-cygwin";
906         }
907
908 if ($target =~ /linux.*-mips/ && !$no_asm && $user_cflags !~ /-m(ips|arch=)/) {
909         # minimally required architecture flags for assembly modules
910         $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
911         $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
912 }
913
914 my $no_shared_warn=0;
915 my $no_user_cflags=0;
916 my $no_user_defines=0;
917
918 # The DSO code currently always implements all functions so that no
919 # applications will have to worry about that from a compilation point
920 # of view. However, the "method"s may return zero unless that platform
921 # has support compiled in for them. Currently each method is enabled
922 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
923 # string entry into using the following logic;
924 if (!$no_dso && $target{dso_scheme} ne "")
925         {
926         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
927         if ($target{dso_scheme} eq "DLFCN")
928                 {
929                 $config{defines} = [ "DSO_DLFCN", "HAVE_DLFCN_H",
930                                      @{$config{defines}} ]
931                 }
932         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
933                 {
934                 $config{defines} = [ "DSO_DLFCN", @{$config{defines}} ]
935                 }
936         else
937                 {
938                 $config{defines} = [ "DSO_$target{dso_scheme}",
939                                      @{$config{defines}} ]
940                 }
941         }
942
943 my $thread_cflags = "";
944 my @thread_defines;
945 if ($target{thread_cflag} ne "(unknown)" && !$no_threads)
946         {
947         # If we know how to do it, support threads by default.
948         $threads = 1;
949         }
950 if ($target{thread_cflag} eq "(unknown)" && $threads)
951         {
952         # If the user asked for "threads", [s]he is also expected to
953         # provide any system-dependent compiler options that are
954         # necessary.
955         if ($no_user_cflags && $no_user_defines)
956                 {
957                 print "You asked for multi-threading support, but didn't\n";
958                 print "provide any system-specific compiler options\n";
959                 exit(1);
960                 }
961         push @thread_defines, "OPENSSL_THREADS";
962         }
963 else
964         {
965         $thread_cflags=" $target{thread_cflag}";
966         push @thread_defines, @{$target{thread_defines}}, "OPENSSL_THREADS";
967         }
968
969 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
970
971 if ($no_asm)
972         {
973         @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}}
974             if ($config{fips});
975         }
976
977 if ($threads)
978         {
979         $config{cflags} = "$thread_cflags $config{cflags}" if $thread_cflags;
980         push @{$config{defines}}, @thread_defines;
981         push @{$config{openssl_thread_defines}}, @thread_defines;
982         }
983
984 if ($zlib)
985         {
986         push @{$config{defines}}, "ZLIB";
987         if (defined($disabled{"zlib-dynamic"}))
988                 {
989                 if (defined($withargs{zlib_lib}))
990                         {
991                         $config{ex_libs} .= " -L" . $withargs{zlib_lib} . " -lz";
992                         }
993                 else
994                         {
995                         $config{ex_libs} .= " -lz";
996                         }
997                 }
998         else
999                 {
1000                 push @{$config{defines}}, "ZLIB_SHARED";
1001                 }
1002         }
1003
1004 # With "deprecated" disable all deprecated features.
1005 if (defined($disabled{"deprecated"})) {
1006         $config{api} = $maxapi;
1007 }
1008
1009 if ($target{shared_target} eq "")
1010         {
1011         $no_shared_warn = 1 if !$config{no_shared} && !$config{fips};
1012         $config{no_shared} = 1;
1013         }
1014 if (!$config{no_shared})
1015         {
1016         if ($target{shared_cflag} ne "")
1017                 {
1018                 push @{$config{defines}}, "OPENSSL_PIC";
1019                 $config{cflags} = "$target{shared_cflag} $config{cflags}";
1020                 }
1021         }
1022
1023 if ($builder ne "mk1mf")
1024         {
1025         # add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
1026         if ($config{no_shared})
1027                 {
1028                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1029                 $config{options}.=" static-engine";
1030                 }
1031         else
1032                 {
1033                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_STATIC_ENGINE";
1034                 $config{options}.=" no-static-engine";
1035                 }
1036         }
1037
1038 #
1039 # Platform fix-ups
1040 #
1041 if ($target{sys_id} ne "")
1042         {
1043         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1044         }
1045
1046 if ($target{ranlib} eq "")
1047         {
1048         $target{ranlib} = $default_ranlib;
1049         }
1050
1051 if (!$no_asm) {
1052     $target{cpuid_asm_src}=$table{BASE}->{cpuid_asm_src} if ($config{processor} eq "386");
1053     $target{cpuid_asm_src}.=" uplink.c uplink-x86.s"
1054         if (grep { $_ eq "OPENSSL_USE_APPLINK"} @{$config{defines}}
1055             || $config{cflags} =~ /(?:^|\s)-DOPENSSL_USE_APPLINK(?:\s|$)/);
1056
1057     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1058
1059     # bn-586 is the only one implementing bn_*_part_words
1060     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1061     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1062
1063     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1064     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1065     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1066
1067     if ($config{fips}) {
1068         push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
1069     }
1070
1071     if ($target{sha1_asm_src}) {
1072         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1073         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1074         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1075     }
1076     if ($target{md5_asm_src}) {
1077         push @{$config{defines}}, "MD5_ASM";
1078     }
1079     $target{cast_asm_src}=$table{BASE}->{cast_asm_src} if (!$config{no_shared}); # CAST assembler is not PIC
1080     if ($target{rmd160_asm_src}) {
1081         push @{$config{defines}}, "RMD160_ASM";
1082     }
1083     if ($target{aes_asm_src}) {
1084         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1085         # aes-ctr.fake is not a real file, only indication that assembler
1086         # module implements AES_ctr32_encrypt...
1087         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1088         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1089         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1090         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1091         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1092         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1093     }
1094     if ($target{wp_asm_src} =~ /mmx/) {
1095         if ($config{processor} eq "386") {
1096             $target{wp_asm_src}=$table{BASE}->{wp_asm_src};
1097         } elsif (!$disabled{"whirlpool"}) {
1098             $config{cflags}.=" -DWHIRLPOOL_ASM";
1099         }
1100     }
1101     if ($target{modes_asm_src} =~ /ghash-/) {
1102         push @{$config{defines}}, "GHASH_ASM";
1103     }
1104     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1105         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1106     }
1107     if ($target{poly1305_asm_src} ne "") {
1108         push @{$config{defines}}, "POLY1305_ASM";
1109     }
1110 }
1111
1112 my $ecc = $target{cc};
1113 if ($^O ne "VMS") {
1114     # Is the compiler gcc or clang?  $ecc is used below to see if
1115     # error-checking can be turned on.
1116     my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1117     $config{makedepprog} = 'makedepend';
1118     open(PIPE, "$ccpcc --version 2>&1 | head -2 |");
1119     while ( <PIPE> ) {
1120         $config{makedepprog} = $ccpcc if /clang|gcc/;
1121         $ecc = "clang" if /clang/;
1122         $ecc = "gcc" if /gcc/;
1123     }
1124     close(PIPE);
1125 }
1126
1127 $config{depflags} =~ s/^\s*//;
1128
1129
1130 # Deal with bn_ops ###################################################
1131
1132 $config{bn_ll}                  =0;
1133 $config{export_var_as_fn}       =0;
1134 my $def_int="unsigned int";
1135 $config{rc4_int}                =$def_int;
1136 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1137
1138 my $count = 0;
1139 foreach (sort split(/\s+/,$target{bn_ops})) {
1140     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1141     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1142     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1143     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1144     ($config{b64l},$config{b64},$config{b32})
1145         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1146     ($config{b64l},$config{b64},$config{b32})
1147         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1148     ($config{b64l},$config{b64},$config{b32})
1149         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1150 }
1151 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1152     if $count > 1;
1153
1154
1155 # Hack cflags for better warnings (dev option) #######################
1156
1157 # "Stringify" the C flags string.  This permits it to be made part of a string
1158 # and works as well on command lines.
1159 $config{cflags} =~ s/([\\\"])/\\\1/g;
1160
1161 if (defined($config{api})) {
1162     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1163     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1164     push @default_depdefines, $apiflag;
1165     push @{$config{defines}}, $apiflag;
1166 }
1167
1168 if ($strict_warnings)
1169         {
1170         my $wopt;
1171         die "ERROR --strict-warnings requires gcc or clang"
1172             unless $ecc eq 'gcc' || $ecc eq 'clang';
1173         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1174                 {
1175                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1176                 }
1177         if ($ecc eq "clang")
1178                 {
1179                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1180                         {
1181                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1182                         }
1183                 }
1184         }
1185
1186 unless ($disabled{"crypto-mdebug-backtrace"})
1187         {
1188         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1189                 {
1190                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1191                 }
1192         if ($target =~ /^BSD-/)
1193                 {
1194                 $config{ex_libs} .= " -lexecinfo";
1195                 }
1196         }
1197
1198 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; }
1199 else                    { $no_user_cflags=1;  }
1200 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1201 else               { $no_user_defines=1;    }
1202
1203 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1204
1205 # If we use the unified build, collect information from build.info files
1206 my %unified_info = ();
1207
1208 if ($builder eq "unified") {
1209     # Store the name of the template file we will build the build file from
1210     # in %config.  This may be useful for the build file itself.
1211     my $build_file_template =
1212         catfile($srcdir, "Configurations",
1213                 $builder_platform."-".$target{build_file}.".tmpl");
1214     $build_file_template =
1215         catfile($srcdir, "Configurations", $target{build_file}.".tmpl")
1216         if (! -f $build_file_template);
1217     $config{build_file_template} = $build_file_template;
1218
1219     use lib catdir(dirname(__FILE__),"util");
1220     use with_fallback qw(Text::Template);
1221
1222     sub cleandir {
1223         my $base = shift;
1224         my $dir = shift;
1225         my $relativeto = shift || ".";
1226
1227         $dir = catdir($base,$dir) unless isabsolute($dir);
1228
1229         # Make sure the directories we're building in exists
1230         mkpath($dir);
1231
1232         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1233         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1234         return $res;
1235     }
1236
1237     sub cleanfile {
1238         my $base = shift;
1239         my $file = shift;
1240         my $relativeto = shift || ".";
1241
1242         $file = catfile($base,$file) unless isabsolute($file);
1243
1244         my $d = dirname($file);
1245         my $f = basename($file);
1246
1247         # Make sure the directories we're building in exists
1248         mkpath($d);
1249
1250         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1251         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1252         return $res;
1253     }
1254
1255     my @build_infos = ( [ ".", "build.info" ] );
1256     foreach (@{$config{dirs}}) {
1257         push @build_infos, [ $_, "build.info" ]
1258             if (-f catfile($srcdir, $_, "build.info"));
1259     }
1260     foreach (@{$config{sdirs}}) {
1261         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1262             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1263     }
1264     foreach (@{$config{engdirs}}) {
1265         push @build_infos, [ catdir("engines", $_), "build.info" ]
1266             if (-f catfile($srcdir, "engines", $_, "build.info"));
1267     }
1268
1269     foreach (@build_infos) {
1270         my $sourced = catdir($srcdir, $_->[0]);
1271         my $buildd = catdir($blddir, $_->[0]);
1272
1273         mkpath($buildd);
1274
1275         my $f = $_->[1];
1276         # The basic things we're trying to build
1277         my @programs = ();
1278         my @libraries = ();
1279         my @engines = ();
1280         my @scripts = ();
1281         my @extra = ();
1282         my @intermediates = ();
1283         my @rawlines = ();
1284
1285         my %ordinals = ();
1286         my %sources = ();
1287         my %includes = ();
1288         my %depends = ();
1289         my %renames = ();
1290         my %sharednames = ();
1291
1292         my $template = Text::Template->new(TYPE => 'FILE',
1293                                            SOURCE => catfile($sourced, $f));
1294         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1295         my @text =
1296             split /^/m,
1297             $template->fill_in(HASH => { config => \%config,
1298                                          target => \%target,
1299                                          builddir => abs2rel($buildd, $blddir),
1300                                          sourcedir => abs2rel($sourced, $blddir),
1301                                          buildtop => abs2rel($blddir, $blddir),
1302                                          sourcetop => abs2rel($srcdir, $blddir) },
1303                                DELIMITERS => [ "{-", "-}" ]);
1304
1305         # The top item of this stack has the following values
1306         # -2 positive already run and we found ELSE (following ELSIF should fail)
1307         # -1 positive already run (skip until ENDIF)
1308         # 0 negatives so far (if we're at a condition, check it)
1309         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1310         # 2 positive ELSE (following ELSIF should fail)
1311         my @skip = ();
1312         collect_information(
1313             collect_from_array([ @text ],
1314                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1315                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1316             # Info we're looking for
1317             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1318             => sub { push @skip, !! $1; },
1319             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1320             => sub { die "ELSIF out of scope" if ! @skip;
1321                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1322                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1323                      $skip[$#skip] = !! $1
1324                          if $skip[$#skip] == 0; },
1325             qr/^\s*ELSE\s*$/
1326             => sub { die "ELSE out of scope" if ! @skip;
1327                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1328                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1329             qr/^\s*ENDIF\s*$/
1330             => sub { die "ENDIF out of scope" if ! @skip;
1331                      pop @skip; },
1332             qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
1333             => sub { push @programs, split(/\s+/, $1)
1334                          if !@skip || $skip[$#skip] > 0 },
1335             qr/^\s*LIBS\s*=\s*(.*)\s*$/
1336             => sub { push @libraries, split(/\s+/, $1)
1337                          if !@skip || $skip[$#skip] > 0 },
1338             qr/^\s*ENGINES\s*=\s*(.*)\s*$/
1339             => sub { push @engines, split(/\s+/, $1)
1340                          if !@skip || $skip[$#skip] > 0 },
1341             qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
1342             => sub { push @scripts, split(/\s+/, $1)
1343                          if !@skip || $skip[$#skip] > 0 },
1344             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1345             => sub { push @extra, split(/\s+/, $1)
1346                          if !@skip || $skip[$#skip] > 0 },
1347
1348             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1349             => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
1350                          if !@skip || $skip[$#skip] > 0 },
1351             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1352             => sub { push @{$sources{$1}}, split(/\s+/, $2)
1353                          if !@skip || $skip[$#skip] > 0 },
1354             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1355             => sub { push @{$includes{$1}}, split(/\s+/, $2)
1356                          if !@skip || $skip[$#skip] > 0 },
1357             qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1358             => sub { push @{$depends{$1}}, split(/\s+/, $2)
1359                          if !@skip || $skip[$#skip] > 0 },
1360             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1361             => sub { push @{$renames{$1}}, split(/\s+/, $2)
1362                          if !@skip || $skip[$#skip] > 0 },
1363             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1364             => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
1365                          if !@skip || $skip[$#skip] > 0 },
1366             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1367             => sub {
1368                 my $lineiterator = shift;
1369                 my $target_kind = $1;
1370                 while (defined $lineiterator->()) {
1371                     s|\R$||;
1372                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1373                         die "ENDRAW doesn't match BEGINRAW"
1374                             if $1 ne $target_kind;
1375                         last;
1376                     }
1377                     next if @skip && $skip[$#skip] <= 0;
1378                     push @rawlines,  $_
1379                         if ($target_kind eq $target{build_file}
1380                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1381                 }
1382             },
1383             qr/^(?:#.*|\s*)$/ => sub { },
1384             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
1385             );
1386         die "runaway IF?" if (@skip);
1387
1388         foreach (keys %renames) {
1389             die "$_ renamed to more than one thing: "
1390                 ,join(" ", @{$renames{$_}}),"\n"
1391                 if scalar @{$renames{$_}} > 1;
1392             my $dest = cleanfile($buildd, $_, $blddir);
1393             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1394             die "$dest renamed to more than one thing: "
1395                 ,$unified_info{rename}->{$dest}, $to
1396                 unless !defined($unified_info{rename}->{$dest})
1397                 or $unified_info{rename}->{$dest} eq $to;
1398             $unified_info{rename}->{$dest} = $to;
1399         }
1400
1401         foreach (@programs) {
1402             my $program = cleanfile($buildd, $_, $blddir);
1403             if ($unified_info{rename}->{$program}) {
1404                 $program = $unified_info{rename}->{$program};
1405             }
1406             $unified_info{programs}->{$program} = 1;
1407         }
1408
1409         foreach (@libraries) {
1410             my $library = cleanfile($buildd, $_, $blddir);
1411             if ($unified_info{rename}->{$library}) {
1412                 $library = $unified_info{rename}->{$library};
1413             }
1414             $unified_info{libraries}->{$library} = 1;
1415         }
1416
1417         die <<"EOF" if $config{no_shared} && scalar @engines;
1418 ENGINES can only be used if configured with 'shared'.
1419 This is usually a fault in a build.info file.
1420 EOF
1421         foreach (@engines) {
1422             my $library = cleanfile($buildd, $_, $blddir);
1423             if ($unified_info{rename}->{$library}) {
1424                 $library = $unified_info{rename}->{$library};
1425             }
1426             $unified_info{engines}->{$library} = 1;
1427         }
1428
1429         foreach (@scripts) {
1430             my $script = cleanfile($buildd, $_, $blddir);
1431             if ($unified_info{rename}->{$script}) {
1432                 $script = $unified_info{rename}->{$script};
1433             }
1434             $unified_info{scripts}->{$script} = 1;
1435         }
1436
1437         foreach (@extra) {
1438             my $extra = cleanfile($buildd, $_, $blddir);
1439             $unified_info{extra}->{$extra} = 1;
1440         }
1441
1442         push @{$unified_info{rawlines}}, @rawlines;
1443
1444         if (!$config{no_shared}) {
1445             # Check sharednames.
1446             foreach (keys %sharednames) {
1447                 my $dest = cleanfile($buildd, $_, $blddir);
1448                 if ($unified_info{rename}->{$dest}) {
1449                     $dest = $unified_info{rename}->{$dest};
1450                 }
1451                 die "shared_name for $dest with multiple values: "
1452                     ,join(" ", @{$sharednames{$_}}),"\n"
1453                     if scalar @{$sharednames{$_}} > 1;
1454                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1455                 die "shared_name found for a library $dest that isn't defined\n"
1456                     unless $unified_info{libraries}->{$dest};
1457                 die "shared_name for $dest with multiple values: "
1458                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1459                     unless !defined($unified_info{sharednames}->{$dest})
1460                     or $unified_info{sharednames}->{$dest} eq $to;
1461                 $unified_info{sharednames}->{$dest} = $to;
1462             }
1463
1464             # Additionally, we set up sharednames for libraries that don't
1465             # have any, as themselves.
1466             foreach (keys %{$unified_info{libraries}}) {
1467                 if (!defined $unified_info{sharednames}->{$_}) {
1468                     $unified_info{sharednames}->{$_} = $_
1469                 }
1470             }
1471         }
1472
1473         foreach (keys %ordinals) {
1474             my $dest = $_;
1475             my $ddest = cleanfile($buildd, $_, $blddir);
1476             if ($unified_info{rename}->{$ddest}) {
1477                 $ddest = $unified_info{rename}->{$ddest};
1478             }
1479             foreach (@{$ordinals{$dest}}) {
1480                 my %known_ordinals =
1481                     (
1482                      crypto =>
1483                      cleanfile($sourced, catfile("util", "libeay.num"), $blddir),
1484                      ssl =>
1485                      cleanfile($sourced, catfile("util", "ssleay.num"), $blddir)
1486                     );
1487                 my $o = $known_ordinals{$_};
1488                 die "Ordinals for $ddest defined more than once\n"
1489                     if $unified_info{ordinals}->{$ddest};
1490                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1491             }
1492         }
1493
1494         foreach (keys %sources) {
1495             my $dest = $_;
1496             my $ddest = cleanfile($buildd, $_, $blddir);
1497             if ($unified_info{rename}->{$ddest}) {
1498                 $ddest = $unified_info{rename}->{$ddest};
1499             }
1500             foreach (@{$sources{$dest}}) {
1501                 my $s = cleanfile($sourced, $_, $blddir);
1502
1503                 # If it isn't in the source tree, we assume it's generated
1504                 # in the build tree
1505                 if (! -f $s) {
1506                     $s = cleanfile($buildd, $_, $blddir);
1507                 }
1508                 # We recognise C and asm files
1509                 if ($s =~ /\.[csS]\b$/) {
1510                     (my $o = $_) =~ s/\.[csS]\b$/.o/;
1511                     $o = cleanfile($buildd, $o, $blddir);
1512                     $unified_info{sources}->{$ddest}->{$o} = 1;
1513                     $unified_info{sources}->{$o}->{$s} = 1;
1514                 } else {
1515                     $unified_info{sources}->{$ddest}->{$s} = 1;
1516                 }
1517             }
1518         }
1519
1520         foreach (keys %depends) {
1521             my $dest = $_;
1522             my $ddest = cleanfile($buildd, $_, $blddir);
1523             if ($unified_info{rename}->{$ddest}) {
1524                 $ddest = $unified_info{rename}->{$ddest};
1525             }
1526             foreach (@{$depends{$dest}}) {
1527                 my $d = cleanfile($sourced, $_, $blddir);
1528
1529                 # If we know it's generated, or assume it is because we can't
1530                 # find it in the source tree, we set file we depend on to be
1531                 # in the build tree rather than the source tree, and assume
1532                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1533                 # section or in the Makefile template.
1534                 if (! -f $d
1535                     || !(grep { $d eq $_ }
1536                          map { cleanfile($srcdir, $_, $blddir) }
1537                          (@generated_headers, @generated_by_make_headers))) {
1538                     $d = cleanfile($buildd, $_, $blddir);
1539                 }
1540                 # Take note if the file to depend on is being renamed
1541                 if ($unified_info{rename}->{$d}) {
1542                     $d = $unified_info{rename}->{$d};
1543                 }
1544                 $unified_info{depends}->{$ddest}->{$d} = 1;
1545                 # If we depend on a header file, let's make sure it
1546                 # can get included
1547                 if ($d =~ /\.h$/) {
1548                     my $i = dirname($d);
1549                     push @{$unified_info{includes}->{$ddest}}, $i
1550                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1551                 }
1552             }
1553         }
1554
1555         foreach (keys %includes) {
1556             my $dest = $_;
1557             my $ddest = cleanfile($buildd, $_, $blddir);
1558             if ($unified_info{rename}->{$ddest}) {
1559                 $ddest = $unified_info{rename}->{$ddest};
1560             }
1561             foreach (@{$includes{$dest}}) {
1562                 my $i = cleandir($sourced, $_, $blddir);
1563                 push @{$unified_info{includes}->{$ddest}}, $i
1564                     unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1565             }
1566         }
1567     }
1568
1569     ### Make unified_info a bit more efficient
1570     # One level structures
1571     foreach (("programs", "libraries", "engines", "scripts", "extra")) {
1572         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1573     }
1574     # Two level structures
1575     foreach my $l1 (("sources", "ldadd", "depends")) {
1576         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1577             $unified_info{$l1}->{$l2} =
1578                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1579         }
1580     }
1581 }
1582
1583 # For the schemes that need it, we provide the old *_obj configs
1584 # from the *_asm_obj ones
1585 foreach (grep /_asm_src$/, keys %target) {
1586     my $src = $_;
1587     (my $obj = $_) =~ s/_asm_src$/_obj/;
1588     ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1589 }
1590
1591 # Write down our configuration where it fits #########################
1592
1593 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1594 print OUT <<"EOF";
1595 package configdata;
1596
1597 use strict;
1598 use warnings;
1599
1600 use Exporter;
1601 #use vars qw(\@ISA \@EXPORT);
1602 our \@ISA = qw(Exporter);
1603 our \@EXPORT = qw(\%config \%target %withargs %unified_info);
1604
1605 EOF
1606 print OUT "our %config = (\n";
1607 foreach (sort keys %config) {
1608     if (ref($config{$_}) eq "ARRAY") {
1609         print OUT "  ", $_, " => [ ", join(", ",
1610                                            map { quotify("perl", $_) }
1611                                            @{$config{$_}}), " ],\n";
1612     } else {
1613         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1614     }
1615 }
1616 print OUT <<"EOF";
1617 );
1618
1619 EOF
1620 print OUT "our %target = (\n";
1621 foreach (sort keys %target) {
1622     if (ref($target{$_}) eq "ARRAY") {
1623         print OUT "  ", $_, " => [ ", join(", ",
1624                                            map { quotify("perl", $_) }
1625                                            @{$target{$_}}), " ],\n";
1626     } else {
1627         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1628     }
1629 }
1630 print OUT <<"EOF";
1631 );
1632
1633 EOF
1634 print OUT "our \%available_protocols = (\n";
1635 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1636 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1637 print OUT <<"EOF";
1638 );
1639
1640 EOF
1641 print OUT "our \%disabled = (\n";
1642 foreach (sort keys %disabled) {
1643     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1644 }
1645 print OUT <<"EOF";
1646 );
1647
1648 EOF
1649 print OUT "our %withargs = (\n";
1650 foreach (sort keys %withargs) {
1651     if (ref($withargs{$_}) eq "ARRAY") {
1652         print OUT "  ", $_, " => [ ", join(", ",
1653                                            map { quotify("perl", $_) }
1654                                            @{$withargs{$_}}), " ],\n";
1655     } else {
1656         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1657     }
1658 }
1659 print OUT <<"EOF";
1660 );
1661
1662 EOF
1663 if ($builder eq "unified") {
1664     my $recurse;
1665     $recurse = sub {
1666         my $indent = shift;
1667         foreach (@_) {
1668             if (ref $_ eq "ARRAY") {
1669                 print OUT " "x$indent, "[\n";
1670                 foreach (@$_) {
1671                     $recurse->($indent + 4, $_);
1672                 }
1673                 print OUT " "x$indent, "],\n";
1674             } elsif (ref $_ eq "HASH") {
1675                 my %h = %$_;
1676                 print OUT " "x$indent, "{\n";
1677                 foreach (sort keys %h) {
1678                     if (ref $h{$_} eq "") {
1679                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1680                     } else {
1681                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1682                         $recurse->($indent + 8, $h{$_});
1683                     }
1684                 }
1685                 print OUT " "x$indent, "},\n";
1686             } else {
1687                 print OUT " "x$indent, quotify("perl", $_), ",\n";
1688             }
1689         }
1690     };
1691     print OUT "our %unified_info = (\n";
1692     foreach (sort keys %unified_info) {
1693         if (ref $unified_info{$_} eq "") {
1694             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1695         } else {
1696             print OUT " "x4, quotify("perl", $_), " =>\n";
1697             $recurse->(8, $unified_info{$_});
1698         }
1699     }
1700     print OUT <<"EOF";
1701 );
1702
1703 EOF
1704 }
1705 print OUT "1;\n";
1706 close(OUT);
1707
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 }