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