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