Configure - move the addition of the zlib / libz lib to configs
[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 my $build_prefix = "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                 $build_prefix = "debug_";
595                 }
596         elsif (/^--release$/)
597                 {
598                 $build_prefix = "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     $build_prefix = "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                      @{$target{$build_prefix."defines"}} ];
871 $config{cflags} = join(" ",
872                        grep { $_ ne "" } ($target{cflags},
873                                           $target{$build_prefix."cflags"}));
874 $config{lflags} = join(" ",
875                        grep { $_ ne "" } ($target{lflags},
876                                           $target{$build_prefix."lflags"}));
877 $config{plib_lflags} = join(" ",
878                             grep { $_  ne "" } ($target{plib_lflags},
879                                                 $target{$build_prefix."plib_lflags"}));
880 $config{ex_libs} = join(" ",
881                         grep { $_  ne "" } ($target{ex_libs},
882                                             $target{$build_prefix."ex_libs"}));
883
884 # Make sure build_scheme is consistent.
885 $target{build_scheme} = [ $target{build_scheme} ]
886     if ref($target{build_scheme}) ne "ARRAY";
887
888 ###### TO BE REMOVED BEFORE FINAL RELEASE
889 ######
890 ###### If the user has chosen --unified, we give it to them.
891 ###### The same happens if we detect that they try to build out-of-source.
892 if ($target{build_file} eq "Makefile"
893     && $target{build_scheme}->[0] eq "unixmake"
894     && ($unified || $srcdir ne $blddir)) {
895     $target{build_scheme} = [ "unified", "unix" ];
896 }
897
898 my ($builder, $builder_platform, @builder_opts) =
899     @{$target{build_scheme}};
900
901 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
902         {
903         $config{cflags} .= " -mno-cygwin";
904         $target{shared_ldflag} .= " -mno-cygwin";
905         }
906
907 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
908         # minimally required architecture flags for assembly modules
909         $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
910         $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
911 }
912
913 my $no_shared_warn=0;
914 my $no_user_cflags=0;
915 my $no_user_defines=0;
916
917 # The DSO code currently always implements all functions so that no
918 # applications will have to worry about that from a compilation point
919 # of view. However, the "method"s may return zero unless that platform
920 # has support compiled in for them. Currently each method is enabled
921 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
922 # string entry into using the following logic;
923 if (!$disabled{dso} && $target{dso_scheme} ne "")
924         {
925         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
926         if ($target{dso_scheme} eq "DLFCN")
927                 {
928                 $config{defines} = [ "DSO_DLFCN", "HAVE_DLFCN_H",
929                                      @{$config{defines}} ]
930                 }
931         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
932                 {
933                 $config{defines} = [ "DSO_DLFCN", @{$config{defines}} ]
934                 }
935         else
936                 {
937                 $config{defines} = [ "DSO_$target{dso_scheme}",
938                                      @{$config{defines}} ]
939                 }
940         }
941
942 my $thread_cflags = "";
943 my @thread_defines;
944 if ($target{thread_cflag} ne "(unknown)" && !$disabled{threads})
945         {
946         # If we know how to do it, support threads by default.
947         $threads = 1;
948         }
949 if ($target{thread_cflag} eq "(unknown)" && $threads)
950         {
951         # If the user asked for "threads", [s]he is also expected to
952         # provide any system-dependent compiler options that are
953         # necessary.
954         if ($no_user_cflags && $no_user_defines)
955                 {
956                 print "You asked for multi-threading support, but didn't\n";
957                 print "provide any system-specific compiler options\n";
958                 exit(1);
959                 }
960         push @thread_defines, "OPENSSL_THREADS";
961         }
962 else
963         {
964         $thread_cflags=" $target{thread_cflag}";
965         push @thread_defines, @{$target{thread_defines}}, "OPENSSL_THREADS";
966         }
967
968 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
969
970 if ($disabled{asm})
971         {
972         @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}}
973             if ($config{fips});
974         }
975
976 if ($threads)
977         {
978         $config{cflags} = "$thread_cflags $config{cflags}" if $thread_cflags;
979         push @{$config{defines}}, @thread_defines;
980         push @{$config{openssl_thread_defines}}, @thread_defines;
981         }
982
983 # With "deprecated" disable all deprecated features.
984 if (defined($disabled{"deprecated"})) {
985         $config{api} = $maxapi;
986 }
987
988 if ($target{shared_target} eq "")
989         {
990         $no_shared_warn = 1
991             if ((!$disabled{shared} || !$disabled{"dynamic-engine"})
992                 && !$config{fips});
993         $disabled{shared} = "no-shared-target";
994         $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
995             "no-shared-target";
996         }
997
998 if ($disabled{"dynamic-engine"}) {
999         push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1000         $config{dynamic_engines} = 0;
1001 } else {
1002         push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1003         $config{dynamic_engines} = 1;
1004 }
1005
1006 #
1007 # Platform fix-ups
1008 #
1009
1010 # This saves the build files from having to check
1011 if ($disabled{pic})
1012         {
1013         $target{shared_cflag} = $target{shared_ldflag} =
1014                 $target{shared_rcflag} = "";
1015         }
1016 else
1017         {
1018         push @{$config{defines}}, "OPENSSL_PIC";
1019         }
1020
1021 if ($target{sys_id} ne "")
1022         {
1023         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1024         }
1025
1026 unless ($disabled{asm}) {
1027     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1028     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1029
1030     # bn-586 is the only one implementing bn_*_part_words
1031     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1032     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1033
1034     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1035     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1036     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1037
1038     if ($config{fips}) {
1039         push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
1040     }
1041
1042     if ($target{sha1_asm_src}) {
1043         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1044         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1045         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1046     }
1047     if ($target{md5_asm_src}) {
1048         push @{$config{defines}}, "MD5_ASM";
1049     }
1050     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1051     if ($target{rmd160_asm_src}) {
1052         push @{$config{defines}}, "RMD160_ASM";
1053     }
1054     if ($target{aes_asm_src}) {
1055         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1056         # aes-ctr.fake is not a real file, only indication that assembler
1057         # module implements AES_ctr32_encrypt...
1058         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1059         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1060         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1061         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1062         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1063         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1064     }
1065     if ($target{wp_asm_src} =~ /mmx/) {
1066         if ($config{processor} eq "386") {
1067             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1068         } elsif (!$disabled{"whirlpool"}) {
1069             $config{cflags}.=" -DWHIRLPOOL_ASM";
1070         }
1071     }
1072     if ($target{modes_asm_src} =~ /ghash-/) {
1073         push @{$config{defines}}, "GHASH_ASM";
1074     }
1075     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1076         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1077     }
1078     if ($target{poly1305_asm_src} ne "") {
1079         push @{$config{defines}}, "POLY1305_ASM";
1080     }
1081 }
1082
1083 my $ecc = $target{cc};
1084 if ($^O ne "VMS") {
1085     # Is the compiler gcc or clang?  $ecc is used below to see if
1086     # error-checking can be turned on.
1087     my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1088     $config{makedepprog} = 'makedepend';
1089     open(PIPE, "$ccpcc --version 2>&1 | head -2 |");
1090     while ( <PIPE> ) {
1091         $config{makedepprog} = $ccpcc if /clang|gcc/;
1092         $ecc = "clang" if /clang/;
1093         $ecc = "gcc" if /gcc/;
1094     }
1095     close(PIPE);
1096 }
1097
1098
1099 # Deal with bn_ops ###################################################
1100
1101 $config{bn_ll}                  =0;
1102 $config{export_var_as_fn}       =0;
1103 my $def_int="unsigned int";
1104 $config{rc4_int}                =$def_int;
1105 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1106
1107 my $count = 0;
1108 foreach (sort split(/\s+/,$target{bn_ops})) {
1109     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1110     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1111     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1112     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1113     ($config{b64l},$config{b64},$config{b32})
1114         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1115     ($config{b64l},$config{b64},$config{b32})
1116         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1117     ($config{b64l},$config{b64},$config{b32})
1118         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1119 }
1120 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1121     if $count > 1;
1122
1123
1124 # Hack cflags for better warnings (dev option) #######################
1125
1126 # "Stringify" the C flags string.  This permits it to be made part of a string
1127 # and works as well on command lines.
1128 $config{cflags} =~ s/([\\\"])/\\\1/g;
1129
1130 if (defined($config{api})) {
1131     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1132     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1133     push @{$config{defines}}, $apiflag;
1134 }
1135
1136 if ($strict_warnings)
1137         {
1138         my $wopt;
1139         die "ERROR --strict-warnings requires gcc or clang"
1140             unless $ecc eq 'gcc' || $ecc eq 'clang';
1141         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1142                 {
1143                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1144                 }
1145         if ($ecc eq "clang")
1146                 {
1147                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1148                         {
1149                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1150                         }
1151                 }
1152         }
1153
1154 unless ($disabled{"crypto-mdebug-backtrace"})
1155         {
1156         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1157                 {
1158                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1159                 }
1160         if ($target =~ /^BSD-/)
1161                 {
1162                 $config{ex_libs} .= " -lexecinfo";
1163                 }
1164         }
1165
1166 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; }
1167 else                    { $no_user_cflags=1;  }
1168 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1169 else               { $no_user_defines=1;    }
1170
1171 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1172
1173 # If we use the unified build, collect information from build.info files
1174 my %unified_info = ();
1175
1176 if ($builder eq "unified") {
1177     # Store the name of the template file we will build the build file from
1178     # in %config.  This may be useful for the build file itself.
1179     my $build_file_template =
1180         catfile($srcdir, "Configurations",
1181                 $builder_platform."-".$target{build_file}.".tmpl");
1182     $build_file_template =
1183         catfile($srcdir, "Configurations", $target{build_file}.".tmpl")
1184         if (! -f $build_file_template);
1185     $config{build_file_template} = $build_file_template;
1186
1187     use lib catdir(dirname(__FILE__),"util");
1188     use with_fallback qw(Text::Template);
1189
1190     sub cleandir {
1191         my $base = shift;
1192         my $dir = shift;
1193         my $relativeto = shift || ".";
1194
1195         $dir = catdir($base,$dir) unless isabsolute($dir);
1196
1197         # Make sure the directories we're building in exists
1198         mkpath($dir);
1199
1200         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1201         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1202         return $res;
1203     }
1204
1205     sub cleanfile {
1206         my $base = shift;
1207         my $file = shift;
1208         my $relativeto = shift || ".";
1209
1210         $file = catfile($base,$file) unless isabsolute($file);
1211
1212         my $d = dirname($file);
1213         my $f = basename($file);
1214
1215         # Make sure the directories we're building in exists
1216         mkpath($d);
1217
1218         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1219         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1220         return $res;
1221     }
1222
1223     my @build_infos = ( [ ".", "build.info" ] );
1224     foreach (@{$config{dirs}}) {
1225         push @build_infos, [ $_, "build.info" ]
1226             if (-f catfile($srcdir, $_, "build.info"));
1227     }
1228     foreach (@{$config{sdirs}}) {
1229         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1230             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1231     }
1232     foreach (@{$config{engdirs}}) {
1233         push @build_infos, [ catdir("engines", $_), "build.info" ]
1234             if (-f catfile($srcdir, "engines", $_, "build.info"));
1235     }
1236
1237     $config{build_infos} = [ ];
1238
1239     foreach (@build_infos) {
1240         my $sourced = catdir($srcdir, $_->[0]);
1241         my $buildd = catdir($blddir, $_->[0]);
1242
1243         mkpath($buildd);
1244
1245         my $f = $_->[1];
1246         # The basic things we're trying to build
1247         my @programs = ();
1248         my @libraries = ();
1249         my @engines = ();
1250         my @scripts = ();
1251         my @extra = ();
1252         my @intermediates = ();
1253         my @rawlines = ();
1254
1255         my %ordinals = ();
1256         my %sources = ();
1257         my %includes = ();
1258         my %depends = ();
1259         my %renames = ();
1260         my %sharednames = ();
1261
1262         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1263         my $template = Text::Template->new(TYPE => 'FILE',
1264                                            SOURCE => catfile($sourced, $f));
1265         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1266         my @text =
1267             split /^/m,
1268             $template->fill_in(HASH => { config => \%config,
1269                                          target => \%target,
1270                                          disabled => \%disabled,
1271                                          builddir => abs2rel($buildd, $blddir),
1272                                          sourcedir => abs2rel($sourced, $blddir),
1273                                          buildtop => abs2rel($blddir, $blddir),
1274                                          sourcetop => abs2rel($srcdir, $blddir) },
1275                                DELIMITERS => [ "{-", "-}" ]);
1276
1277         # The top item of this stack has the following values
1278         # -2 positive already run and we found ELSE (following ELSIF should fail)
1279         # -1 positive already run (skip until ENDIF)
1280         # 0 negatives so far (if we're at a condition, check it)
1281         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1282         # 2 positive ELSE (following ELSIF should fail)
1283         my @skip = ();
1284         collect_information(
1285             collect_from_array([ @text ],
1286                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1287                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1288             # Info we're looking for
1289             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1290             => sub { push @skip, !! $1; },
1291             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1292             => sub { die "ELSIF out of scope" if ! @skip;
1293                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1294                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1295                      $skip[$#skip] = !! $1
1296                          if $skip[$#skip] == 0; },
1297             qr/^\s*ELSE\s*$/
1298             => sub { die "ELSE out of scope" if ! @skip;
1299                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1300                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1301             qr/^\s*ENDIF\s*$/
1302             => sub { die "ENDIF out of scope" if ! @skip;
1303                      pop @skip; },
1304             qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
1305             => sub { push @programs, split(/\s+/, $1)
1306                          if !@skip || $skip[$#skip] > 0 },
1307             qr/^\s*LIBS\s*=\s*(.*)\s*$/
1308             => sub { push @libraries, split(/\s+/, $1)
1309                          if !@skip || $skip[$#skip] > 0 },
1310             qr/^\s*ENGINES\s*=\s*(.*)\s*$/
1311             => sub { push @engines, split(/\s+/, $1)
1312                          if !@skip || $skip[$#skip] > 0 },
1313             qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
1314             => sub { push @scripts, split(/\s+/, $1)
1315                          if !@skip || $skip[$#skip] > 0 },
1316             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1317             => sub { push @extra, split(/\s+/, $1)
1318                          if !@skip || $skip[$#skip] > 0 },
1319
1320             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1321             => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
1322                          if !@skip || $skip[$#skip] > 0 },
1323             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1324             => sub { push @{$sources{$1}}, split(/\s+/, $2)
1325                          if !@skip || $skip[$#skip] > 0 },
1326             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1327             => sub { push @{$includes{$1}}, split(/\s+/, $2)
1328                          if !@skip || $skip[$#skip] > 0 },
1329             qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1330             => sub { push @{$depends{$1}}, split(/\s+/, $2)
1331                          if !@skip || $skip[$#skip] > 0 },
1332             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1333             => sub { push @{$renames{$1}}, split(/\s+/, $2)
1334                          if !@skip || $skip[$#skip] > 0 },
1335             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1336             => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
1337                          if !@skip || $skip[$#skip] > 0 },
1338             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1339             => sub {
1340                 my $lineiterator = shift;
1341                 my $target_kind = $1;
1342                 while (defined $lineiterator->()) {
1343                     s|\R$||;
1344                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1345                         die "ENDRAW doesn't match BEGINRAW"
1346                             if $1 ne $target_kind;
1347                         last;
1348                     }
1349                     next if @skip && $skip[$#skip] <= 0;
1350                     push @rawlines,  $_
1351                         if ($target_kind eq $target{build_file}
1352                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1353                 }
1354             },
1355             qr/^(?:#.*|\s*)$/ => sub { },
1356             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
1357             );
1358         die "runaway IF?" if (@skip);
1359
1360         foreach (keys %renames) {
1361             die "$_ renamed to more than one thing: "
1362                 ,join(" ", @{$renames{$_}}),"\n"
1363                 if scalar @{$renames{$_}} > 1;
1364             my $dest = cleanfile($buildd, $_, $blddir);
1365             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1366             die "$dest renamed to more than one thing: "
1367                 ,$unified_info{rename}->{$dest}, $to
1368                 unless !defined($unified_info{rename}->{$dest})
1369                 or $unified_info{rename}->{$dest} eq $to;
1370             $unified_info{rename}->{$dest} = $to;
1371         }
1372
1373         foreach (@programs) {
1374             my $program = cleanfile($buildd, $_, $blddir);
1375             if ($unified_info{rename}->{$program}) {
1376                 $program = $unified_info{rename}->{$program};
1377             }
1378             $unified_info{programs}->{$program} = 1;
1379         }
1380
1381         foreach (@libraries) {
1382             my $library = cleanfile($buildd, $_, $blddir);
1383             if ($unified_info{rename}->{$library}) {
1384                 $library = $unified_info{rename}->{$library};
1385             }
1386             $unified_info{libraries}->{$library} = 1;
1387         }
1388
1389         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1390 ENGINES can only be used if configured with 'dynamic-engine'.
1391 This is usually a fault in a build.info file.
1392 EOF
1393         foreach (@engines) {
1394             my $library = cleanfile($buildd, $_, $blddir);
1395             if ($unified_info{rename}->{$library}) {
1396                 $library = $unified_info{rename}->{$library};
1397             }
1398             $unified_info{engines}->{$library} = 1;
1399         }
1400
1401         foreach (@scripts) {
1402             my $script = cleanfile($buildd, $_, $blddir);
1403             if ($unified_info{rename}->{$script}) {
1404                 $script = $unified_info{rename}->{$script};
1405             }
1406             $unified_info{scripts}->{$script} = 1;
1407         }
1408
1409         foreach (@extra) {
1410             my $extra = cleanfile($buildd, $_, $blddir);
1411             $unified_info{extra}->{$extra} = 1;
1412         }
1413
1414         push @{$unified_info{rawlines}}, @rawlines;
1415
1416         unless ($disabled{shared}) {
1417             # Check sharednames.
1418             foreach (keys %sharednames) {
1419                 my $dest = cleanfile($buildd, $_, $blddir);
1420                 if ($unified_info{rename}->{$dest}) {
1421                     $dest = $unified_info{rename}->{$dest};
1422                 }
1423                 die "shared_name for $dest with multiple values: "
1424                     ,join(" ", @{$sharednames{$_}}),"\n"
1425                     if scalar @{$sharednames{$_}} > 1;
1426                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1427                 die "shared_name found for a library $dest that isn't defined\n"
1428                     unless $unified_info{libraries}->{$dest};
1429                 die "shared_name for $dest with multiple values: "
1430                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1431                     unless !defined($unified_info{sharednames}->{$dest})
1432                     or $unified_info{sharednames}->{$dest} eq $to;
1433                 $unified_info{sharednames}->{$dest} = $to;
1434             }
1435
1436             # Additionally, we set up sharednames for libraries that don't
1437             # have any, as themselves.
1438             foreach (keys %{$unified_info{libraries}}) {
1439                 if (!defined $unified_info{sharednames}->{$_}) {
1440                     $unified_info{sharednames}->{$_} = $_
1441                 }
1442             }
1443         }
1444
1445         foreach (keys %ordinals) {
1446             my $dest = $_;
1447             my $ddest = cleanfile($buildd, $_, $blddir);
1448             if ($unified_info{rename}->{$ddest}) {
1449                 $ddest = $unified_info{rename}->{$ddest};
1450             }
1451             foreach (@{$ordinals{$dest}}) {
1452                 my %known_ordinals =
1453                     (
1454                      crypto =>
1455                      cleanfile($sourced, catfile("util", "libeay.num"), $blddir),
1456                      ssl =>
1457                      cleanfile($sourced, catfile("util", "ssleay.num"), $blddir)
1458                     );
1459                 my $o = $known_ordinals{$_};
1460                 die "Ordinals for $ddest defined more than once\n"
1461                     if $unified_info{ordinals}->{$ddest};
1462                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1463             }
1464         }
1465
1466         foreach (keys %sources) {
1467             my $dest = $_;
1468             my $ddest = cleanfile($buildd, $_, $blddir);
1469             if ($unified_info{rename}->{$ddest}) {
1470                 $ddest = $unified_info{rename}->{$ddest};
1471             }
1472             foreach (@{$sources{$dest}}) {
1473                 my $s = cleanfile($sourced, $_, $blddir);
1474
1475                 # If it isn't in the source tree, we assume it's generated
1476                 # in the build tree
1477                 if (! -f $s) {
1478                     $s = cleanfile($buildd, $_, $blddir);
1479                 }
1480                 # We recognise C and asm files
1481                 if ($s =~ /\.[csS]\b$/) {
1482                     (my $o = $_) =~ s/\.[csS]\b$/.o/;
1483                     $o = cleanfile($buildd, $o, $blddir);
1484                     $unified_info{sources}->{$ddest}->{$o} = 1;
1485                     $unified_info{sources}->{$o}->{$s} = 1;
1486                 } else {
1487                     $unified_info{sources}->{$ddest}->{$s} = 1;
1488                 }
1489             }
1490         }
1491
1492         foreach (keys %depends) {
1493             my $dest = $_;
1494             my $ddest = cleanfile($buildd, $_, $blddir);
1495             if ($unified_info{rename}->{$ddest}) {
1496                 $ddest = $unified_info{rename}->{$ddest};
1497             }
1498             foreach (@{$depends{$dest}}) {
1499                 my $d = cleanfile($sourced, $_, $blddir);
1500
1501                 # If we know it's generated, or assume it is because we can't
1502                 # find it in the source tree, we set file we depend on to be
1503                 # in the build tree rather than the source tree, and assume
1504                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1505                 # section or in the Makefile template.
1506                 if (! -f $d
1507                     || !(grep { $d eq $_ }
1508                          map { cleanfile($srcdir, $_, $blddir) }
1509                          (@generated_headers, @generated_by_make_headers))) {
1510                     $d = cleanfile($buildd, $_, $blddir);
1511                 }
1512                 # Take note if the file to depend on is being renamed
1513                 if ($unified_info{rename}->{$d}) {
1514                     $d = $unified_info{rename}->{$d};
1515                 }
1516                 $unified_info{depends}->{$ddest}->{$d} = 1;
1517                 # If we depend on a header file, let's make sure it
1518                 # can get included
1519                 if ($d =~ /\.h$/) {
1520                     my $i = dirname($d);
1521                     push @{$unified_info{includes}->{$ddest}}, $i
1522                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1523                 }
1524             }
1525         }
1526
1527         foreach (keys %includes) {
1528             my $dest = $_;
1529             my $ddest = cleanfile($buildd, $_, $blddir);
1530             if ($unified_info{rename}->{$ddest}) {
1531                 $ddest = $unified_info{rename}->{$ddest};
1532             }
1533             foreach (@{$includes{$dest}}) {
1534                 my $i = cleandir($sourced, $_, $blddir);
1535                 push @{$unified_info{includes}->{$ddest}}, $i
1536                     unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1537             }
1538         }
1539     }
1540
1541     ### Make unified_info a bit more efficient
1542     # One level structures
1543     foreach (("programs", "libraries", "engines", "scripts", "extra")) {
1544         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1545     }
1546     # Two level structures
1547     foreach my $l1 (("sources", "ldadd", "depends")) {
1548         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1549             $unified_info{$l1}->{$l2} =
1550                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1551         }
1552     }
1553 }
1554
1555 # For the schemes that need it, we provide the old *_obj configs
1556 # from the *_asm_obj ones
1557 foreach (grep /_(asm|aux)_src$/, keys %target) {
1558     my $src = $_;
1559     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1560     ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1561 }
1562
1563 # Write down our configuration where it fits #########################
1564
1565 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1566 print OUT <<"EOF";
1567 package configdata;
1568
1569 use strict;
1570 use warnings;
1571
1572 use Exporter;
1573 #use vars qw(\@ISA \@EXPORT);
1574 our \@ISA = qw(Exporter);
1575 our \@EXPORT = qw(\%config \%target %disabled %withargs %unified_info);
1576
1577 EOF
1578 print OUT "our %config = (\n";
1579 foreach (sort keys %config) {
1580     if (ref($config{$_}) eq "ARRAY") {
1581         print OUT "  ", $_, " => [ ", join(", ",
1582                                            map { quotify("perl", $_) }
1583                                            @{$config{$_}}), " ],\n";
1584     } else {
1585         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1586     }
1587 }
1588 print OUT <<"EOF";
1589 );
1590
1591 EOF
1592 print OUT "our %target = (\n";
1593 foreach (sort keys %target) {
1594     if (ref($target{$_}) eq "ARRAY") {
1595         print OUT "  ", $_, " => [ ", join(", ",
1596                                            map { quotify("perl", $_) }
1597                                            @{$target{$_}}), " ],\n";
1598     } else {
1599         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1600     }
1601 }
1602 print OUT <<"EOF";
1603 );
1604
1605 EOF
1606 print OUT "our \%available_protocols = (\n";
1607 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1608 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1609 print OUT <<"EOF";
1610 );
1611
1612 EOF
1613 print OUT "our \%disabled = (\n";
1614 foreach (sort keys %disabled) {
1615     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1616 }
1617 print OUT <<"EOF";
1618 );
1619
1620 EOF
1621 print OUT "our %withargs = (\n";
1622 foreach (sort keys %withargs) {
1623     if (ref($withargs{$_}) eq "ARRAY") {
1624         print OUT "  ", $_, " => [ ", join(", ",
1625                                            map { quotify("perl", $_) }
1626                                            @{$withargs{$_}}), " ],\n";
1627     } else {
1628         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1629     }
1630 }
1631 print OUT <<"EOF";
1632 );
1633
1634 EOF
1635 if ($builder eq "unified") {
1636     my $recurse;
1637     $recurse = sub {
1638         my $indent = shift;
1639         foreach (@_) {
1640             if (ref $_ eq "ARRAY") {
1641                 print OUT " "x$indent, "[\n";
1642                 foreach (@$_) {
1643                     $recurse->($indent + 4, $_);
1644                 }
1645                 print OUT " "x$indent, "],\n";
1646             } elsif (ref $_ eq "HASH") {
1647                 my %h = %$_;
1648                 print OUT " "x$indent, "{\n";
1649                 foreach (sort keys %h) {
1650                     if (ref $h{$_} eq "") {
1651                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1652                     } else {
1653                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1654                         $recurse->($indent + 8, $h{$_});
1655                     }
1656                 }
1657                 print OUT " "x$indent, "},\n";
1658             } else {
1659                 print OUT " "x$indent, quotify("perl", $_), ",\n";
1660             }
1661         }
1662     };
1663     print OUT "our %unified_info = (\n";
1664     foreach (sort keys %unified_info) {
1665         if (ref $unified_info{$_} eq "") {
1666             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1667         } else {
1668             print OUT " "x4, quotify("perl", $_), " =>\n";
1669             $recurse->(8, $unified_info{$_});
1670         }
1671     }
1672     print OUT <<"EOF";
1673 );
1674
1675 EOF
1676 }
1677 print OUT "1;\n";
1678 close(OUT);
1679
1680
1681 print "IsMK1MF       =", ($builder eq "mk1mf" ? "yes" : "no"), "\n";
1682 print "CC            =$target{cc}\n";
1683 print "CFLAG         =$config{cflags}\n";
1684 print "DEFINES       =",join(" ", @{$config{defines}}),"\n";
1685 print "LFLAG         =$config{lflags}\n";
1686 print "PLIB_LFLAG    =$config{plib_lflags}\n";
1687 print "EX_LIBS       =$config{ex_libs}\n";
1688 print "APPS_OBJ      =$target{apps_obj}\n";
1689 print "CPUID_OBJ     =$target{cpuid_obj}\n";
1690 print "UPLINK_OBJ    =$target{uplink_obj}\n";
1691 print "BN_ASM        =$target{bn_obj}\n";
1692 print "EC_ASM        =$target{ec_obj}\n";
1693 print "DES_ENC       =$target{des_obj}\n";
1694 print "AES_ENC       =$target{aes_obj}\n";
1695 print "BF_ENC        =$target{bf_obj}\n";
1696 print "CAST_ENC      =$target{cast_obj}\n";
1697 print "RC4_ENC       =$target{rc4_obj}\n";
1698 print "RC5_ENC       =$target{rc5_obj}\n";
1699 print "MD5_OBJ_ASM   =$target{md5_obj}\n";
1700 print "SHA1_OBJ_ASM  =$target{sha1_obj}\n";
1701 print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
1702 print "CMLL_ENC      =$target{cmll_obj}\n";
1703 print "MODES_OBJ     =$target{modes_obj}\n";
1704 print "PADLOCK_OBJ   =$target{padlock_obj}\n";
1705 print "CHACHA_ENC    =$target{chacha_obj}\n";
1706 print "POLY1305_OBJ  =$target{poly1305_obj}\n";
1707 print "PROCESSOR     =$config{processor}\n";
1708 print "RANLIB        =$target{ranlib}\n";
1709 print "ARFLAGS       =$target{arflags}\n";
1710 print "PERL          =$config{perl}\n";
1711 print "\n";
1712 print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
1713 print "SIXTY_FOUR_BIT mode\n" if $config{b64};
1714 print "THIRTY_TWO_BIT mode\n" if $config{b32};
1715 print "BN_LLONG mode\n" if $config{bn_ll};
1716 print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} != $def_int;
1717
1718 for (@generated_headers) {
1719     mkpath(catdir($blddir, dirname($_)));
1720     run_dofile(catfile($blddir, $_),
1721                catfile($srcdir, $_.".in"));
1722 }
1723
1724 ###
1725 ### When the old "unixmake" scheme goes away, so does this function
1726 ###
1727 sub build_Makefile {
1728     run_dofile("Makefile","Makefile.in");
1729
1730     # Copy all Makefile.in to Makefile (except top-level)
1731     use File::Find;
1732     use IO::File;
1733     find(
1734         {
1735             preprocess => sub {
1736                 grep(!/^\./, @_);
1737             },
1738             wanted => sub {
1739                 return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
1740                 my $in = IO::File->new($_, "r") or
1741                     die sprintf "Error reading Makefile.in in %s: !$\n",
1742                     $File::Find::dir;
1743                 my $out = IO::File->new("Makefile", "w") or
1744                     die sprintf "Error writing Makefile in %s: !$\n",
1745                     $File::Find::dir;
1746                 print $out "# Generated from $_, do not edit\n";
1747                 while (my $line = <$in>) { print $out $line }
1748                 $in->close() or
1749                     die sprintf "Error reading Makefile.in in %s: !$\n",
1750                     $File::Find::dir;
1751                 $out->close() or
1752                     die sprintf "Error writing Makefile in %s: !$\n",
1753                     $File::Find::dir;
1754             },
1755         },
1756         ".");
1757 }
1758
1759 my %builders = (
1760     unified => sub {
1761         run_dofile(catfile($blddir, $target{build_file}),
1762                    $config{build_file_template},
1763                    catfile($srcdir, "Configurations", "common.tmpl"));
1764     },
1765     unixmake => sub {
1766         build_Makefile();
1767
1768         run_dofile("util/domd", "util/domd.in");
1769         chmod 0755, "util/domd";
1770     },
1771     mk1mf => sub {
1772         my $platform = shift;
1773         # The only reason we do this is to have something to build MINFO from
1774         build_Makefile();
1775
1776         # create the ms/version32.rc file if needed
1777         if ($platform ne "netware") {
1778             my ($v1, $v2, $v3, $v4);
1779             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) {
1780                 $v1=hex $1;
1781                 $v2=hex $2;
1782                 $v3=hex $3;
1783                 $v4=hex $4;
1784             }
1785             open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
1786             print OUT <<"EOF";
1787 #include <winver.h>
1788
1789 LANGUAGE 0x09,0x01
1790
1791 1 VERSIONINFO
1792   FILEVERSION $v1,$v2,$v3,$v4
1793   PRODUCTVERSION $v1,$v2,$v3,$v4
1794   FILEFLAGSMASK 0x3fL
1795 #ifdef _DEBUG
1796   FILEFLAGS 0x01L
1797 #else
1798   FILEFLAGS 0x00L
1799 #endif
1800   FILEOS VOS__WINDOWS32
1801   FILETYPE VFT_DLL
1802   FILESUBTYPE 0x0L
1803 BEGIN
1804     BLOCK "StringFileInfo"
1805     BEGIN
1806         BLOCK "040904b0"
1807         BEGIN
1808             // Required:
1809             VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
1810             VALUE "FileDescription", "OpenSSL Shared Library\\0"
1811             VALUE "FileVersion", "$config{version}\\0"
1812 #if defined(CRYPTO)
1813             VALUE "InternalName", "libeay32\\0"
1814             VALUE "OriginalFilename", "libeay32.dll\\0"
1815 #elif defined(SSL)
1816             VALUE "InternalName", "ssleay32\\0"
1817             VALUE "OriginalFilename", "ssleay32.dll\\0"
1818 #endif
1819             VALUE "ProductName", "The OpenSSL Toolkit\\0"
1820             VALUE "ProductVersion", "$config{version}\\0"
1821             // Optional:
1822             //VALUE "Comments", "\\0"
1823             VALUE "LegalCopyright", "Copyright © 1998-2015 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
1824             //VALUE "LegalTrademarks", "\\0"
1825             //VALUE "PrivateBuild", "\\0"
1826             //VALUE "SpecialBuild", "\\0"
1827         END
1828     END
1829     BLOCK "VarFileInfo"
1830     BEGIN
1831         VALUE "Translation", 0x409, 0x4b0
1832     END
1833 END
1834 EOF
1835             close(OUT);
1836         }
1837     },
1838     );
1839
1840 $builders{$builder}->($builder_platform, @builder_opts);
1841
1842 print <<"EOF";
1843
1844 Configured for $target.
1845 EOF
1846
1847 print <<"EOF" if (!$disabled{threads} && !$threads);
1848
1849 The library could not be configured for supporting multi-threaded
1850 applications as the compiler options required on this system are not known.
1851 See file INSTALL for details if you need multi-threading.
1852 EOF
1853
1854 print <<"EOF" if ($no_shared_warn);
1855
1856 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
1857 platform, so we will pretend you gave the option 'no-pic', which also disables
1858 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
1859 or position independent code, please let us know (but please first make sure
1860 you have tried with a current version of OpenSSL).
1861 EOF
1862
1863 ###### TO BE REMOVED BEFORE FINAL RELEASE
1864 ######
1865 ###### If the user hasn't chosen --unified, try to nudge them.
1866 if ($target{build_file} eq "Makefile"
1867     && $target{build_scheme}->[0] eq "unixmake"
1868     && !$unified) {
1869
1870     my $plausible_builddir =
1871         abs2rel(rel2abs("../_openssl-build_$target"),rel2abs("."));
1872     my $plausible_to_sourcedir =
1873         abs2rel(rel2abs("."),rel2abs("../_openssl-build_$target"));
1874     print <<"EOF";
1875
1876 ----------------------------------------------------------------------
1877 Please consider configuring with the flag --unified .
1878 It's to test out a new "unified" building system.
1879
1880 One cool feature is that you can have your build directory elsewhere,
1881 for example:
1882
1883     make clean          # Clean the current configuration away
1884     mkdir $plausible_builddir
1885     cd $plausible_builddir
1886     $plausible_to_sourcedir/config --unified
1887     make
1888     make test
1889
1890 Please report any problem you have.
1891 ----------------------------------------------------------------------
1892
1893 EOF
1894 }
1895
1896 exit(0);
1897
1898 ######################################################################
1899 #
1900 # Helpers and utility functions
1901 #
1902
1903 # Configuration file reading #########################################
1904
1905 # Helper function to implement conditional inheritance depending on the
1906 # value of $disabled{asm}.  Used in inherit_from values as follows:
1907 #
1908 #      inherit_from => [ "template", asm("asm_tmpl") ]
1909 #
1910 sub asm {
1911     my @x = @_;
1912     sub {
1913         $disabled{asm} ? () : @x;
1914     }
1915 }
1916
1917 # Helper function to implement adding values to already existing configuration
1918 # values.  It handles elements that are ARRAYs, CODEs and scalars
1919 sub _add {
1920     my $separator = shift;
1921
1922     # If there's any ARRAY in the collection of values OR the separator
1923     # is undef, we will return an ARRAY of combined values, otherwise a
1924     # string of joined values with $separator as the separator.
1925     my $found_array = !defined($separator);
1926
1927     my @values =
1928         map {
1929             my $res = $_;
1930             while (ref($res) eq "CODE") {
1931                 $res = $res->();
1932             }
1933             if (defined($res)) {
1934                 if (ref($res) eq "ARRAY") {
1935                     $found_array = 1;
1936                     @$res;
1937                 } else {
1938                     $res;
1939                 }
1940             } else {
1941                 ();
1942             }
1943     } (@_);
1944
1945     if ($found_array) {
1946         [ @values ];
1947     } else {
1948         join($separator, grep { defined($_) && $_ ne "" } @values);
1949     }
1950 }
1951 sub add_before {
1952     my $separator = " ";
1953     if (ref($_[$#_]) eq "HASH") {
1954         my $opts = pop;
1955         $separator = $opts->{separator};
1956     }
1957     my @x = @_;
1958     sub { _add($separator, @x, @_) };
1959 }
1960 sub add {
1961     my $separator = " ";
1962     if (ref($_[$#_]) eq "HASH") {
1963         my $opts = pop;
1964         $separator = $opts->{separator};
1965     }
1966     my @x = @_;
1967     sub { _add($separator, @_, @x) };
1968 }
1969
1970 # configuration reader, evaluates the input file as a perl script and expects
1971 # it to fill %targets with target configurations.  Those are then added to
1972 # %table.
1973 sub read_config {
1974     my $fname = shift;
1975     open(CONFFILE, "< $fname")
1976         or die "Can't open configuration file '$fname'!\n";
1977     my $x = $/;
1978     undef $/;
1979     my $content = <CONFFILE>;
1980     $/ = $x;
1981     close(CONFFILE);
1982     my %targets = ();
1983     {
1984         local %table = %::table;    # Protect %table from tampering
1985
1986         eval $content;
1987         warn $@ if $@;
1988     }
1989
1990     # For each target, check that it's configured with a hash table.
1991     foreach (keys %targets) {
1992         if (ref($targets{$_}) ne "HASH") {
1993             if (ref($targets{$_}) eq "") {
1994                 warn "Deprecated target configuration for $_, ignoring...\n";
1995             } else {
1996                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
1997             }
1998             delete $targets{$_};
1999         }
2000     }
2001
2002     %table = (%table, %targets);
2003
2004 }
2005
2006 # configuration resolver.  Will only resolve all the lazy evalutation
2007 # codeblocks for the chozen target and all those it inherits from,
2008 # recursively
2009 sub resolve_config {
2010     my $target = shift;
2011     my @breadcrumbs = @_;
2012
2013     if (grep { $_ eq $target } @breadcrumbs) {
2014         die "inherit_from loop!  target backtrace:\n  "
2015             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2016     }
2017
2018     if (!defined($table{$target})) {
2019         warn "Warning! target $target doesn't exist!\n";
2020         return ();
2021     }
2022     # Recurse through all inheritances.  They will be resolved on the
2023     # fly, so when this operation is done, they will all just be a
2024     # bunch of attributes with string values.
2025     # What we get here, though, are keys with references to lists of
2026     # the combined values of them all.  We will deal with lists after
2027     # this stage is done.
2028     my %combined_inheritance = ();
2029     if ($table{$target}->{inherit_from}) {
2030         my @inherit_from =
2031             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2032         foreach (@inherit_from) {
2033             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2034
2035             # 'template' is a marker that's considered private to
2036             # the config that had it.
2037             delete $inherited_config{template};
2038
2039             map {
2040                 if (!$combined_inheritance{$_}) {
2041                     $combined_inheritance{$_} = [];
2042                 }
2043                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2044             } keys %inherited_config;
2045         }
2046     }
2047
2048     # We won't need inherit_from in this target any more, since we've
2049     # resolved all the inheritances that lead to this
2050     delete $table{$target}->{inherit_from};
2051
2052     # Now is the time to deal with those lists.  Here's the place to
2053     # decide what shall be done with those lists, all based on the
2054     # values of the target we're currently dealing with.
2055     # - If a value is a coderef, it will be executed with the list of
2056     #   inherited values as arguments.
2057     # - If the corresponding key doesn't have a value at all or is the
2058     #   emoty string, the inherited value list will be run through the
2059     #   default combiner (below), and the result becomes this target's
2060     #   value.
2061     # - Otherwise, this target's value is assumed to be a string that
2062     #   will simply override the inherited list of values.
2063     my $default_combiner = add();
2064
2065     my %all_keys =
2066         map { $_ => 1 } (keys %combined_inheritance,
2067                          keys %{$table{$target}});
2068
2069     sub process_values {
2070         my $object    = shift;
2071         my $inherited = shift;  # Always a [ list ]
2072         my $target    = shift;
2073         my $entry     = shift;
2074
2075         while(ref($object) eq "CODE") {
2076             $object = $object->(@$inherited);
2077         }
2078         if (!defined($object)) {
2079             return ();
2080         }
2081         elsif (ref($object) eq "ARRAY") {
2082             return [ map { process_values($_, $inherited, $target, $entry) }
2083                      @$object ];
2084         } elsif (ref($object) eq "") {
2085             return $object;
2086         } else {
2087             die "cannot handle reference type ",ref($object)
2088                 ," found in target ",$target," -> ",$entry,"\n";
2089         }
2090     }
2091
2092     foreach (sort keys %all_keys) {
2093
2094         # Current target doesn't have a value for the current key?
2095         # Assign it the default combiner, the rest of this loop body
2096         # will handle it just like any other coderef.
2097         if (!exists $table{$target}->{$_}) {
2098             $table{$target}->{$_} = $default_combiner;
2099         }
2100
2101         $table{$target}->{$_} = process_values($table{$target}->{$_},
2102                                                $combined_inheritance{$_},
2103                                                $target, $_);
2104         unless(defined($table{$target}->{$_})) {
2105             delete $table{$target}->{$_};
2106         }
2107     }
2108
2109     # Finally done, return the result.
2110     return %{$table{$target}};
2111 }
2112
2113 sub usage
2114         {
2115         print STDERR $usage;
2116         print STDERR "\npick os/compiler from:\n";
2117         my $j=0;
2118         my $i;
2119         my $k=0;
2120         foreach $i (sort keys %table)
2121                 {
2122                 next if $table{$i}->{template};
2123                 next if $i =~ /^debug/;
2124                 $k += length($i) + 1;
2125                 if ($k > 78)
2126                         {
2127                         print STDERR "\n";
2128                         $k=length($i);
2129                         }
2130                 print STDERR $i . " ";
2131                 }
2132         foreach $i (sort keys %table)
2133                 {
2134                 next if $table{$i}->{template};
2135                 next if $i !~ /^debug/;
2136                 $k += length($i) + 1;
2137                 if ($k > 78)
2138                         {
2139                         print STDERR "\n";
2140                         $k=length($i);
2141                         }
2142                 print STDERR $i . " ";
2143                 }
2144         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2145         exit(1);
2146         }
2147
2148 sub run_dofile()
2149 {
2150     my $out = shift;
2151     my @templates = @_;
2152
2153     unlink $out || warn "Can't remove $out, $!"
2154         if -f $out;
2155     foreach (@templates) {
2156         die "Can't open $_, $!" unless -f $_;
2157     }
2158     my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2159     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2160     system($cmd);
2161     exit 1 if $? != 0;
2162     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2163 }
2164
2165 # Configuration printer ##############################################
2166
2167 sub print_table_entry
2168 {
2169     my $target = shift;
2170     my %target = resolve_config($target);
2171     my $type = shift;
2172
2173     # Don't print the templates
2174     return if $target{template};
2175
2176     my @sequence = (
2177         "sys_id",
2178         "cc",
2179         "cflags",
2180         "defines",
2181         "debug_cflags",
2182         "debug_defines",
2183         "release_cflags",
2184         "release_defines",
2185         "thread_cflag",
2186         "unistd",
2187         "ld",
2188         "lflags",
2189         "plib_lflags",
2190         "ex_libs",
2191         "debug_lflags",
2192         "debug_plib_lflags",
2193         "debug_ex_libs",
2194         "release_lflags",
2195         "release_plib_lflags",
2196         "release_ex_libs",
2197         "bn_ops",
2198         "cpuid_obj",
2199         "bn_obj",
2200         "ec_obj",
2201         "des_obj",
2202         "aes_obj",
2203         "bf_obj",
2204         "md5_obj",
2205         "sha1_obj",
2206         "cast_obj",
2207         "rc4_obj",
2208         "rmd160_obj",
2209         "rc5_obj",
2210         "wp_obj",
2211         "cmll_obj",
2212         "modes_obj",
2213         "padlock_obj",
2214         "perlasm_scheme",
2215         "dso_scheme",
2216         "shared_target",
2217         "shared_cflag",
2218         "shared_ldflag",
2219         "shared_rcflag",
2220         "shared_extension",
2221         "shared_extension_simple",
2222         "shared_import_extension",
2223         "dso_extension",
2224         "obj_extension",
2225         "exe_extension",
2226         "ranlib",
2227         "ar",
2228         "arflags",
2229         "multilib",
2230         "build_scheme",
2231         );
2232
2233     if ($type eq "TABLE") {
2234         print "\n";
2235         print "*** $target\n";
2236         foreach (@sequence) {
2237             if (ref($target{$_}) eq "ARRAY") {
2238                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2239             } else {
2240                 printf "\$%-12s = %s\n", $_, $target{$_};
2241             }
2242         }
2243     } elsif ($type eq "HASH") {
2244         my $largest =
2245             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2246         print "    '$target' => {\n";
2247         foreach (@sequence) {
2248             if ($target{$_}) {
2249                 if (ref($target{$_}) eq "ARRAY") {
2250                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2251                 } else {
2252                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2253                 }
2254             }
2255         }
2256         print "    },\n";
2257     }
2258 }
2259
2260 # Utility routines ###################################################
2261
2262 # On VMS, if the given file is a logical name, File::Spec::Functions
2263 # will consider it an absolute path.  There are cases when we want a
2264 # purely syntactic check without checking the environment.
2265 sub isabsolute {
2266     my $file = shift;
2267
2268     # On non-platforms, we just use file_name_is_absolute().
2269     return file_name_is_absolute($file) unless $^O eq "VMS";
2270
2271     # If the file spec includes a device or a directpry spec,
2272     # file_name_is_absolute() is perfectly safe.
2273     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2274
2275     # Here, we know the given file spec isn't absolute
2276     return 0;
2277 }
2278
2279 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2280 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2281 # realpath() requires that at least all path components except the last is an
2282 # existing directory.  On VMS, the last component of the directory spec must
2283 # exist.
2284 sub absolutedir {
2285     my $dir = shift;
2286
2287     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2288     # will return the volume name for the device, no matter what.  Also,
2289     # it will return an incorrect directory spec if the argument is a
2290     # directory that doesn't exist.
2291     if ($^O eq "VMS") {
2292         return rel2abs($dir);
2293     }
2294
2295     # We use realpath() on Unix, since no other will properly clean out
2296     # a directory spec.
2297     use Cwd qw/realpath/;
2298
2299     return realpath($dir);
2300 }
2301
2302 sub which
2303         {
2304         my($name)=@_;
2305         my $path;
2306         foreach $path (split /:/, $ENV{PATH})
2307                 {
2308                 if (-f "$path/$name$target{exe_extension}" and -x _)
2309                         {
2310                         return "$path/$name$target{exe_extension}" unless ($name eq "perl" and
2311                          system("$path/$name$target{exe_extension} -e " . '\'exit($]<5.0);\''));
2312                         }
2313                 }
2314         }
2315
2316 sub quotify {
2317     my %processors = (
2318         perl    => sub { my $x = shift;
2319                          $x =~ s/([\\\$\@"])/\\$1/g;
2320                          return '"'.$x.'"'; },
2321         );
2322     my $for = shift;
2323     my $processor =
2324         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2325
2326     map { $processor->($_); } @_;
2327 }
2328
2329 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2330 # $filename is a file name to read from
2331 # $line_concat_cond_re is a regexp detecting a line continuation ending
2332 # $line_concat is a CODEref that takes care of concatenating two lines
2333 sub collect_from_file {
2334     my $filename = shift;
2335     my $line_concat_cond_re = shift;
2336     my $line_concat = shift;
2337
2338     open my $fh, $filename || die "unable to read $filename: $!\n";
2339     return sub {
2340         my $saved_line = "";
2341         $_ = "";
2342         while (<$fh>) {
2343             s|\R$||;
2344             if (defined $line_concat) {
2345                 $_ = $line_concat->($saved_line, $_);
2346                 $saved_line = "";
2347             }
2348             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2349                 $saved_line = $_;
2350                 next;
2351             }
2352             return $_;
2353         }
2354         die "$filename ending with continuation line\n" if $_;
2355         close $fh;
2356         return undef;
2357     }
2358 }
2359
2360 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2361 # $array is an ARRAYref of lines
2362 # $line_concat_cond_re is a regexp detecting a line continuation ending
2363 # $line_concat is a CODEref that takes care of concatenating two lines
2364 sub collect_from_array {
2365     my $array = shift;
2366     my $line_concat_cond_re = shift;
2367     my $line_concat = shift;
2368     my @array = (@$array);
2369
2370     return sub {
2371         my $saved_line = "";
2372         $_ = "";
2373         while (defined($_ = shift @array)) {
2374             s|\R$||;
2375             if (defined $line_concat) {
2376                 $_ = $line_concat->($saved_line, $_);
2377                 $saved_line = "";
2378             }
2379             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2380                 $saved_line = $_;
2381                 next;
2382             }
2383             return $_;
2384         }
2385         die "input text ending with continuation line\n" if $_;
2386         return undef;
2387     }
2388 }
2389
2390 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2391 # $lineiterator is a CODEref that delivers one line at a time.
2392 # All following arguments are regex/CODEref pairs, where the regexp detects a
2393 # line and the CODEref does something with the result of the regexp.
2394 sub collect_information {
2395     my $lineiterator = shift;
2396     my %collectors = @_;
2397
2398     while(defined($_ = $lineiterator->())) {
2399         s|\R$||;
2400         my $found = 0;
2401         foreach my $re (keys %collectors) {
2402             if ($re ne "OTHERWISE" && /$re/) {
2403                 $collectors{$re}->($lineiterator);
2404                 $found = 1;
2405             };
2406         }
2407         if ($collectors{"OTHERWISE"}) {
2408             $collectors{"OTHERWISE"}->($lineiterator, $_)
2409                 unless $found || !defined $collectors{"OTHERWISE"};
2410         }
2411     }
2412 }