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