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