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