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