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