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