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