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