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