Comment away the extra checks in Configure
[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     "makedepend",
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 (/^makedepend$/)
800                 { }
801         elsif (/^zlib-dynamic$/)
802                 { }
803         elsif (/^sse2$/)
804                 { $no_sse2 = 1; }
805         elsif (/^engine$/)
806                 {
807                 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
808                 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
809                 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
810                 }
811         else
812                 {
813                 my ($ALGO, $algo);
814                 ($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
815
816                 if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/ || /^async$/
817                                 || /^autoalginit/ || /^autoerrinit/)
818                         {
819                         push @{$config{openssl_other_defines}}, "OPENSSL_NO_$ALGO";
820                         print " OPENSSL_NO_$ALGO";
821
822                         if (/^err$/)    { push @user_defines, "OPENSSL_NO_ERR"; }
823                         }
824                 else
825                         {
826                         ($ALGO,$algo) = ("RMD160","rmd160") if ($algo eq "ripemd");
827
828                         push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$ALGO";
829                         print " OPENSSL_NO_$ALGO";
830
831                         # fix-up crypto/directory name(s)
832                         $algo="whrlpool" if $algo eq "whirlpool";
833                         $algo="ripemd" if $algo eq "rmd160";
834                         @{$config{sdirs}} = grep { $_ ne $algo} @{$config{sdirs}};
835
836                         print " (skip dir)";
837                         }
838                 }
839
840         print "\n";
841         }
842
843 print "Configuring for $target\n";
844
845 # Support for legacy targets having a name starting with 'debug-'
846 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
847 if ($d) {
848     $config{build_type} = "debug";
849
850     # If we do not find debug-foo in the table, the target is set to foo.
851     if (!$table{$target}) {
852         $target = $t;
853     }
854 }
855 $config{target} = $target;
856 my %target = resolve_config($target);
857
858 &usage if (!%target || $target{template});
859
860 %target = ( %{$table{DEFAULTS}}, %target );
861
862 $target{exe_extension}="";
863 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
864                                   || $config{target} =~ /^(?:Cygwin|mingw)/);
865 $target{exe_extension}=".nlm" if ($config{target} =~ /netware/);
866 $target{exe_extension}=".pm"  if ($config{target} =~ /vos/);
867
868 ($target{shared_extension_simple}=$target{shared_extension})
869     =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||;
870 $target{dso_extension}=$target{shared_extension_simple};
871 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
872     if ($config{target} =~ /^(?:Cygwin|mingw)/);
873
874
875 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
876     if $config{cross_compile_prefix} eq "";
877
878 # Allow overriding the names of some tools.  USE WITH CARE
879 $config{perl} =    $ENV{'PERL'}    || which("perl5") || which("perl") || "perl";
880 $target{cc} =      $ENV{'CC'}      || $target{cc}      || "cc";
881 $target{ranlib} =  $ENV{'RANLIB'}  || $target{ranlib}  || which("ranlib") || "true";
882 $target{ar} =      $ENV{'AR'}      || $target{ar}      || "ar";
883 $target{nm} =      $ENV{'NM'}      || $target{nm}      || "nm";
884
885 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
886 # or release_ attributes.
887 # Do it in such a way that no spurious space is appended (hence the grep).
888 $config{defines} = [];
889 $config{cflags} = "";
890 $config{ex_libs} = "";
891 $config{shared_ldflag} = "";
892
893 # Make sure build_scheme is consistent.
894 $target{build_scheme} = [ $target{build_scheme} ]
895     if ref($target{build_scheme}) ne "ARRAY";
896
897 ###### TO BE REMOVED WHEN CLASSIC BUILD IS REMOVED
898 ######
899 ###### If the user has chosen --classic, we give it to them.
900 ###### If they try that with an out-of-source config, we complain.
901 if ($target{build_scheme}->[0] eq "unified" && $classic) {
902     die "Can't perform a classic build out of source tree\n"
903         if $srcdir ne $blddir;
904
905     $target{build_scheme} = { unix    => [ "unixmake" ],
906                               windows => [ "mk1mf", $target{build_scheme}->[2] ],
907                               VMS     => undef } -> {$target{build_scheme}->[1]};
908
909     die "Classic mode unavailable on this platform\n"
910         unless defined($target{build_scheme});
911 }
912
913 my ($builder, $builder_platform, @builder_opts) =
914     @{$target{build_scheme}};
915
916 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
917         {
918         $config{cflags} .= " -mno-cygwin";
919         $config{shared_ldflag} .= " -mno-cygwin";
920         }
921
922 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
923         # minimally required architecture flags for assembly modules
924         $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
925         $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
926 }
927
928 my $no_shared_warn=0;
929 my $no_user_cflags=0;
930 my $no_user_defines=0;
931
932 # The DSO code currently always implements all functions so that no
933 # applications will have to worry about that from a compilation point
934 # of view. However, the "method"s may return zero unless that platform
935 # has support compiled in for them. Currently each method is enabled
936 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
937 # string entry into using the following logic;
938 if (!$disabled{dso} && $target{dso_scheme} ne "")
939         {
940         $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
941         if ($target{dso_scheme} eq "DLFCN")
942                 {
943                 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
944                 }
945         elsif ($target{dso_scheme} eq "DLFCN_NO_H")
946                 {
947                 unshift @{$config{defines}}, "DSO_DLFCN";
948                 }
949         else
950                 {
951                 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
952                 }
953         }
954
955 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
956
957 if ($disabled{asm})
958         {
959         if ($config{fips})
960                 {
961                 @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}};
962                 @{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}};
963                 }
964         }
965
966 # If threads aren't disabled, check how possible they are
967 unless ($disabled{threads}) {
968     if ($auto_threads) {
969         # Enabled by default, disable it forcibly if unavailable
970         if ($target{thread_scheme} eq "(unknown)") {
971             $disabled{threads} = "unavailable";
972         }
973     } else {
974         # The user chose to enable threads explicitely, let's see
975         # if there's a chance that's possible
976         if ($target{thread_scheme} eq "(unknown)") {
977             # If the user asked for "threads" and we don't have internal
978             # knowledge how to do it, [s]he is expected to provide any
979             # system-dependent compiler options that are necessary.  We
980             # can't truly check that the given options are correct, but
981             # we expect the user to know what [s]He is doing.
982             if ($no_user_cflags && $no_user_defines) {
983                 die "You asked for multi-threading support, but didn't\n"
984                     ,"provide any system-specific compiler options\n";
985             }
986         }
987     }
988 }
989
990 # If threads still aren't disabled, add a C macro to ensure the source
991 # code knows about it.  Any other flag is taken care of by the configs.
992 unless($disabled{threads}) {
993     foreach (("defines", "openssl_thread_defines")) {
994         push @{$config{$_}}, "OPENSSL_THREADS";
995     }
996 }
997
998 # With "deprecated" disable all deprecated features.
999 if (defined($disabled{"deprecated"})) {
1000         $config{api} = $maxapi;
1001 }
1002
1003 if ($target{shared_target} eq "")
1004         {
1005         $no_shared_warn = 1
1006             if ((!$disabled{shared} || !$disabled{"dynamic-engine"})
1007                 && !$config{fips});
1008         $disabled{shared} = "no-shared-target";
1009         $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1010             "no-shared-target";
1011         }
1012
1013 if ($disabled{"dynamic-engine"}) {
1014         push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1015         $config{dynamic_engines} = 0;
1016 } else {
1017         push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1018         $config{dynamic_engines} = 1;
1019 }
1020
1021 #
1022 # Platform fix-ups
1023 #
1024
1025 # This saves the build files from having to check
1026 if ($disabled{pic})
1027         {
1028         $target{shared_cflag} = $target{shared_ldflag} =
1029                 $target{shared_rcflag} = "";
1030         }
1031 else
1032         {
1033         push @{$config{defines}}, "OPENSSL_PIC";
1034         }
1035
1036 if ($target{sys_id} ne "")
1037         {
1038         push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1039         }
1040
1041 unless ($disabled{asm}) {
1042     $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1043     $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1044
1045     # bn-586 is the only one implementing bn_*_part_words
1046     push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1047     push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1048
1049     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1050     push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1051     push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1052
1053     if ($config{fips}) {
1054         push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
1055     }
1056
1057     if ($target{sha1_asm_src}) {
1058         push @{$config{defines}}, "SHA1_ASM"   if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1059         push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1060         push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1061     }
1062     if ($target{md5_asm_src}) {
1063         push @{$config{defines}}, "MD5_ASM";
1064     }
1065     $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1066     if ($target{rmd160_asm_src}) {
1067         push @{$config{defines}}, "RMD160_ASM";
1068     }
1069     if ($target{aes_asm_src}) {
1070         push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1071         # aes-ctr.fake is not a real file, only indication that assembler
1072         # module implements AES_ctr32_encrypt...
1073         push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1074         # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1075         push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1076         $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1077         push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1078         push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1079     }
1080     if ($target{wp_asm_src} =~ /mmx/) {
1081         if ($config{processor} eq "386") {
1082             $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1083         } elsif (!$disabled{"whirlpool"}) {
1084             push @{$config{defines}}, "WHIRLPOOL_ASM";
1085         }
1086     }
1087     if ($target{modes_asm_src} =~ /ghash-/) {
1088         push @{$config{defines}}, "GHASH_ASM";
1089     }
1090     if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1091         push @{$config{defines}}, "ECP_NISTZ256_ASM";
1092     }
1093     if ($target{poly1305_asm_src} ne "") {
1094         push @{$config{defines}}, "POLY1305_ASM";
1095     }
1096 }
1097
1098 my $ecc = $target{cc};
1099 if ($^O ne "VMS" && !$disabled{makedepend}) {
1100     # Is the compiler gcc or clang?  $ecc is used below to see if
1101     # error-checking can be turned on.
1102     my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1103     $config{makedepprog} = which('makedepend');
1104     open(PIPE, "$ccpcc --version 2>&1 | head -2 |");
1105     while ( <PIPE> ) {
1106         # Find the version number and save the major.
1107         m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
1108         # We know that GNU C version 3 and up as well as all clang
1109         # versions support dependency generation
1110         $config{makedepprog} = $ccpcc if /clang/ || (/gcc/ && $1 > 3);
1111         $ecc = "clang" if /clang/;
1112         $ecc = "gcc" if /gcc/;
1113     }
1114     close(PIPE);
1115
1116     $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1117 }
1118
1119
1120
1121 # Deal with bn_ops ###################################################
1122
1123 $config{bn_ll}                  =0;
1124 $config{export_var_as_fn}       =0;
1125 my $def_int="unsigned int";
1126 $config{rc4_int}                =$def_int;
1127 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1128
1129 my $count = 0;
1130 foreach (sort split(/\s+/,$target{bn_ops})) {
1131     $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1132     $config{export_var_as_fn}=1                 if $_ eq 'EXPORT_VAR_AS_FN';
1133     $config{bn_ll}=1                            if $_ eq 'BN_LLONG';
1134     $config{rc4_int}="unsigned char"            if $_ eq 'RC4_CHAR';
1135     ($config{b64l},$config{b64},$config{b32})
1136         =(0,1,0)                                if $_ eq 'SIXTY_FOUR_BIT';
1137     ($config{b64l},$config{b64},$config{b32})
1138         =(1,0,0)                                if $_ eq 'SIXTY_FOUR_BIT_LONG';
1139     ($config{b64l},$config{b64},$config{b32})
1140         =(0,0,1)                                if $_ eq 'THIRTY_TWO_BIT';
1141 }
1142 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1143     if $count > 1;
1144
1145
1146 # Hack cflags for better warnings (dev option) #######################
1147
1148 # "Stringify" the C flags string.  This permits it to be made part of a string
1149 # and works as well on command lines.
1150 $config{cflags} =~ s/([\\\"])/\\\1/g;
1151
1152 if (defined($config{api})) {
1153     $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1154     my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1155     push @{$config{defines}}, $apiflag;
1156 }
1157
1158 if ($strict_warnings)
1159         {
1160         my $wopt;
1161         die "ERROR --strict-warnings requires gcc or clang"
1162             unless $ecc eq 'gcc' || $ecc eq 'clang';
1163         foreach $wopt (split /\s+/, $gcc_devteam_warn)
1164                 {
1165                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1166                 }
1167         if ($ecc eq "clang")
1168                 {
1169                 foreach $wopt (split /\s+/, $clang_devteam_warn)
1170                         {
1171                         $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1172                         }
1173                 }
1174         }
1175
1176 unless ($disabled{"crypto-mdebug-backtrace"})
1177         {
1178         foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1179                 {
1180                 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1181                 }
1182         if ($target =~ /^BSD-/)
1183                 {
1184                 $config{ex_libs} .= " -lexecinfo";
1185                 }
1186         }
1187
1188 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; }
1189 else                    { $no_user_cflags=1;  }
1190 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1191 else               { $no_user_defines=1;    }
1192
1193 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1194
1195 unless ($disabled{engine}) {
1196     $config{afalg}="";
1197     if ($target =~ m/^linux/) {
1198         my $minver = 4*10000 + 1*100 + 0;
1199         if ($config{cross_compile_prefix} eq "") {
1200             my $verstr = `uname -r`;
1201             my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1202             ($mi2) = $mi2 =~ /(\d+)/;
1203             my $ver = $ma*10000 + $mi1*100 + $mi2;
1204             if ($ver < $minver) {
1205                 $disabled{afalg} = "too-old-kernel";
1206             } else {
1207                 push @{$config{engdirs}}, "afalg";
1208             }
1209         }
1210     } else {
1211         $disabled{afalg}  = "not-linux";
1212     }
1213 }
1214
1215 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalg});
1216
1217 # If we use the unified build, collect information from build.info files
1218 my %unified_info = ();
1219
1220 if ($builder eq "unified") {
1221     # Store the name of the template file we will build the build file from
1222     # in %config.  This may be useful for the build file itself.
1223     my $build_file_template =
1224         catfile($srcdir, "Configurations",
1225                 $builder_platform."-".$target{build_file}.".tmpl");
1226     $build_file_template =
1227         catfile($srcdir, "Configurations", $target{build_file}.".tmpl")
1228         if (! -f $build_file_template);
1229     $config{build_file_template} = $build_file_template;
1230
1231     use lib catdir(dirname(__FILE__),"util");
1232     use with_fallback qw(Text::Template);
1233
1234     sub cleandir {
1235         my $base = shift;
1236         my $dir = shift;
1237         my $relativeto = shift || ".";
1238
1239         $dir = catdir($base,$dir) unless isabsolute($dir);
1240
1241         # Make sure the directories we're building in exists
1242         mkpath($dir);
1243
1244         my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1245         #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1246         return $res;
1247     }
1248
1249     sub cleanfile {
1250         my $base = shift;
1251         my $file = shift;
1252         my $relativeto = shift || ".";
1253
1254         $file = catfile($base,$file) unless isabsolute($file);
1255
1256         my $d = dirname($file);
1257         my $f = basename($file);
1258
1259         # Make sure the directories we're building in exists
1260         mkpath($d);
1261
1262         my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1263         #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1264         return $res;
1265     }
1266
1267     my @build_infos = ( [ ".", "build.info" ] );
1268     foreach (@{$config{dirs}}) {
1269         push @build_infos, [ $_, "build.info" ]
1270             if (-f catfile($srcdir, $_, "build.info"));
1271     }
1272     foreach (@{$config{sdirs}}) {
1273         push @build_infos, [ catdir("crypto", $_), "build.info" ]
1274             if (-f catfile($srcdir, "crypto", $_, "build.info"));
1275     }
1276     foreach (@{$config{engdirs}}) {
1277         push @build_infos, [ catdir("engines", $_), "build.info" ]
1278             if (-f catfile($srcdir, "engines", $_, "build.info"));
1279     }
1280
1281     $config{build_infos} = [ ];
1282
1283     foreach (@build_infos) {
1284         my $sourced = catdir($srcdir, $_->[0]);
1285         my $buildd = catdir($blddir, $_->[0]);
1286
1287         mkpath($buildd);
1288
1289         my $f = $_->[1];
1290         # The basic things we're trying to build
1291         my @programs = ();
1292         my @libraries = ();
1293         my @engines = ();
1294         my @scripts = ();
1295         my @extra = ();
1296         my @overrides = ();
1297         my @intermediates = ();
1298         my @rawlines = ();
1299
1300         my %ordinals = ();
1301         my %sources = ();
1302         my %includes = ();
1303         my %depends = ();
1304         my %renames = ();
1305         my %sharednames = ();
1306         my %generate = ();
1307
1308         push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1309         my $template = Text::Template->new(TYPE => 'FILE',
1310                                            SOURCE => catfile($sourced, $f));
1311         die "Something went wrong with $sourced/$f: $!\n" unless $template;
1312         my @text =
1313             split /^/m,
1314             $template->fill_in(HASH => { config => \%config,
1315                                          target => \%target,
1316                                          disabled => \%disabled,
1317                                          builddir => abs2rel($buildd, $blddir),
1318                                          sourcedir => abs2rel($sourced, $blddir),
1319                                          buildtop => abs2rel($blddir, $blddir),
1320                                          sourcetop => abs2rel($srcdir, $blddir) },
1321                                DELIMITERS => [ "{-", "-}" ]);
1322
1323         # The top item of this stack has the following values
1324         # -2 positive already run and we found ELSE (following ELSIF should fail)
1325         # -1 positive already run (skip until ENDIF)
1326         # 0 negatives so far (if we're at a condition, check it)
1327         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1328         # 2 positive ELSE (following ELSIF should fail)
1329         my @skip = ();
1330         collect_information(
1331             collect_from_array([ @text ],
1332                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1333                                                 $l1 =~ s/\\$//; $l1.$l2 }),
1334             # Info we're looking for
1335             qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1336             => sub {
1337                 if (! @skip || $skip[$#skip] >= 0) {
1338                     push @skip, !! $1;
1339                 } else {
1340                     push @skip, -1;
1341                 }
1342             },
1343             qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1344             => sub { die "ELSIF out of scope" if ! @skip;
1345                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1346                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
1347                      $skip[$#skip] = !! $1
1348                          if $skip[$#skip] == 0; },
1349             qr/^\s*ELSE\s*$/
1350             => sub { die "ELSE out of scope" if ! @skip;
1351                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
1352                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1353             qr/^\s*ENDIF\s*$/
1354             => sub { die "ENDIF out of scope" if ! @skip;
1355                      pop @skip; },
1356             qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
1357             => sub { push @programs, split(/\s+/, $1)
1358                          if !@skip || $skip[$#skip] > 0 },
1359             qr/^\s*LIBS\s*=\s*(.*)\s*$/
1360             => sub { push @libraries, split(/\s+/, $1)
1361                          if !@skip || $skip[$#skip] > 0 },
1362             qr/^\s*ENGINES\s*=\s*(.*)\s*$/
1363             => sub { push @engines, split(/\s+/, $1)
1364                          if !@skip || $skip[$#skip] > 0 },
1365             qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
1366             => sub { push @scripts, split(/\s+/, $1)
1367                          if !@skip || $skip[$#skip] > 0 },
1368             qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1369             => sub { push @extra, split(/\s+/, $1)
1370                          if !@skip || $skip[$#skip] > 0 },
1371             qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1372             => sub { push @overrides, split(/\s+/, $1)
1373                          if !@skip || $skip[$#skip] > 0 },
1374
1375             qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1376             => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
1377                          if !@skip || $skip[$#skip] > 0 },
1378             qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1379             => sub { push @{$sources{$1}}, split(/\s+/, $2)
1380                          if !@skip || $skip[$#skip] > 0 },
1381             qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1382             => sub { push @{$includes{$1}}, split(/\s+/, $2)
1383                          if !@skip || $skip[$#skip] > 0 },
1384             qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1385             => sub { push @{$depends{$1}}, split(/\s+/, $2)
1386                          if !@skip || $skip[$#skip] > 0 },
1387             qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1388             => sub { push @{$generate{$1}}, $2
1389                          if !@skip || $skip[$#skip] > 0 },
1390             qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1391             => sub { push @{$renames{$1}}, split(/\s+/, $2)
1392                          if !@skip || $skip[$#skip] > 0 },
1393             qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1394             => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
1395                          if !@skip || $skip[$#skip] > 0 },
1396             qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1397             => sub {
1398                 my $lineiterator = shift;
1399                 my $target_kind = $1;
1400                 while (defined $lineiterator->()) {
1401                     s|\R$||;
1402                     if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1403                         die "ENDRAW doesn't match BEGINRAW"
1404                             if $1 ne $target_kind;
1405                         last;
1406                     }
1407                     next if @skip && $skip[$#skip] <= 0;
1408                     push @rawlines,  $_
1409                         if ($target_kind eq $target{build_file}
1410                             || $target_kind eq $target{build_file}."(".$builder_platform.")");
1411                 }
1412             },
1413             qr/^(?:#.*|\s*)$/ => sub { },
1414             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
1415             );
1416         die "runaway IF?" if (@skip);
1417
1418         foreach (keys %renames) {
1419             die "$_ renamed to more than one thing: "
1420                 ,join(" ", @{$renames{$_}}),"\n"
1421                 if scalar @{$renames{$_}} > 1;
1422             my $dest = cleanfile($buildd, $_, $blddir);
1423             my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1424             die "$dest renamed to more than one thing: "
1425                 ,$unified_info{rename}->{$dest}, $to
1426                 unless !defined($unified_info{rename}->{$dest})
1427                 or $unified_info{rename}->{$dest} eq $to;
1428             $unified_info{rename}->{$dest} = $to;
1429         }
1430
1431         foreach (@programs) {
1432             my $program = cleanfile($buildd, $_, $blddir);
1433             if ($unified_info{rename}->{$program}) {
1434                 $program = $unified_info{rename}->{$program};
1435             }
1436             $unified_info{programs}->{$program} = 1;
1437         }
1438
1439         foreach (@libraries) {
1440             my $library = cleanfile($buildd, $_, $blddir);
1441             if ($unified_info{rename}->{$library}) {
1442                 $library = $unified_info{rename}->{$library};
1443             }
1444             $unified_info{libraries}->{$library} = 1;
1445         }
1446
1447         die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1448 ENGINES can only be used if configured with 'dynamic-engine'.
1449 This is usually a fault in a build.info file.
1450 EOF
1451         foreach (@engines) {
1452             my $library = cleanfile($buildd, $_, $blddir);
1453             if ($unified_info{rename}->{$library}) {
1454                 $library = $unified_info{rename}->{$library};
1455             }
1456             $unified_info{engines}->{$library} = 1;
1457         }
1458
1459         foreach (@scripts) {
1460             my $script = cleanfile($buildd, $_, $blddir);
1461             if ($unified_info{rename}->{$script}) {
1462                 $script = $unified_info{rename}->{$script};
1463             }
1464             $unified_info{scripts}->{$script} = 1;
1465         }
1466
1467         foreach (@extra) {
1468             my $extra = cleanfile($buildd, $_, $blddir);
1469             $unified_info{extra}->{$extra} = 1;
1470         }
1471
1472         foreach (@overrides) {
1473             my $override = cleanfile($buildd, $_, $blddir);
1474             $unified_info{overrides}->{$override} = 1;
1475         }
1476
1477         push @{$unified_info{rawlines}}, @rawlines;
1478
1479         unless ($disabled{shared}) {
1480             # Check sharednames.
1481             foreach (keys %sharednames) {
1482                 my $dest = cleanfile($buildd, $_, $blddir);
1483                 if ($unified_info{rename}->{$dest}) {
1484                     $dest = $unified_info{rename}->{$dest};
1485                 }
1486                 die "shared_name for $dest with multiple values: "
1487                     ,join(" ", @{$sharednames{$_}}),"\n"
1488                     if scalar @{$sharednames{$_}} > 1;
1489                 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1490                 die "shared_name found for a library $dest that isn't defined\n"
1491                     unless $unified_info{libraries}->{$dest};
1492                 die "shared_name for $dest with multiple values: "
1493                     ,$unified_info{sharednames}->{$dest}, ", ", $to
1494                     unless !defined($unified_info{sharednames}->{$dest})
1495                     or $unified_info{sharednames}->{$dest} eq $to;
1496                 $unified_info{sharednames}->{$dest} = $to;
1497             }
1498
1499             # Additionally, we set up sharednames for libraries that don't
1500             # have any, as themselves.
1501             foreach (keys %{$unified_info{libraries}}) {
1502                 if (!defined $unified_info{sharednames}->{$_}) {
1503                     $unified_info{sharednames}->{$_} = $_
1504                 }
1505             }
1506         }
1507
1508         foreach (keys %ordinals) {
1509             my $dest = $_;
1510             my $ddest = cleanfile($buildd, $_, $blddir);
1511             if ($unified_info{rename}->{$ddest}) {
1512                 $ddest = $unified_info{rename}->{$ddest};
1513             }
1514             foreach (@{$ordinals{$dest}}) {
1515                 my %known_ordinals =
1516                     (
1517                      crypto =>
1518                      cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1519                      ssl =>
1520                      cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1521                     );
1522                 my $o = $known_ordinals{$_};
1523                 die "Ordinals for $ddest defined more than once\n"
1524                     if $unified_info{ordinals}->{$ddest};
1525                 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1526             }
1527         }
1528
1529         foreach (keys %sources) {
1530             my $dest = $_;
1531             my $ddest = cleanfile($buildd, $_, $blddir);
1532             if ($unified_info{rename}->{$ddest}) {
1533                 $ddest = $unified_info{rename}->{$ddest};
1534             }
1535             foreach (@{$sources{$dest}}) {
1536                 my $s = cleanfile($sourced, $_, $blddir);
1537
1538                 # If it isn't in the source tree, we assume it's generated
1539                 # in the build tree
1540                 if (! -f $s) {
1541                     $s = cleanfile($buildd, $_, $blddir);
1542                 }
1543                 # We recognise C and asm files
1544                 if ($s =~ /\.[csS]\b$/) {
1545                     (my $o = $_) =~ s/\.[csS]\b$/.o/;
1546                     $o = cleanfile($buildd, $o, $blddir);
1547                     $unified_info{sources}->{$ddest}->{$o} = 1;
1548                     $unified_info{sources}->{$o}->{$s} = 1;
1549                 } else {
1550                     $unified_info{sources}->{$ddest}->{$s} = 1;
1551                 }
1552             }
1553         }
1554
1555         foreach (keys %generate) {
1556             my $dest = $_;
1557             my $ddest = cleanfile($buildd, $_, $blddir);
1558             if ($unified_info{rename}->{$ddest}) {
1559                 $ddest = $unified_info{rename}->{$ddest};
1560             }
1561             die "more than one generator for $dest: "
1562                     ,join(" ", @{$generate{$_}}),"\n"
1563                     if scalar @{$generate{$_}} > 1;
1564             my @generator = split /\s+/, $generate{$dest}->[0];
1565             $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1566             $unified_info{generate}->{$ddest} = [ @generator ];
1567         }
1568
1569         foreach (keys %depends) {
1570             my $dest = $_;
1571             my $ddest = cleanfile($buildd, $_, $blddir);
1572             if ($unified_info{rename}->{$ddest}) {
1573                 $ddest = $unified_info{rename}->{$ddest};
1574             }
1575             foreach (@{$depends{$dest}}) {
1576                 my $d = cleanfile($sourced, $_, $blddir);
1577
1578                 # If we know it's generated, or assume it is because we can't
1579                 # find it in the source tree, we set file we depend on to be
1580                 # in the build tree rather than the source tree, and assume
1581                 # and that there are lines to build it in a BEGINRAW..ENDRAW
1582                 # section or in the Makefile template.
1583                 if (! -f $d
1584                     || !(grep { $d eq $_ }
1585                          map { cleanfile($srcdir, $_, $blddir) }
1586                          (@generated_headers, @generated_by_make_headers))) {
1587                     $d = cleanfile($buildd, $_, $blddir);
1588                 }
1589                 # Take note if the file to depend on is being renamed
1590                 if ($unified_info{rename}->{$d}) {
1591                     $d = $unified_info{rename}->{$d};
1592                 }
1593                 $unified_info{depends}->{$ddest}->{$d} = 1;
1594                 # If we depend on a header file, let's make sure it
1595                 # can get included
1596                 if ($d =~ /\.h$/) {
1597                     my $i = dirname($d);
1598                     push @{$unified_info{includes}->{$ddest}}, $i
1599                         unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1600                 }
1601             }
1602         }
1603
1604         foreach (keys %includes) {
1605             my $dest = $_;
1606             my $ddest = cleanfile($buildd, $_, $blddir);
1607             if ($unified_info{rename}->{$ddest}) {
1608                 $ddest = $unified_info{rename}->{$ddest};
1609             }
1610             foreach (@{$includes{$dest}}) {
1611                 my $i = cleandir($sourced, $_, $blddir);
1612                 push @{$unified_info{includes}->{$ddest}}, $i
1613                     unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1614             }
1615         }
1616     }
1617
1618     ### Make unified_info a bit more efficient
1619     # One level structures
1620     foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1621         $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1622     }
1623     # Two level structures
1624     foreach my $l1 (("sources", "ldadd", "depends")) {
1625         foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1626             $unified_info{$l1}->{$l2} =
1627                 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1628         }
1629     }
1630 }
1631
1632 # For the schemes that need it, we provide the old *_obj configs
1633 # from the *_asm_obj ones
1634 foreach (grep /_(asm|aux)_src$/, keys %target) {
1635     my $src = $_;
1636     (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1637     ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1638 }
1639
1640 # Write down our configuration where it fits #########################
1641
1642 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1643 print OUT <<"EOF";
1644 package configdata;
1645
1646 use strict;
1647 use warnings;
1648
1649 use Exporter;
1650 #use vars qw(\@ISA \@EXPORT);
1651 our \@ISA = qw(Exporter);
1652 our \@EXPORT = qw(\%config \%target %disabled %withargs %unified_info);
1653
1654 EOF
1655 print OUT "our %config = (\n";
1656 foreach (sort keys %config) {
1657     if (ref($config{$_}) eq "ARRAY") {
1658         print OUT "  ", $_, " => [ ", join(", ",
1659                                            map { quotify("perl", $_) }
1660                                            @{$config{$_}}), " ],\n";
1661     } else {
1662         print OUT "  ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1663     }
1664 }
1665 print OUT <<"EOF";
1666 );
1667
1668 EOF
1669 print OUT "our %target = (\n";
1670 foreach (sort keys %target) {
1671     if (ref($target{$_}) eq "ARRAY") {
1672         print OUT "  ", $_, " => [ ", join(", ",
1673                                            map { quotify("perl", $_) }
1674                                            @{$target{$_}}), " ],\n";
1675     } else {
1676         print OUT "  ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1677     }
1678 }
1679 print OUT <<"EOF";
1680 );
1681
1682 EOF
1683 print OUT "our \%available_protocols = (\n";
1684 print OUT "  tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1685 print OUT "  dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1686 print OUT <<"EOF";
1687 );
1688
1689 EOF
1690 print OUT "our \%disabled = (\n";
1691 foreach (sort keys %disabled) {
1692     print OUT "  ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1693 }
1694 print OUT <<"EOF";
1695 );
1696
1697 EOF
1698 print OUT "our %withargs = (\n";
1699 foreach (sort keys %withargs) {
1700     if (ref($withargs{$_}) eq "ARRAY") {
1701         print OUT "  ", $_, " => [ ", join(", ",
1702                                            map { quotify("perl", $_) }
1703                                            @{$withargs{$_}}), " ],\n";
1704     } else {
1705         print OUT "  ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1706     }
1707 }
1708 print OUT <<"EOF";
1709 );
1710
1711 EOF
1712 if ($builder eq "unified") {
1713     my $recurse;
1714     $recurse = sub {
1715         my $indent = shift;
1716         foreach (@_) {
1717             if (ref $_ eq "ARRAY") {
1718                 print OUT " "x$indent, "[\n";
1719                 foreach (@$_) {
1720                     $recurse->($indent + 4, $_);
1721                 }
1722                 print OUT " "x$indent, "],\n";
1723             } elsif (ref $_ eq "HASH") {
1724                 my %h = %$_;
1725                 print OUT " "x$indent, "{\n";
1726                 foreach (sort keys %h) {
1727                     if (ref $h{$_} eq "") {
1728                         print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1729                     } else {
1730                         print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1731                         $recurse->($indent + 8, $h{$_});
1732                     }
1733                 }
1734                 print OUT " "x$indent, "},\n";
1735             } else {
1736                 print OUT " "x$indent, quotify("perl", $_), ",\n";
1737             }
1738         }
1739     };
1740     print OUT "our %unified_info = (\n";
1741     foreach (sort keys %unified_info) {
1742         if (ref $unified_info{$_} eq "") {
1743             print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1744         } else {
1745             print OUT " "x4, quotify("perl", $_), " =>\n";
1746             $recurse->(8, $unified_info{$_});
1747         }
1748     }
1749     print OUT <<"EOF";
1750 );
1751
1752 EOF
1753 }
1754 print OUT "1;\n";
1755 close(OUT);
1756
1757
1758 print "IsMK1MF       =", ($builder eq "mk1mf" ? "yes" : "no"), "\n";
1759 print "CC            =$target{cc}\n";
1760 print "CFLAG         =$target{cflags} $config{cflags}\n";
1761 print "SHARED_CFLAG  =$target{shared_cflag}\n";
1762 print "DEFINES       =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
1763 print "LFLAG         =$target{lflags}\n";
1764 print "PLIB_LFLAG    =$target{plib_lflags}\n";
1765 print "EX_LIBS       =$target{ex_libs} $config{ex_libs}\n";
1766 print "APPS_OBJ      =$target{apps_obj}\n";
1767 print "CPUID_OBJ     =$target{cpuid_obj}\n";
1768 print "UPLINK_OBJ    =$target{uplink_obj}\n";
1769 print "BN_ASM        =$target{bn_obj}\n";
1770 print "EC_ASM        =$target{ec_obj}\n";
1771 print "DES_ENC       =$target{des_obj}\n";
1772 print "AES_ENC       =$target{aes_obj}\n";
1773 print "BF_ENC        =$target{bf_obj}\n";
1774 print "CAST_ENC      =$target{cast_obj}\n";
1775 print "RC4_ENC       =$target{rc4_obj}\n";
1776 print "RC5_ENC       =$target{rc5_obj}\n";
1777 print "MD5_OBJ_ASM   =$target{md5_obj}\n";
1778 print "SHA1_OBJ_ASM  =$target{sha1_obj}\n";
1779 print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
1780 print "CMLL_ENC      =$target{cmll_obj}\n";
1781 print "MODES_OBJ     =$target{modes_obj}\n";
1782 print "PADLOCK_OBJ   =$target{padlock_obj}\n";
1783 print "CHACHA_ENC    =$target{chacha_obj}\n";
1784 print "POLY1305_OBJ  =$target{poly1305_obj}\n";
1785 print "PROCESSOR     =$config{processor}\n";
1786 print "RANLIB        =$target{ranlib}\n";
1787 print "ARFLAGS       =$target{arflags}\n";
1788 print "PERL          =$config{perl}\n";
1789 print "\n";
1790 print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
1791 print "SIXTY_FOUR_BIT mode\n" if $config{b64};
1792 print "THIRTY_TWO_BIT mode\n" if $config{b32};
1793 print "BN_LLONG mode\n" if $config{bn_ll};
1794 print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} != $def_int;
1795
1796 for (@generated_headers) {
1797     mkpath(catdir($blddir, dirname($_)));
1798     run_dofile(catfile($blddir, $_),
1799                catfile($srcdir, $_.".in"));
1800 }
1801
1802 ###
1803 ### When the old "unixmake" scheme goes away, so does this function
1804 ###
1805 sub build_Makefile {
1806     run_dofile("Makefile","Makefile.in");
1807
1808     # Copy all Makefile.in to Makefile (except top-level)
1809     use File::Find;
1810     use IO::File;
1811     find(
1812         {
1813             preprocess => sub {
1814                 grep(!/^\./, @_);
1815             },
1816             wanted => sub {
1817                 return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
1818                 my $in = IO::File->new($_, "r") or
1819                     die sprintf "Error reading Makefile.in in %s: !$\n",
1820                     $File::Find::dir;
1821                 my $out = IO::File->new("Makefile", "w") or
1822                     die sprintf "Error writing Makefile in %s: !$\n",
1823                     $File::Find::dir;
1824                 print $out "# Generated from $_, do not edit\n";
1825                 while (my $line = <$in>) { print $out $line }
1826                 $in->close() or
1827                     die sprintf "Error reading Makefile.in in %s: !$\n",
1828                     $File::Find::dir;
1829                 $out->close() or
1830                     die sprintf "Error writing Makefile in %s: !$\n",
1831                     $File::Find::dir;
1832             },
1833         },
1834         ".");
1835 }
1836
1837 my %builders = (
1838     unified => sub {
1839         run_dofile(catfile($blddir, $target{build_file}),
1840                    $config{build_file_template},
1841                    catfile($srcdir, "Configurations", "common.tmpl"));
1842     },
1843     unixmake => sub {
1844         build_Makefile();
1845
1846         run_dofile("util/domd", "util/domd.in");
1847         chmod 0755, "util/domd";
1848     },
1849     mk1mf => sub {
1850         my $platform = shift;
1851         # The only reason we do this is to have something to build MINFO from
1852         build_Makefile();
1853
1854         # create the ms/version32.rc file if needed
1855         if ($platform ne "netware") {
1856             my ($v1, $v2, $v3, $v4);
1857             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) {
1858                 $v1=hex $1;
1859                 $v2=hex $2;
1860                 $v3=hex $3;
1861                 $v4=hex $4;
1862             }
1863             open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
1864             print OUT <<"EOF";
1865 #include <winver.h>
1866
1867 LANGUAGE 0x09,0x01
1868
1869 1 VERSIONINFO
1870   FILEVERSION $v1,$v2,$v3,$v4
1871   PRODUCTVERSION $v1,$v2,$v3,$v4
1872   FILEFLAGSMASK 0x3fL
1873 #ifdef _DEBUG
1874   FILEFLAGS 0x01L
1875 #else
1876   FILEFLAGS 0x00L
1877 #endif
1878   FILEOS VOS__WINDOWS32
1879   FILETYPE VFT_DLL
1880   FILESUBTYPE 0x0L
1881 BEGIN
1882     BLOCK "StringFileInfo"
1883     BEGIN
1884         BLOCK "040904b0"
1885         BEGIN
1886             // Required:
1887             VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
1888             VALUE "FileDescription", "OpenSSL Shared Library\\0"
1889             VALUE "FileVersion", "$config{version}\\0"
1890 #if defined(CRYPTO)
1891             VALUE "InternalName", "libcrypto32\\0"
1892             VALUE "OriginalFilename", "libcrypto32.dll\\0"
1893 #elif defined(SSL)
1894             VALUE "InternalName", "libssl32\\0"
1895             VALUE "OriginalFilename", "libssl32.dll\\0"
1896 #endif
1897             VALUE "ProductName", "The OpenSSL Toolkit\\0"
1898             VALUE "ProductVersion", "$config{version}\\0"
1899             // Optional:
1900             //VALUE "Comments", "\\0"
1901             VALUE "LegalCopyright", "Copyright © 1998-2015 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
1902             //VALUE "LegalTrademarks", "\\0"
1903             //VALUE "PrivateBuild", "\\0"
1904             //VALUE "SpecialBuild", "\\0"
1905         END
1906     END
1907     BLOCK "VarFileInfo"
1908     BEGIN
1909         VALUE "Translation", 0x409, 0x4b0
1910     END
1911 END
1912 EOF
1913             close(OUT);
1914         }
1915     },
1916     );
1917
1918 $builders{$builder}->($builder_platform, @builder_opts);
1919
1920 print <<"EOF";
1921
1922 Configured for $target.
1923 EOF
1924
1925 print <<"EOF" if ($disabled{threads} eq "unavailable");
1926
1927 The library could not be configured for supporting multi-threaded
1928 applications as the compiler options required on this system are not known.
1929 See file INSTALL for details if you need multi-threading.
1930 EOF
1931
1932 print <<"EOF" if ($no_shared_warn);
1933
1934 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
1935 platform, so we will pretend you gave the option 'no-pic', which also disables
1936 'shared' and 'dynamic-engine'.  If you know how to implement shared libraries
1937 or position independent code, please let us know (but please first make sure
1938 you have tried with a current version of OpenSSL).
1939 EOF
1940
1941 exit(0);
1942
1943 ######################################################################
1944 #
1945 # Helpers and utility functions
1946 #
1947
1948 # Configuration file reading #########################################
1949
1950 # Helper function to implement conditional inheritance depending on the
1951 # value of $disabled{asm}.  Used in inherit_from values as follows:
1952 #
1953 #      inherit_from => [ "template", asm("asm_tmpl") ]
1954 #
1955 sub asm {
1956     my @x = @_;
1957     sub {
1958         $disabled{asm} ? () : @x;
1959     }
1960 }
1961
1962 our $add_called = 0;
1963 # Helper function to implement adding values to already existing configuration
1964 # values.  It handles elements that are ARRAYs, CODEs and scalars
1965 sub _add {
1966     my $separator = shift;
1967
1968     # If there's any ARRAY in the collection of values OR the separator
1969     # is undef, we will return an ARRAY of combined values, otherwise a
1970     # string of joined values with $separator as the separator.
1971     my $found_array = !defined($separator);
1972
1973     my @values =
1974         map {
1975             my $res = $_;
1976             while (ref($res) eq "CODE") {
1977                 $res = $res->();
1978             }
1979             if (defined($res)) {
1980                 if (ref($res) eq "ARRAY") {
1981                     $found_array = 1;
1982                     @$res;
1983                 } else {
1984                     $res;
1985                 }
1986             } else {
1987                 ();
1988             }
1989     } (@_);
1990
1991     $add_called = 1;
1992
1993     if ($found_array) {
1994         [ @values ];
1995     } else {
1996         join($separator, grep { defined($_) && $_ ne "" } @values);
1997     }
1998 }
1999 sub add_before {
2000     my $separator = " ";
2001     if (ref($_[$#_]) eq "HASH") {
2002         my $opts = pop;
2003         $separator = $opts->{separator};
2004     }
2005     my @x = @_;
2006     sub { _add($separator, @x, @_) };
2007 }
2008 sub add {
2009     my $separator = " ";
2010     if (ref($_[$#_]) eq "HASH") {
2011         my $opts = pop;
2012         $separator = $opts->{separator};
2013     }
2014     my @x = @_;
2015     sub { _add($separator, @_, @x) };
2016 }
2017
2018 # configuration reader, evaluates the input file as a perl script and expects
2019 # it to fill %targets with target configurations.  Those are then added to
2020 # %table.
2021 sub read_config {
2022     my $fname = shift;
2023     open(CONFFILE, "< $fname")
2024         or die "Can't open configuration file '$fname'!\n";
2025     my $x = $/;
2026     undef $/;
2027     my $content = <CONFFILE>;
2028     $/ = $x;
2029     close(CONFFILE);
2030     my %targets = ();
2031     {
2032         local %table = %::table;    # Protect %table from tampering
2033
2034         eval $content;
2035         warn $@ if $@;
2036     }
2037
2038     # For each target, check that it's configured with a hash table.
2039     foreach (keys %targets) {
2040         if (ref($targets{$_}) ne "HASH") {
2041             if (ref($targets{$_}) eq "") {
2042                 warn "Deprecated target configuration for $_, ignoring...\n";
2043             } else {
2044                 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2045             }
2046             delete $targets{$_};
2047         }
2048     }
2049
2050     %table = (%table, %targets);
2051
2052 }
2053
2054 # configuration resolver.  Will only resolve all the lazy evalutation
2055 # codeblocks for the chozen target and all those it inherits from,
2056 # recursively
2057 sub resolve_config {
2058     my $target = shift;
2059     my @breadcrumbs = @_;
2060
2061 #    my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2062
2063     if (grep { $_ eq $target } @breadcrumbs) {
2064         die "inherit_from loop!  target backtrace:\n  "
2065             ,$target,"\n  ",join("\n  ", @breadcrumbs),"\n";
2066     }
2067
2068     if (!defined($table{$target})) {
2069         warn "Warning! target $target doesn't exist!\n";
2070         return ();
2071     }
2072     # Recurse through all inheritances.  They will be resolved on the
2073     # fly, so when this operation is done, they will all just be a
2074     # bunch of attributes with string values.
2075     # What we get here, though, are keys with references to lists of
2076     # the combined values of them all.  We will deal with lists after
2077     # this stage is done.
2078     my %combined_inheritance = ();
2079     if ($table{$target}->{inherit_from}) {
2080         my @inherit_from =
2081             map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2082         foreach (@inherit_from) {
2083             my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2084
2085             # 'template' is a marker that's considered private to
2086             # the config that had it.
2087             delete $inherited_config{template};
2088
2089             map {
2090                 if (!$combined_inheritance{$_}) {
2091                     $combined_inheritance{$_} = [];
2092                 }
2093                 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2094             } keys %inherited_config;
2095         }
2096     }
2097
2098     # We won't need inherit_from in this target any more, since we've
2099     # resolved all the inheritances that lead to this
2100     delete $table{$target}->{inherit_from};
2101
2102     # Now is the time to deal with those lists.  Here's the place to
2103     # decide what shall be done with those lists, all based on the
2104     # values of the target we're currently dealing with.
2105     # - If a value is a coderef, it will be executed with the list of
2106     #   inherited values as arguments.
2107     # - If the corresponding key doesn't have a value at all or is the
2108     #   emoty string, the inherited value list will be run through the
2109     #   default combiner (below), and the result becomes this target's
2110     #   value.
2111     # - Otherwise, this target's value is assumed to be a string that
2112     #   will simply override the inherited list of values.
2113     my $default_combiner = add();
2114
2115     my %all_keys =
2116         map { $_ => 1 } (keys %combined_inheritance,
2117                          keys %{$table{$target}});
2118
2119     sub process_values {
2120         my $object    = shift;
2121         my $inherited = shift;  # Always a [ list ]
2122         my $target    = shift;
2123         my $entry     = shift;
2124
2125         $add_called = 0;
2126
2127         while(ref($object) eq "CODE") {
2128             $object = $object->(@$inherited);
2129         }
2130         if (!defined($object)) {
2131             return ();
2132         }
2133         elsif (ref($object) eq "ARRAY") {
2134             local $add_called;  # To make sure recursive calls don't affect it
2135             return [ map { process_values($_, $inherited, $target, $entry) }
2136                      @$object ];
2137         } elsif (ref($object) eq "") {
2138             return $object;
2139         } else {
2140             die "cannot handle reference type ",ref($object)
2141                 ," found in target ",$target," -> ",$entry,"\n";
2142         }
2143     }
2144
2145     foreach (sort keys %all_keys) {
2146         my $previous = $combined_inheritance{$_};
2147
2148         # Current target doesn't have a value for the current key?
2149         # Assign it the default combiner, the rest of this loop body
2150         # will handle it just like any other coderef.
2151         if (!exists $table{$target}->{$_}) {
2152             $table{$target}->{$_} = $default_combiner;
2153         }
2154
2155         $table{$target}->{$_} = process_values($table{$target}->{$_},
2156                                                $combined_inheritance{$_},
2157                                                $target, $_);
2158         unless(defined($table{$target}->{$_})) {
2159             delete $table{$target}->{$_};
2160         }
2161 #        if ($extra_checks &&
2162 #            $previous && !($add_called ||  $previous ~~ $table{$target}->{$_})) {
2163 #            warn "$_ got replaced in $target\n";
2164 #        }
2165     }
2166
2167     # Finally done, return the result.
2168     return %{$table{$target}};
2169 }
2170
2171 sub usage
2172         {
2173         print STDERR $usage;
2174         print STDERR "\npick os/compiler from:\n";
2175         my $j=0;
2176         my $i;
2177         my $k=0;
2178         foreach $i (sort keys %table)
2179                 {
2180                 next if $table{$i}->{template};
2181                 next if $i =~ /^debug/;
2182                 $k += length($i) + 1;
2183                 if ($k > 78)
2184                         {
2185                         print STDERR "\n";
2186                         $k=length($i);
2187                         }
2188                 print STDERR $i . " ";
2189                 }
2190         foreach $i (sort keys %table)
2191                 {
2192                 next if $table{$i}->{template};
2193                 next if $i !~ /^debug/;
2194                 $k += length($i) + 1;
2195                 if ($k > 78)
2196                         {
2197                         print STDERR "\n";
2198                         $k=length($i);
2199                         }
2200                 print STDERR $i . " ";
2201                 }
2202         print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2203         exit(1);
2204         }
2205
2206 sub run_dofile()
2207 {
2208     my $out = shift;
2209     my @templates = @_;
2210
2211     unlink $out || warn "Can't remove $out, $!"
2212         if -f $out;
2213     foreach (@templates) {
2214         die "Can't open $_, $!" unless -f $_;
2215     }
2216     my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2217     #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2218     system($cmd);
2219     exit 1 if $? != 0;
2220     rename("$out.new", $out) || die "Can't rename $out.new, $!";
2221 }
2222
2223 # Configuration printer ##############################################
2224
2225 sub print_table_entry
2226 {
2227     my $target = shift;
2228     my %target = resolve_config($target);
2229     my $type = shift;
2230
2231     # Don't print the templates
2232     return if $target{template};
2233
2234     my @sequence = (
2235         "sys_id",
2236         "cc",
2237         "cflags",
2238         "defines",
2239         "unistd",
2240         "ld",
2241         "lflags",
2242         "plib_lflags",
2243         "ex_libs",
2244         "bn_ops",
2245         "cpuid_obj",
2246         "bn_obj",
2247         "ec_obj",
2248         "des_obj",
2249         "aes_obj",
2250         "bf_obj",
2251         "md5_obj",
2252         "sha1_obj",
2253         "cast_obj",
2254         "rc4_obj",
2255         "rmd160_obj",
2256         "rc5_obj",
2257         "wp_obj",
2258         "cmll_obj",
2259         "modes_obj",
2260         "padlock_obj",
2261         "thread_scheme",
2262         "perlasm_scheme",
2263         "dso_scheme",
2264         "shared_target",
2265         "shared_cflag",
2266         "shared_ldflag",
2267         "shared_rcflag",
2268         "shared_extension",
2269         "shared_extension_simple",
2270         "shared_import_extension",
2271         "dso_extension",
2272         "obj_extension",
2273         "exe_extension",
2274         "ranlib",
2275         "ar",
2276         "arflags",
2277         "multilib",
2278         "build_scheme",
2279         );
2280
2281     if ($type eq "TABLE") {
2282         print "\n";
2283         print "*** $target\n";
2284         foreach (@sequence) {
2285             if (ref($target{$_}) eq "ARRAY") {
2286                 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2287             } else {
2288                 printf "\$%-12s = %s\n", $_, $target{$_};
2289             }
2290         }
2291     } elsif ($type eq "HASH") {
2292         my $largest =
2293             length((sort { length($a) <=> length($b) } @sequence)[-1]);
2294         print "    '$target' => {\n";
2295         foreach (@sequence) {
2296             if ($target{$_}) {
2297                 if (ref($target{$_}) eq "ARRAY") {
2298                     print "      '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2299                 } else {
2300                     print "      '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2301                 }
2302             }
2303         }
2304         print "    },\n";
2305     }
2306 }
2307
2308 # Utility routines ###################################################
2309
2310 # On VMS, if the given file is a logical name, File::Spec::Functions
2311 # will consider it an absolute path.  There are cases when we want a
2312 # purely syntactic check without checking the environment.
2313 sub isabsolute {
2314     my $file = shift;
2315
2316     # On non-platforms, we just use file_name_is_absolute().
2317     return file_name_is_absolute($file) unless $^O eq "VMS";
2318
2319     # If the file spec includes a device or a directpry spec,
2320     # file_name_is_absolute() is perfectly safe.
2321     return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2322
2323     # Here, we know the given file spec isn't absolute
2324     return 0;
2325 }
2326
2327 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2328 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2329 # realpath() requires that at least all path components except the last is an
2330 # existing directory.  On VMS, the last component of the directory spec must
2331 # exist.
2332 sub absolutedir {
2333     my $dir = shift;
2334
2335     # realpath() is quite buggy on VMS.  It uses LIB$FID_TO_NAME, which
2336     # will return the volume name for the device, no matter what.  Also,
2337     # it will return an incorrect directory spec if the argument is a
2338     # directory that doesn't exist.
2339     if ($^O eq "VMS") {
2340         return rel2abs($dir);
2341     }
2342
2343     # We use realpath() on Unix, since no other will properly clean out
2344     # a directory spec.
2345     use Cwd qw/realpath/;
2346
2347     return realpath($dir);
2348 }
2349
2350 sub which
2351         {
2352         my($name)=@_;
2353         my $path;
2354         foreach $path (split /:/, $ENV{PATH})
2355                 {
2356                 my $fullpath = "$path/$name$target{exe_extension}";
2357                 if (-f $fullpath and -x $fullpath)
2358                         {
2359                         return $fullpath
2360                             unless ($name eq "perl" and
2361                                     system("$fullpath -e " . '\'exit($]<5.0);\''));
2362                         }
2363                 }
2364         }
2365
2366 sub quotify {
2367     my %processors = (
2368         perl    => sub { my $x = shift;
2369                          $x =~ s/([\\\$\@"])/\\$1/g;
2370                          return '"'.$x.'"'; },
2371         );
2372     my $for = shift;
2373     my $processor =
2374         defined($processors{$for}) ? $processors{$for} : sub { shift; };
2375
2376     map { $processor->($_); } @_;
2377 }
2378
2379 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2380 # $filename is a file name to read from
2381 # $line_concat_cond_re is a regexp detecting a line continuation ending
2382 # $line_concat is a CODEref that takes care of concatenating two lines
2383 sub collect_from_file {
2384     my $filename = shift;
2385     my $line_concat_cond_re = shift;
2386     my $line_concat = shift;
2387
2388     open my $fh, $filename || die "unable to read $filename: $!\n";
2389     return sub {
2390         my $saved_line = "";
2391         $_ = "";
2392         while (<$fh>) {
2393             s|\R$||;
2394             if (defined $line_concat) {
2395                 $_ = $line_concat->($saved_line, $_);
2396                 $saved_line = "";
2397             }
2398             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2399                 $saved_line = $_;
2400                 next;
2401             }
2402             return $_;
2403         }
2404         die "$filename ending with continuation line\n" if $_;
2405         close $fh;
2406         return undef;
2407     }
2408 }
2409
2410 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2411 # $array is an ARRAYref of lines
2412 # $line_concat_cond_re is a regexp detecting a line continuation ending
2413 # $line_concat is a CODEref that takes care of concatenating two lines
2414 sub collect_from_array {
2415     my $array = shift;
2416     my $line_concat_cond_re = shift;
2417     my $line_concat = shift;
2418     my @array = (@$array);
2419
2420     return sub {
2421         my $saved_line = "";
2422         $_ = "";
2423         while (defined($_ = shift @array)) {
2424             s|\R$||;
2425             if (defined $line_concat) {
2426                 $_ = $line_concat->($saved_line, $_);
2427                 $saved_line = "";
2428             }
2429             if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2430                 $saved_line = $_;
2431                 next;
2432             }
2433             return $_;
2434         }
2435         die "input text ending with continuation line\n" if $_;
2436         return undef;
2437     }
2438 }
2439
2440 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2441 # $lineiterator is a CODEref that delivers one line at a time.
2442 # All following arguments are regex/CODEref pairs, where the regexp detects a
2443 # line and the CODEref does something with the result of the regexp.
2444 sub collect_information {
2445     my $lineiterator = shift;
2446     my %collectors = @_;
2447
2448     while(defined($_ = $lineiterator->())) {
2449         s|\R$||;
2450         my $found = 0;
2451         foreach my $re (keys %collectors) {
2452             if ($re ne "OTHERWISE" && /$re/) {
2453                 $collectors{$re}->($lineiterator);
2454                 $found = 1;
2455             };
2456         }
2457         if ($collectors{"OTHERWISE"}) {
2458             $collectors{"OTHERWISE"}->($lineiterator, $_)
2459                 unless $found || !defined $collectors{"OTHERWISE"};
2460         }
2461     }
2462 }