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