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