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