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