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