Expose %disables to the perl fragments in build.info files.
[openssl.git] / Configure
1 #! /usr/bin/env perl
2 # -*- mode: perl; -*-
3
4 ##
5 ##  Configure -- OpenSSL source tree configuration script
6 ##  If editing this file, run this command before committing
7 ##      make -f Makefile.in TABLE
8 ##
9
10 require 5.000;
11 use strict;
12 use File::Basename;
13 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
14 use File::Path qw/mkpath/;
15
16 # see INSTALL for instructions.
17
18 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
19
20 # Options:
21 #
22 # --config      add the given configuration file, which will be read after
23 #               any "Configurations*" files that are found in the same
24 #               directory as this script.
25 # --prefix      prefix for the OpenSSL installation, which includes the
26 #               directories bin, lib, include, share/man, share/doc/openssl
27 #               This becomes the value of INSTALLTOP in Makefile
28 #               (Default: /usr/local)
29 # --openssldir  OpenSSL data area, such as openssl.cnf, certificates and keys.
30 #               If it's a relative directory, it will be added on the directory
31 #               given with --prefix.
32 #               This becomes the value of OPENSSLDIR in Makefile and in C.
33 #               (Default: PREFIX/ssl)
34 #
35 # --cross-compile-prefix Add specified prefix to binutils components.
36 #
37 # --api         One of 0.9.8, 1.0.0 or 1.1.0.  Do not compile support for
38 #               interfaces deprecated as of the specified OpenSSL version.
39 #
40 # no-hw-xxx     do not compile support for specific crypto hardware.
41 #               Generic OpenSSL-style methods relating to this support
42 #               are always compiled but return NULL if the hardware
43 #               support isn't compiled.
44 # no-hw         do not compile support for any crypto hardware.
45 # [no-]threads  [don't] try to create a library that is suitable for
46 #               multithreaded applications (default is "threads" if we
47 #               know how to do it)
48 # [no-]shared   [don't] try to create shared libraries when supported.
49 # [no-]pic      [don't] try to build position independent code when supported.
50 #               If disabled, it also disables shared and dynamic-engine.
51 # no-asm        do not use assembler
52 # no-dso        do not compile in any native shared-library methods. This
53 #               will ensure that all methods just return NULL.
54 # no-egd        do not compile support for the entropy-gathering daemon APIs
55 # [no-]zlib     [don't] compile support for zlib compression.
56 # zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
57 #               library and will be loaded in run-time by the OpenSSL library.
58 # sctp          include SCTP support
59 # 386           generate 80386 code
60 # no-sse2       disables IA-32 SSE2 code, above option implies no-sse2
61 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
62 # -<xxx> +<xxx> compiler options are passed through
63 #
64 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
65 #               provided to stack calls. Generates unique stack functions for
66 #               each possible stack type.
67 # BN_LLONG      use the type 'long long' in crypto/bn/bn.h
68 # RC4_CHAR      use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
69 # Following are set automatically by this script
70 #
71 # MD5_ASM       use some extra md5 assember,
72 # SHA1_ASM      use some extra sha1 assember, must define L_ENDIAN for x86
73 # RMD160_ASM    use some extra ripemd160 assember,
74 # SHA256_ASM    sha256_block is implemented in assembler
75 # SHA512_ASM    sha512_block is implemented in assembler
76 # AES_ASM       ASE_[en|de]crypt is implemented in assembler
77
78 # Minimum warning options... any contributions to OpenSSL should at least get
79 # past these.
80
81 my $gcc_devteam_warn = "-DPEDANTIC -DREF_DEBUG -DDEBUG_UNUSED -DBIO_DEBUG"
82         . " -pedantic"
83         . " -Wall"
84         . " -Wno-long-long"
85         . " -Wsign-compare"
86         . " -Wmissing-prototypes"
87         . " -Wshadow"
88         . " -Wformat"
89         . " -Wtype-limits"
90         . " -Werror"
91         ;
92
93 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
94 # TODO(openssl-team): fix problems and investigate if (at least) the
95 # following warnings can also be enabled:
96 #       -Wswitch-enum
97 #       -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 our %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                                          disabled => \%disabled,
1305                                          builddir => abs2rel($buildd, $blddir),
1306                                          sourcedir => abs2rel($sourced, $blddir),
1307                                          buildtop => abs2rel($blddir, $blddir),
1308                                          sourcetop => abs2rel($srcdir, $blddir) },
1309                                DELIMITERS => [ "{-", "-}" ]);
1310
1311         # The top item of this stack has the following values
1312         # -2 positive already run and we found ELSE (following ELSIF should fail)
1313         # -1 positive already run (skip until ENDIF)
1314         # 0 negatives so far (if we're at a condition, check it)
1315         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1316         # 2 positive ELSE (following ELSIF should fail)
1317         my @skip = ();
1318         collect_information(
1319             collect_from_array([ @text ],
1320                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1321                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1322             # Info we're looking for
1323             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1324             => sub { push @skip, !! $1; },
1325             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1326             => sub { die "ELSIF out of scope" if ! @skip;
1327                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1328                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1329                      $skip[$#skip] = !! $1
1330                          if $skip[$#skip] == 0; },
1331             qr/^\s*ELSE\s*$/
1332             => sub { die "ELSE out of scope" if ! @skip;
1333                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1334                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1335             qr/^\s*ENDIF\s*$/
1336             => sub { die "ENDIF out of scope" if ! @skip;
1337                      pop @skip; },
1338             qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
1339             => sub { push @programs, split(/\s+/, $1)
1340                          if !@skip || $skip[$#skip] > 0 },
1341             qr/^\s*LIBS\s*=\s*(.*)\s*$/
1342             => sub { push @libraries, split(/\s+/, $1)
1343                          if !@skip || $skip[$#skip] > 0 },
1344             qr/^\s*ENGINES\s*=\s*(.*)\s*$/
1345             => sub { push @engines, split(/\s+/, $1)
1346                          if !@skip || $skip[$#skip] > 0 },
1347             qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
1348             => sub { push @scripts, split(/\s+/, $1)
1349                          if !@skip || $skip[$#skip] > 0 },
1350             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1351             => sub { push @extra, split(/\s+/, $1)
1352                          if !@skip || $skip[$#skip] > 0 },
1353
1354             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1355             => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
1356                          if !@skip || $skip[$#skip] > 0 },
1357             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1358             => sub { push @{$sources{$1}}, split(/\s+/, $2)
1359                          if !@skip || $skip[$#skip] > 0 },
1360             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1361             => sub { push @{$includes{$1}}, split(/\s+/, $2)
1362                          if !@skip || $skip[$#skip] > 0 },
1363             qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1364             => sub { push @{$depends{$1}}, split(/\s+/, $2)
1365                          if !@skip || $skip[$#skip] > 0 },
1366             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1367             => sub { push @{$renames{$1}}, split(/\s+/, $2)
1368                          if !@skip || $skip[$#skip] > 0 },
1369             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1370             => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
1371                          if !@skip || $skip[$#skip] > 0 },
1372             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1373             => sub {
1374                 my $lineiterator = shift;
1375                 my $target_kind = $1;
1376                 while (defined $lineiterator->()) {
1377                     s|\R$||;
1378                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1379                         die "ENDRAW doesn't match BEGINRAW"
1380                             if $1 ne $target_kind;
1381                         last;
1382                     }
1383                     next if @skip && $skip[$#skip] <= 0;
1384                     push @rawlines,  $_
1385                         if ($target_kind eq $target{build_file}
1386                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1387                 }
1388             },
1389             qr/^(?:#.*|\s*)$/ => sub { },
1390             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
1391             );
1392         die "runaway IF?" if (@skip);
1393
1394         foreach (keys %renames) {
1395             die "$_ renamed to more than one thing: "
1396                 ,join(" ", @{$renames{$_}}),"\n"
1397                 if scalar @{$renames{$_}} > 1;
1398             my $dest = cleanfile($buildd, $_, $blddir);
1399             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1400             die "$dest renamed to more than one thing: "
1401                 ,$unified_info{rename}->{$dest}, $to
1402                 unless !defined($unified_info{rename}->{$dest})
1403                 or $unified_info{rename}->{$dest} eq $to;
1404             $unified_info{rename}->{$dest} = $to;
1405         }
1406
1407         foreach (@programs) {
1408             my $program = cleanfile($buildd, $_, $blddir);
1409             if ($unified_info{rename}->{$program}) {
1410                 $program = $unified_info{rename}->{$program};
1411             }
1412             $unified_info{programs}->{$program} = 1;
1413         }
1414
1415         foreach (@libraries) {
1416             my $library = cleanfile($buildd, $_, $blddir);
1417             if ($unified_info{rename}->{$library}) {
1418                 $library = $unified_info{rename}->{$library};
1419             }
1420             $unified_info{libraries}->{$library} = 1;
1421         }
1422
1423         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1424 ENGINES can only be used if configured with 'dynamic-engine'.
1425 This is usually a fault in a build.info file.
1426 EOF
1427         foreach (@engines) {
1428             my $library = cleanfile($buildd, $_, $blddir);
1429             if ($unified_info{rename}->{$library}) {
1430                 $library = $unified_info{rename}->{$library};
1431             }
1432             $unified_info{engines}->{$library} = 1;
1433         }
1434
1435         foreach (@scripts) {
1436             my $script = cleanfile($buildd, $_, $blddir);
1437             if ($unified_info{rename}->{$script}) {
1438                 $script = $unified_info{rename}->{$script};
1439             }
1440             $unified_info{scripts}->{$script} = 1;
1441         }
1442
1443         foreach (@extra) {
1444             my $extra = cleanfile($buildd, $_, $blddir);
1445             $unified_info{extra}->{$extra} = 1;
1446         }
1447
1448         push @{$unified_info{rawlines}}, @rawlines;
1449
1450         if (!$config{no_shared}) {
1451             # Check sharednames.
1452             foreach (keys %sharednames) {
1453                 my $dest = cleanfile($buildd, $_, $blddir);
1454                 if ($unified_info{rename}->{$dest}) {
1455                     $dest = $unified_info{rename}->{$dest};
1456                 }
1457                 die "shared_name for $dest with multiple values: "
1458                     ,join(" ", @{$sharednames{$_}}),"\n"
1459                     if scalar @{$sharednames{$_}} > 1;
1460                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1461                 die "shared_name found for a library $dest that isn't defined\n"
1462                     unless $unified_info{libraries}->{$dest};
1463                 die "shared_name for $dest with multiple values: "
1464                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1465                     unless !defined($unified_info{sharednames}->{$dest})
1466                     or $unified_info{sharednames}->{$dest} eq $to;
1467                 $unified_info{sharednames}->{$dest} = $to;
1468             }
1469
1470             # Additionally, we set up sharednames for libraries that don't
1471             # have any, as themselves.
1472             foreach (keys %{$unified_info{libraries}}) {
1473                 if (!defined $unified_info{sharednames}->{$_}) {
1474                     $unified_info{sharednames}->{$_} = $_
1475                 }
1476             }
1477         }
1478
1479         foreach (keys %ordinals) {
1480             my $dest = $_;
1481             my $ddest = cleanfile($buildd, $_, $blddir);
1482             if ($unified_info{rename}->{$ddest}) {
1483                 $ddest = $unified_info{rename}->{$ddest};
1484             }
1485             foreach (@{$ordinals{$dest}}) {
1486                 my %known_ordinals =
1487                     (
1488                      crypto =>
1489                      cleanfile($sourced, catfile("util", "libeay.num"), $blddir),
1490                      ssl =>
1491                      cleanfile($sourced, catfile("util", "ssleay.num"), $blddir)
1492                     );
1493                 my $o = $known_ordinals{$_};
1494                 die "Ordinals for $ddest defined more than once\n"
1495                     if $unified_info{ordinals}->{$ddest};
1496                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1497             }
1498         }
1499
1500         foreach (keys %sources) {
1501             my $dest = $_;
1502             my $ddest = cleanfile($buildd, $_, $blddir);
1503             if ($unified_info{rename}->{$ddest}) {
1504                 $ddest = $unified_info{rename}->{$ddest};
1505             }
1506             foreach (@{$sources{$dest}}) {
1507                 my $s = cleanfile($sourced, $_, $blddir);
1508
1509                 # If it isn't in the source tree, we assume it's generated
1510                 # in the build tree
1511                 if (! -f $s) {
1512                     $s = cleanfile($buildd, $_, $blddir);
1513                 }
1514                 # We recognise C and asm files
1515                 if ($s =~ /\.[csS]\b$/) {
1516                     (my $o = $_) =~ s/\.[csS]\b$/.o/;
1517                     $o = cleanfile($buildd, $o, $blddir);
1518                     $unified_info{sources}->{$ddest}->{$o} = 1;
1519                     $unified_info{sources}->{$o}->{$s} = 1;
1520                 } else {
1521                     $unified_info{sources}->{$ddest}->{$s} = 1;
1522                 }
1523             }
1524         }
1525
1526         foreach (keys %depends) {
1527             my $dest = $_;
1528             my $ddest = cleanfile($buildd, $_, $blddir);
1529             if ($unified_info{rename}->{$ddest}) {
1530                 $ddest = $unified_info{rename}->{$ddest};
1531             }
1532             foreach (@{$depends{$dest}}) {
1533                 my $d = cleanfile($sourced, $_, $blddir);
1534
1535                 # If we know it's generated, or assume it is because we can't
1536                 # find it in the source tree, we set file we depend on to be
1537                 # in the build tree rather than the source tree, and assume
1538                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1539                 # section or in the Makefile template.
1540                 if (! -f $d
1541                     || !(grep { $d eq $_ }
1542                          map { cleanfile($srcdir, $_, $blddir) }
1543                          (@generated_headers, @generated_by_make_headers))) {
1544                     $d = cleanfile($buildd, $_, $blddir);
1545                 }
1546                 # Take note if the file to depend on is being renamed
1547                 if ($unified_info{rename}->{$d}) {
1548                     $d = $unified_info{rename}->{$d};
1549                 }
1550                 $unified_info{depends}->{$ddest}->{$d} = 1;
1551                 # If we depend on a header file, let's make sure it
1552                 # can get included
1553                 if ($d =~ /\.h$/) {
1554                     my $i = dirname($d);
1555                     push @{$unified_info{includes}->{$ddest}}, $i
1556                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1557                 }
1558             }
1559         }
1560
1561         foreach (keys %includes) {
1562             my $dest = $_;
1563             my $ddest = cleanfile($buildd, $_, $blddir);
1564             if ($unified_info{rename}->{$ddest}) {
1565                 $ddest = $unified_info{rename}->{$ddest};
1566             }
1567             foreach (@{$includes{$dest}}) {
1568                 my $i = cleandir($sourced, $_, $blddir);
1569                 push @{$unified_info{includes}->{$ddest}}, $i
1570                     unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1571             }
1572         }
1573     }
1574
1575     ### Make unified_info a bit more efficient
1576     # One level structures
1577     foreach (("programs", "libraries", "engines", "scripts", "extra")) {
1578         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1579     }
1580     # Two level structures
1581     foreach my $l1 (("sources", "ldadd", "depends")) {
1582         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1583             $unified_info{$l1}->{$l2} =
1584                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1585         }
1586     }
1587 }
1588
1589 # For the schemes that need it, we provide the old *_obj configs
1590 # from the *_asm_obj ones
1591 foreach (grep /_(asm|aux)_src$/, keys %target) {
1592     my $src = $_;
1593     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1594     ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1595 }
1596
1597 # Write down our configuration where it fits #########################
1598
1599 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1600 print OUT <<"EOF";
1601 package configdata;
1602
1603 use strict;
1604 use warnings;
1605
1606 use Exporter;
1607 #use vars qw(\@ISA \@EXPORT);
1608 our \@ISA = qw(Exporter);
1609 our \@EXPORT = qw(\%config \%target %withargs %unified_info);
1610
1611 EOF
1612 print OUT "our %config = (\n";
1613 foreach (sort keys %config) {
1614     if (ref($config{$_}) eq "ARRAY") {
1615         print OUT "  ", $_, " => [ ", join(", ",
1616                                            map { quotify("perl", $_) }
1617                                            @{$config{$_}}), " ],\n";
1618     } else {
1619         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1620     }
1621 }
1622 print OUT <<"EOF";
1623 );
1624
1625 EOF
1626 print OUT "our %target = (\n";
1627 foreach (sort keys %target) {
1628     if (ref($target{$_}) eq "ARRAY") {
1629         print OUT "  ", $_, " => [ ", join(", ",
1630                                            map { quotify("perl", $_) }
1631                                            @{$target{$_}}), " ],\n";
1632     } else {
1633         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1634     }
1635 }
1636 print OUT <<"EOF";
1637 );
1638
1639 EOF
1640 print OUT "our \%available_protocols = (\n";
1641 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1642 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1643 print OUT <<"EOF";
1644 );
1645
1646 EOF
1647 print OUT "our \%disabled = (\n";
1648 foreach (sort keys %disabled) {
1649     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1650 }
1651 print OUT <<"EOF";
1652 );
1653
1654 EOF
1655 print OUT "our %withargs = (\n";
1656 foreach (sort keys %withargs) {
1657     if (ref($withargs{$_}) eq "ARRAY") {
1658         print OUT "  ", $_, " => [ ", join(", ",
1659                                            map { quotify("perl", $_) }
1660                                            @{$withargs{$_}}), " ],\n";
1661     } else {
1662         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1663     }
1664 }
1665 print OUT <<"EOF";
1666 );
1667
1668 EOF
1669 if ($builder eq "unified") {
1670     my $recurse;
1671     $recurse = sub {
1672         my $indent = shift;
1673         foreach (@_) {
1674             if (ref $_ eq "ARRAY") {
1675                 print OUT " "x$indent, "[\n";
1676                 foreach (@$_) {
1677                     $recurse->($indent + 4, $_);
1678                 }
1679                 print OUT " "x$indent, "],\n";
1680             } elsif (ref $_ eq "HASH") {
1681                 my %h = %$_;
1682                 print OUT " "x$indent, "{\n";
1683                 foreach (sort keys %h) {
1684                     if (ref $h{$_} eq "") {
1685                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1686                     } else {
1687                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1688                         $recurse->($indent + 8, $h{$_});
1689                     }
1690                 }
1691                 print OUT " "x$indent, "},\n";
1692             } else {
1693                 print OUT " "x$indent, quotify("perl", $_), ",\n";
1694             }
1695         }
1696     };
1697     print OUT "our %unified_info = (\n";
1698     foreach (sort keys %unified_info) {
1699         if (ref $unified_info{$_} eq "") {
1700             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1701         } else {
1702             print OUT " "x4, quotify("perl", $_), " =>\n";
1703             $recurse->(8, $unified_info{$_});
1704         }
1705     }
1706     print OUT <<"EOF";
1707 );
1708
1709 EOF
1710 }
1711 print OUT "1;\n";
1712 close(OUT);
1713
1714
1715 print "IsMK1MF       =", ($builder eq "mk1mf" ? "yes" : "no"), "\n";
1716 print "CC            =$target{cc}\n";
1717 print "CFLAG         =$config{cflags}\n";
1718 print "DEFINES       =",join(" ", @{$config{defines}}),"\n";
1719 print "LFLAG         =$config{lflags}\n";
1720 print "PLIB_LFLAG    =$config{plib_lflags}\n";
1721 print "EX_LIBS       =$config{ex_libs}\n";
1722 print "CPUID_OBJ     =$target{cpuid_obj}\n";
1723 print "BN_ASM        =$target{bn_obj}\n";
1724 print "EC_ASM        =$target{ec_obj}\n";
1725 print "DES_ENC       =$target{des_obj}\n";
1726 print "AES_ENC       =$target{aes_obj}\n";
1727 print "BF_ENC        =$target{bf_obj}\n";
1728 print "CAST_ENC      =$target{cast_obj}\n";
1729 print "RC4_ENC       =$target{rc4_obj}\n";
1730 print "RC5_ENC       =$target{rc5_obj}\n";
1731 print "MD5_OBJ_ASM   =$target{md5_obj}\n";
1732 print "SHA1_OBJ_ASM  =$target{sha1_obj}\n";
1733 print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
1734 print "CMLL_ENC      =$target{cmll_obj}\n";
1735 print "MODES_OBJ     =$target{modes_obj}\n";
1736 print "PADLOCK_OBJ   =$target{padlock_obj}\n";
1737 print "CHACHA_ENC    =$target{chacha_obj}\n";
1738 print "POLY1305_OBJ  =$target{poly1305_obj}\n";
1739 print "PROCESSOR     =$config{processor}\n";
1740 print "RANLIB        =$target{ranlib}\n";
1741 print "ARFLAGS       =$target{arflags}\n";
1742 print "PERL          =$config{perl}\n";
1743 print "\n";
1744 print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
1745 print "SIXTY_FOUR_BIT mode\n" if $config{b64};
1746 print "THIRTY_TWO_BIT mode\n" if $config{b32};
1747 print "BN_LLONG mode\n" if $config{bn_ll};
1748 print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} != $def_int;
1749
1750 for (@generated_headers) {
1751     mkpath(catdir($blddir, dirname($_)));
1752     run_dofile(catfile($blddir, $_),
1753                catfile($srcdir, $_.".in"));
1754 }
1755
1756 ###
1757 ### When the old "unixmake" scheme goes away, so does this function
1758 ###
1759 sub build_Makefile {
1760     run_dofile("Makefile","Makefile.in");
1761
1762     # Copy all Makefile.in to Makefile (except top-level)
1763     use File::Find;
1764     use IO::File;
1765     find(
1766         {
1767             preprocess => sub {
1768                 grep(!/^\./, @_);
1769             },
1770             wanted => sub {
1771                 return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
1772                 my $in = IO::File->new($_, "r") or
1773                     die sprintf "Error reading Makefile.in in %s: !$\n",
1774                     $File::Find::dir;
1775                 my $out = IO::File->new("Makefile", "w") or
1776                     die sprintf "Error writing Makefile in %s: !$\n",
1777                     $File::Find::dir;
1778                 print $out "# Generated from $_, do not edit\n";
1779                 while (my $line = <$in>) { print $out $line }
1780                 $in->close() or
1781                     die sprintf "Error reading Makefile.in in %s: !$\n",
1782                     $File::Find::dir;
1783                 $out->close() or
1784                     die sprintf "Error writing Makefile in %s: !$\n",
1785                     $File::Find::dir;
1786             },
1787         },
1788         ".");
1789 }
1790
1791 my %builders = (
1792     unified => sub {
1793         run_dofile(catfile($blddir, $target{build_file}),
1794                    $config{build_file_template},
1795                    catfile($srcdir, "Configurations", "common.tmpl"));
1796     },
1797     unixmake => sub {
1798         build_Makefile();
1799
1800         run_dofile("util/domd", "util/domd.in");
1801         chmod 0755, "util/domd";
1802     },
1803     mk1mf => sub {
1804         my $platform = shift;
1805         # The only reason we do this is to have something to build MINFO from
1806         build_Makefile();
1807
1808         # create the ms/version32.rc file if needed
1809         if ($platform ne "netware") {
1810             my ($v1, $v2, $v3, $v4);
1811             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) {
1812                 $v1=hex $1;
1813                 $v2=hex $2;
1814                 $v3=hex $3;
1815                 $v4=hex $4;
1816             }
1817             open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
1818             print OUT <<"EOF";
1819 #include <winver.h>
1820
1821 LANGUAGE 0x09,0x01
1822
1823 1 VERSIONINFO
1824   FILEVERSION $v1,$v2,$v3,$v4
1825   PRODUCTVERSION $v1,$v2,$v3,$v4
1826   FILEFLAGSMASK 0x3fL
1827 #ifdef _DEBUG
1828   FILEFLAGS 0x01L
1829 #else
1830   FILEFLAGS 0x00L
1831 #endif
1832   FILEOS VOS__WINDOWS32
1833   FILETYPE VFT_DLL
1834   FILESUBTYPE 0x0L
1835 BEGIN
1836     BLOCK "StringFileInfo"
1837     BEGIN
1838         BLOCK "040904b0"
1839         BEGIN
1840             // Required:
1841             VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
1842             VALUE "FileDescription", "OpenSSL Shared Library\\0"
1843             VALUE "FileVersion", "$config{version}\\0"
1844 #if defined(CRYPTO)
1845             VALUE "InternalName", "libeay32\\0"
1846             VALUE "OriginalFilename", "libeay32.dll\\0"
1847 #elif defined(SSL)
1848             VALUE "InternalName", "ssleay32\\0"
1849             VALUE "OriginalFilename", "ssleay32.dll\\0"
1850 #endif
1851             VALUE "ProductName", "The OpenSSL Toolkit\\0"
1852             VALUE "ProductVersion", "$config{version}\\0"
1853             // Optional:
1854             //VALUE "Comments", "\\0"
1855             VALUE "LegalCopyright", "Copyright Â© 1998-2015 The OpenSSL Project. Copyright Â© 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
1856             //VALUE "LegalTrademarks", "\\0"
1857             //VALUE "PrivateBuild", "\\0"
1858             //VALUE "SpecialBuild", "\\0"
1859         END
1860     END
1861     BLOCK "VarFileInfo"
1862     BEGIN
1863         VALUE "Translation", 0x409, 0x4b0
1864     END
1865 END
1866 EOF
1867             close(OUT);
1868         }
1869     },
1870     );
1871
1872 $builders{$builder}->($builder_platform, @builder_opts);
1873
1874 print <<"EOF";
1875
1876 Configured for $target.
1877 EOF
1878
1879 print <<"EOF" if (!$no_threads && !$threads);
1880
1881 The library could not be configured for supporting multi-threaded
1882 applications as the compiler options required on this system are not known.
1883 See file INSTALL for details if you need multi-threading.
1884 EOF
1885
1886 print <<"EOF" if ($no_shared_warn);
1887
1888 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
1889 platform, so we will pretend you gave the option 'no-pic', which also disables
1890 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
1891 or position independent code, please let us know (but please first make sure
1892 you have tried with a current version of OpenSSL).
1893 EOF
1894
1895 ###### TO BE REMOVED BEFORE FINAL RELEASE
1896 ######
1897 ###### If the user hasn't chosen --unified, try to nudge them.
1898 if ($target{build_file} eq "Makefile"
1899     && $target{build_scheme}->[0] eq "unixmake"
1900     && !$unified) {
1901
1902     my $plausible_builddir =
1903         abs2rel(rel2abs("../_openssl-build_$target"),rel2abs("."));
1904     my $plausible_to_sourcedir =
1905         abs2rel(rel2abs("."),rel2abs("../_openssl-build_$target"));
1906     print <<"EOF";
1907
1908 ----------------------------------------------------------------------
1909 Please consider configuring with the flag --unified .
1910 It's to test out a new "unified" building system.
1911
1912 One cool feature is that you can have your build directory elsewhere,
1913 for example:
1914
1915     make clean          # Clean the current configuration away
1916     mkdir $plausible_builddir
1917     cd $plausible_builddir
1918     $plausible_to_sourcedir/config --unified
1919     make
1920     make test
1921
1922 Please report any problem you have.
1923 ----------------------------------------------------------------------
1924
1925 EOF
1926 }
1927
1928 exit(0);
1929
1930 ######################################################################
1931 #
1932 # Helpers and utility functions
1933 #
1934
1935 # Configuration file reading #########################################
1936
1937 # Helper function to implement conditional inheritance depending on the
1938 # value of $no_asm.  Used in inherit_from values as follows:
1939 #
1940 #      inherit_from => [ "template", asm("asm_tmpl") ]
1941 #
1942 sub asm {
1943     my @x = @_;
1944     sub {
1945         $no_asm ? () : @x;
1946     }
1947 }
1948
1949 # Helper function to implement adding values to already existing configuration
1950 # values.  It handles elements that are ARRAYs, CODEs and scalars
1951 sub _add {
1952     my $separator = shift;
1953
1954     # If there's any ARRAY in the collection of values OR the separator
1955     # is undef, we will return an ARRAY of combined values, otherwise a
1956     # string of joined values with $separator as the separator.
1957     my $found_array = !defined($separator);
1958
1959     my @values =
1960         map {
1961             if (ref($_) eq "ARRAY") {
1962                 $found_array = 1;
1963                 @$_;
1964             } else {
1965                 $_;
1966             }
1967     } (@_);
1968
1969     if ($found_array) {
1970         [ @values ];
1971     } else {
1972         join($separator, @values);
1973     }
1974 }
1975 sub add_before {
1976     my $separator = shift;
1977     my @x = @_;
1978     sub { _add($separator, @x, @_) };
1979 }
1980 sub add {
1981     my $separator = shift;
1982     my @x = @_;
1983     sub { _add($separator, @_, @x) };
1984 }
1985
1986 # configuration reader, evaluates the input file as a perl script and expects
1987 # it to fill %targets with target configurations.  Those are then added to
1988 # %table.
1989 sub read_config {
1990     my $fname = shift;
1991     open(CONFFILE, "< $fname")
1992         or die "Can't open configuration file '$fname'!\n";
1993     my $x = $/;
1994     undef $/;
1995     my $content = <CONFFILE>;
1996     $/ = $x;
1997     close(CONFFILE);
1998     my %targets = ();
1999     {
2000         local %table = %::table;    # Protect %table from tampering
2001
2002         eval $content;
2003         warn $@ if $@;
2004     }
2005
2006     # For each target, check that it's configured with a hash table.
2007     foreach (keys %targets) {
2008         if (ref($targets{$_}) ne "HASH") {
2009             if (ref($targets{$_}) eq "") {
2010                 warn "Deprecated target configuration for $_, ignoring...\n";
2011             } else {
2012                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2013             }
2014             delete $targets{$_};
2015         }
2016     }
2017
2018     %table = (%table, %targets);
2019
2020 }
2021
2022 # configuration resolver.  Will only resolve all the lazy evalutation
2023 # codeblocks for the chozen target and all those it inherits from,
2024 # recursively
2025 sub resolve_config {
2026     my $target = shift;
2027     my @breadcrumbs = @_;
2028
2029     if (grep { $_ eq $target } @breadcrumbs) {
2030         die "inherit_from loop!  target backtrace:\n  "
2031             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2032     }
2033
2034     if (!defined($table{$target})) {
2035         warn "Warning! target $target doesn't exist!\n";
2036         return ();
2037     }
2038     # Recurse through all inheritances.  They will be resolved on the
2039     # fly, so when this operation is done, they will all just be a
2040     # bunch of attributes with string values.
2041     # What we get here, though, are keys with references to lists of
2042     # the combined values of them all.  We will deal with lists after
2043     # this stage is done.
2044     my %combined_inheritance = ();
2045     if ($table{$target}->{inherit_from}) {
2046         my @inherit_from =
2047             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2048         foreach (@inherit_from) {
2049             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2050
2051             # 'template' is a marker that's considered private to
2052             # the config that had it.
2053             delete $inherited_config{template};
2054
2055             map {
2056                 if (!$combined_inheritance{$_}) {
2057                     $combined_inheritance{$_} = [];
2058                 }
2059                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2060             } keys %inherited_config;
2061         }
2062     }
2063
2064     # We won't need inherit_from in this target any more, since we've
2065     # resolved all the inheritances that lead to this
2066     delete $table{$target}->{inherit_from};
2067
2068     # Now is the time to deal with those lists.  Here's the place to
2069     # decide what shall be done with those lists, all based on the
2070     # values of the target we're currently dealing with.
2071     # - If a value is a coderef, it will be executed with the list of
2072     #   inherited values as arguments.
2073     # - If the corresponding key doesn't have a value at all or is the
2074     #   emoty string, the inherited value list will be run through the
2075     #   default combiner (below), and the result becomes this target's
2076     #   value.
2077     # - Otherwise, this target's value is assumed to be a string that
2078     #   will simply override the inherited list of values.
2079     my $default_combiner = add(" ");
2080
2081     my %all_keys =
2082         map { $_ => 1 } (keys %combined_inheritance,
2083                          keys %{$table{$target}});
2084     foreach (sort keys %all_keys) {
2085
2086         # Current target doesn't have a value for the current key?
2087         # Assign it the default combiner, the rest of this loop body
2088         # will handle it just like any other coderef.
2089         if (!exists $table{$target}->{$_}) {
2090             $table{$target}->{$_} = $default_combiner;
2091         }
2092
2093         my $valuetype = ref($table{$target}->{$_});
2094         if ($valuetype eq "CODE") {
2095             # CODE reference, execute it with the inherited values as
2096             # arguments.
2097             $table{$target}->{$_} =
2098                 $table{$target}->{$_}->(@{$combined_inheritance{$_}});
2099         } elsif ($valuetype eq "ARRAY" || $valuetype eq "") {
2100             # ARRAY or Scalar, just leave it as is.
2101         } else {
2102             # Some other type of reference that we don't handle.
2103             # Better to abort at this point.
2104             die "cannot handle reference type $valuetype,"
2105                 ," found in target $target -> $_\n";
2106         }
2107     }
2108
2109     # Finally done, return the result.
2110     return %{$table{$target}};
2111 }
2112
2113 sub usage
2114         {
2115         print STDERR $usage;
2116         print STDERR "\npick os/compiler from:\n";
2117         my $j=0;
2118         my $i;
2119         my $k=0;
2120         foreach $i (sort keys %table)
2121                 {
2122                 next if $table{$i}->{template};
2123                 next if $i =~ /^debug/;
2124                 $k += length($i) + 1;
2125                 if ($k > 78)
2126                         {
2127                         print STDERR "\n";
2128                         $k=length($i);
2129                         }
2130                 print STDERR $i . " ";
2131                 }
2132         foreach $i (sort keys %table)
2133                 {
2134                 next if $table{$i}->{template};
2135                 next if $i !~ /^debug/;
2136                 $k += length($i) + 1;
2137                 if ($k > 78)
2138                         {
2139                         print STDERR "\n";
2140                         $k=length($i);
2141                         }
2142                 print STDERR $i . " ";
2143                 }
2144         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2145         exit(1);
2146         }
2147
2148 sub run_dofile()
2149 {
2150     my $out = shift;
2151     my @templates = @_;
2152
2153     unlink $out || warn "Can't remove $out, $!"
2154         if -f $out;
2155     foreach (@templates) {
2156         die "Can't open $_, $!" unless -f $_;
2157     }
2158     my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2159     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2160     system($cmd);
2161     exit 1 if $? != 0;
2162     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2163 }
2164
2165 # Configuration printer ##############################################
2166
2167 sub print_table_entry
2168 {
2169     my $target = shift;
2170     my %target = resolve_config($target);
2171     my $type = shift;
2172
2173     # Don't print the templates
2174     return if $target{template};
2175
2176     my @sequence = (
2177         "sys_id",
2178         "cc",
2179         "cflags",
2180         "defines",
2181         "debug_cflags",
2182         "debug_defines",
2183         "release_cflags",
2184         "release_defines",
2185         "thread_cflag",
2186         "unistd",
2187         "ld",
2188         "lflags",
2189         "plib_lflags",
2190         "ex_libs",
2191         "debug_lflags",
2192         "debug_plib_lflags",
2193         "debug_ex_libs",
2194         "release_lflags",
2195         "release_plib_lflags",
2196         "release_ex_libs",
2197         "bn_ops",
2198         "cpuid_obj",
2199         "bn_obj",
2200         "ec_obj",
2201         "des_obj",
2202         "aes_obj",
2203         "bf_obj",
2204         "md5_obj",
2205         "sha1_obj",
2206         "cast_obj",
2207         "rc4_obj",
2208         "rmd160_obj",
2209         "rc5_obj",
2210         "wp_obj",
2211         "cmll_obj",
2212         "modes_obj",
2213         "padlock_obj",
2214         "perlasm_scheme",
2215         "dso_scheme",
2216         "shared_target",
2217         "shared_cflag",
2218         "shared_ldflag",
2219         "shared_rcflag",
2220         "shared_extension",
2221         "shared_extension_simple",
2222         "shared_import_extension",
2223         "dso_extension",
2224         "obj_extension",
2225         "exe_extension",
2226         "ranlib",
2227         "ar",
2228         "arflags",
2229         "multilib",
2230         "build_scheme",
2231         );
2232
2233     if ($type eq "TABLE") {
2234         print "\n";
2235         print "*** $target\n";
2236         printf "\$%-12s = %s\n", $_, $target{$_} foreach (@sequence);
2237     } elsif ($type eq "HASH") {
2238         my $largest =
2239             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2240         print "    '$target' => {\n";
2241         foreach (@sequence) {
2242             if ($target{$_}) {
2243                 print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2244             }
2245         }
2246         print "    },\n";
2247     }
2248 }
2249
2250 # Utility routines ###################################################
2251
2252 # On VMS, if the given file is a logical name, File::Spec::Functions
2253 # will consider it an absolute path.  There are cases when we want a
2254 # purely syntactic check without checking the environment.
2255 sub isabsolute {
2256     my $file = shift;
2257
2258     # On non-platforms, we just use file_name_is_absolute().
2259     return file_name_is_absolute($file) unless $^O eq "VMS";
2260
2261     # If the file spec includes a device or a directpry spec,
2262     # file_name_is_absolute() is perfectly safe.
2263     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2264
2265     # Here, we know the given file spec isn't absolute
2266     return 0;
2267 }
2268
2269 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2270 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2271 # realpath() requires that at least all path components except the last is an
2272 # existing directory.  On VMS, the last component of the directory spec must
2273 # exist.
2274 sub absolutedir {
2275     my $dir = shift;
2276
2277     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2278     # will return the volume name for the device, no matter what.  Also,
2279     # it will return an incorrect directory spec if the argument is a
2280     # directory that doesn't exist.
2281     if ($^O eq "VMS") {
2282         return rel2abs($dir);
2283     }
2284
2285     # We use realpath() on Unix, since no other will properly clean out
2286     # a directory spec.
2287     use Cwd qw/realpath/;
2288
2289     return realpath($dir);
2290 }
2291
2292 sub which
2293         {
2294         my($name)=@_;
2295         my $path;
2296         foreach $path (split /:/, $ENV{PATH})
2297                 {
2298                 if (-f "$path/$name$target{exe_extension}" and -x _)
2299                         {
2300                         return "$path/$name$target{exe_extension}" unless ($name eq "perl" and
2301                          system("$path/$name$target{exe_extension} -e " . '\'exit($]<5.0);\''));
2302                         }
2303                 }
2304         }
2305
2306 sub quotify {
2307     my %processors = (
2308         perl    => sub { my $x = shift;
2309                          $x =~ s/([\\\$\@"])/\\$1/g;
2310                          return '"'.$x.'"'; },
2311         );
2312     my $for = shift;
2313     my $processor =
2314         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2315
2316     map { $processor->($_); } @_;
2317 }
2318
2319 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2320 # $filename is a file name to read from
2321 # $line_concat_cond_re is a regexp detecting a line continuation ending
2322 # $line_concat is a CODEref that takes care of concatenating two lines
2323 sub collect_from_file {
2324     my $filename = shift;
2325     my $line_concat_cond_re = shift;
2326     my $line_concat = shift;
2327
2328     open my $fh, $filename || die "unable to read $filename: $!\n";
2329     return sub {
2330         my $saved_line = "";
2331         $_ = "";
2332         while (<$fh>) {
2333             s|\R$||;
2334             if (defined $line_concat) {
2335                 $_ = $line_concat->($saved_line, $_);
2336                 $saved_line = "";
2337             }
2338             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2339                 $saved_line = $_;
2340                 next;
2341             }
2342             return $_;
2343         }
2344         die "$filename ending with continuation line\n" if $_;
2345         close $fh;
2346         return undef;
2347     }
2348 }
2349
2350 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2351 # $array is an ARRAYref of lines
2352 # $line_concat_cond_re is a regexp detecting a line continuation ending
2353 # $line_concat is a CODEref that takes care of concatenating two lines
2354 sub collect_from_array {
2355     my $array = shift;
2356     my $line_concat_cond_re = shift;
2357     my $line_concat = shift;
2358     my @array = (@$array);
2359
2360     return sub {
2361         my $saved_line = "";
2362         $_ = "";
2363         while (defined($_ = shift @array)) {
2364             s|\R$||;
2365             if (defined $line_concat) {
2366                 $_ = $line_concat->($saved_line, $_);
2367                 $saved_line = "";
2368             }
2369             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2370                 $saved_line = $_;
2371                 next;
2372             }
2373             return $_;
2374         }
2375         die "input text ending with continuation line\n" if $_;
2376         return undef;
2377     }
2378 }
2379
2380 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2381 # $lineiterator is a CODEref that delivers one line at a time.
2382 # All following arguments are regex/CODEref pairs, where the regexp detects a
2383 # line and the CODEref does something with the result of the regexp.
2384 sub collect_information {
2385     my $lineiterator = shift;
2386     my %collectors = @_;
2387
2388     while(defined($_ = $lineiterator->())) {
2389         s|\R$||;
2390         my $found = 0;
2391         foreach my $re (keys %collectors) {
2392             if ($re ne "OTHERWISE" && /$re/) {
2393                 $collectors{$re}->($lineiterator);
2394                 $found = 1;
2395             };
2396         }
2397         if ($collectors{"OTHERWISE"}) {
2398             $collectors{"OTHERWISE"}->($lineiterator, $_)
2399                 unless $found || !defined $collectors{"OTHERWISE"};
2400         }
2401     }
2402 }