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