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