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