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