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