]> git.ipfire.org Git - thirdparty/openssl.git/blame - Configure
Make sure getaddrinfo and getnameinfo works as intended on Windows
[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/;
9fe2bb77
RL
14use File::Path qw/make_path/;
15use Cwd qw/:DEFAULT realpath/;
1641cb60 16
22a4f969 17# see INSTALL for instructions.
462ba4f6 18
7fccf05d 19my $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 20
434c5dd3 21# Options:
e5f3045f 22#
f09e7ca9
RS
23# --config add the given configuration file, which will be read after
24# any "Configurations*" files that are found in the same
25# directory as this script.
d74dfafd
RL
26# --prefix prefix for the OpenSSL installation, which includes the
27# directories bin, lib, include, share/man, share/doc/openssl
28# This becomes the value of INSTALLTOP in Makefile
29# (Default: /usr/local)
30# --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys.
31# If it's a relative directory, it will be added on the directory
32# given with --prefix.
33# This becomes the value of OPENSSLDIR in Makefile and in C.
34# (Default: PREFIX/ssl)
e5f3045f
BM
35#
36# --install_prefix Additional prefix for package builders (empty by
37# default). This needn't be set in advance, you can
38# just as well use "make INSTALL_PREFIX=/whatever install".
39#
cbfb39d1
AP
40# --cross-compile-prefix Add specified prefix to binutils components.
41#
98186eb4
VD
42# --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for
43# interfaces deprecated as of the specified OpenSSL version.
44#
5270e702
RL
45# no-hw-xxx do not compile support for specific crypto hardware.
46# Generic OpenSSL-style methods relating to this support
47# are always compiled but return NULL if the hardware
48# support isn't compiled.
49# no-hw do not compile support for any crypto hardware.
5f8d5c96
BM
50# [no-]threads [don't] try to create a library that is suitable for
51# multithreaded applications (default is "threads" if we
52# know how to do it)
fcc6a1c4 53# [no-]shared [don't] try to create shared libraries when supported.
a723979d 54# no-asm do not use assembler
bc2aadad
GT
55# no-dso do not compile in any native shared-library methods. This
56# will ensure that all methods just return NULL.
0423f812 57# no-egd do not compile support for the entropy-gathering daemon APIs
e452de9d
RL
58# [no-]zlib [don't] compile support for zlib compression.
59# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
60# library and will be loaded in run-time by the OpenSSL library.
7e159e01 61# sctp include SCTP support
22a4f969 62# 386 generate 80386 code
d0590fe6 63# no-sse2 disables IA-32 SSE2 code, above option implies no-sse2
79df9d62 64# no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
fce0ba5f 65# -<xxx> +<xxx> compiler options are passed through
e41c8d6a
GT
66#
67# DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
68# provided to stack calls. Generates unique stack functions for
69# each possible stack type.
d02b48c6 70# BN_LLONG use the type 'long long' in crypto/bn/bn.h
d02b48c6 71# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
d0590fe6
AP
72# Following are set automatically by this script
73#
58964a49
RE
74# MD5_ASM use some extra md5 assember,
75# SHA1_ASM use some extra sha1 assember, must define L_ENDIAN for x86
76# RMD160_ASM use some extra ripemd160 assember,
d0590fe6
AP
77# SHA256_ASM sha256_block is implemented in assembler
78# SHA512_ASM sha512_block is implemented in assembler
79# AES_ASM ASE_[en|de]crypt is implemented in assembler
d02b48c6 80
363bd0b4 81# Minimum warning options... any contributions to OpenSSL should at least get
fce0ba5f 82# past these.
363bd0b4 83
c2e27310 84my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Wtype-limits -Werror -DREF_CHECK -DDEBUG_UNUSED";
363bd0b4 85
190c8c60
BL
86# These are used in addition to $gcc_devteam_warn when the compiler is clang.
87# TODO(openssl-team): fix problems and investigate if (at least) the
480405e4 88# following warnings can also be enabled:
190c8c60 89# -Wswitch-enum, -Wunused-macros, -Wmissing-field-initializers,
df2ee0e2 90# -Wcast-align,
190c8c60
BL
91# -Wunreachable-code -Wunused-parameter -Wlanguage-extension-token
92# -Wextended-offsetof
df2ee0e2 93my $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 94
2e31ef03
RS
95# Warn that "make depend" should be run?
96my $warn_make_depend = 0;
97
a1d3f3d1
RL
98# These are used in addition to $gcc_devteam_warn unless this is a mingw build.
99# This adds backtrace information to the memory leak info.
100my $memleak_devteam_backtrace = "-rdynamic -DCRYPTO_MDEBUG_BACKTRACE";
101
0c28f277
DSH
102my $strict_warnings = 0;
103
b7efa56a 104# As for $BSDthreads. Idea is to maintain "collective" set of flags,
fce0ba5f 105# which would cover all BSD flavors. -pthread applies to them all,
b7efa56a
AP
106# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
107# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
108# which has to be accompanied by explicit -D_THREAD_SAFE and
109# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
110# seems to be sufficient?
111my $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
d02b48c6 112
98186eb4
VD
113#
114# API compability name to version number mapping.
115#
116my $maxapi = "1.1.0"; # API for "no-deprecated" builds
117my $apitable = {
118 "1.1.0" => "0x10100000L",
119 "1.0.0" => "0x10000000L",
120 "0.9.8" => "0x00908000L",
121};
122
9e0724a1
RL
123my $base_target = "BASE"; # The template that all other inherit from
124our %table = ();
291e94df 125our %config = ();
3e83e686 126
bd5192b1 127# Forward declarations ###############################################
7ead0c89 128
bd5192b1
RL
129# read_config(filename)
130#
131# Reads a configuration file and populates %table with the contents
132# (which the configuration file places in %targets).
133sub read_config;
7d46b942 134
bd5192b1
RL
135# resolve_config(target)
136#
137# Resolves all the late evalutations, inheritances and so on for the
138# chosen target and any target it inherits from.
139sub resolve_config;
7d46b942 140
15c7adb0 141
107b5792
RL
142# Information collection #############################################
143
9fe2bb77
RL
144# Unified build supports separate build dir
145my $srcdir = catdir(realpath(dirname($0))); # catdir ensures local syntax
146my $blddir = catdir(realpath(".")); # catdir ensures local syntax
147my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
148
149$config{sourcedir} = abs2rel($srcdir);
150$config{builddir} = abs2rel($blddir);
151
107b5792
RL
152# Collect version numbers
153$config{version} = "unknown";
154$config{version_num} = "unknown";
155$config{shlib_version_number} = "unknown";
156$config{shlib_version_history} = "unknown";
157
158collect_information(
9fe2bb77 159 collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
107b5792
RL
160 qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
161 qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 },
162 qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 },
163 qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 }
164 );
165if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
166
167($config{major}, $config{minor})
168 = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
169($config{shlib_major}, $config{shlib_minor})
170 = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
171die "erroneous version information in opensslv.h: ",
172 "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
173 if ($config{major} eq "" || $config{minor} eq ""
174 || $config{shlib_major} eq "" || $config{shlib_minor} eq "");
175
176# Collect target configurations
177
85152ca4 178my $pattern = catfile(dirname($0), "Configurations", "*.conf");
97a0cc52 179foreach (sort glob($pattern) ) {
f09e7ca9
RS
180 &read_config($_);
181}
d02b48c6 182
291e94df 183
107b5792
RL
184print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n";
185
291e94df
RL
186$config{perl};
187$config{prefix}="";
188$config{openssldir}="";
7d130f68 189$config{processor}="";
107b5792
RL
190$config{libdir}="";
191$config{install_prefix}= "$ENV{'INSTALL_PREFIX'}";
642a6138 192$config{cross_compile_prefix}="";
107b5792 193$config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
1ab2f7f1 194my $nofipscanistercheck=0;
107b5792 195$config{baseaddr}="0xFB00000";
5f8d5c96
BM
196my $no_threads=0;
197my $threads=0;
83365051 198$config{no_shared}=0; # but "no-shared" is default
c9a112f5 199my $zlib=1; # but "no-zlib" is default
47bbaa5b 200my $no_rfc3779=0;
1641cb60 201my $no_asm=0;
bc2aadad 202my $no_dso=0;
0396479d 203my $default_ranlib;
107b5792
RL
204$config{fips}=0;
205
206# Top level directories to build
207$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools" ];
208# crypto/ subdirectories to build
209$config{sdirs} = [
210 "objects",
211 "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305",
212 "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes",
213 "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
214 "buffer", "bio", "stack", "lhash", "rand", "err",
215 "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
216 "cms", "ts", "jpake", "srp", "store", "cmac", "ct", "async", "kdf"
217 ];
99aab161 218
6b01bed2
VD
219# Known TLS and DTLS protocols
220my @tls = qw(ssl3 tls1 tls1_1 tls1_2);
221my @dtls = qw(dtls1 dtls1_2);
222
8b527be2
RL
223# Explicitelly known options that are possible to disable. They can
224# be regexps, and will be used like this: /^no-${option}$/
225# For developers: keep it sorted alphabetically
226
227my @disablables = (
228 "aes",
229 "asm",
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
BM
743
744 if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/)
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
1740c162 822# For cflags, lflags and ex_libs, add the debug_ or release_ attributes
aaf878cc 823# Do it in such a way that no spurious space is appended (hence the grep).
107b5792
RL
824$config{cflags} = join(" ",
825 grep { $_ ne "" } ($target{cflags},
826 $target{$build_prefix."cflags"}));
827$config{lflags} = join(" ",
828 grep { $_ ne "" } ($target{lflags},
829 $target{$build_prefix."lflags"}));
1740c162
RL
830$config{ex_libs} = join(" ",
831 grep { $_ ne "" } ($target{ex_libs},
832 $target{$build_prefix."ex_libs"}));
bd5192b1 833
291e94df
RL
834$target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} || $default_ranlib;
835$target{ar} = $ENV{'AR'} || "ar";
107b5792
RL
836$target{arflags} = "" if !defined($target{arflags});
837$target{nm} = "nm";
291e94df
RL
838# Make sure build_scheme is consistent.
839$target{build_scheme} = [ $target{build_scheme} ]
840 if ref($target{build_scheme}) ne "ARRAY";
841
842# if $config{prefix}/lib$target{multilib} is not an existing directory, then
b730b03f 843# assume that it's not searched by linker automatically, in
291e94df 844# which case adding $target{multilib} suffix causes more grief than
b730b03f 845# we're ready to tolerate, so don't...
291e94df 846$target{multilib}="" if !-d "$config{prefix}/lib$target{multilib}";
b730b03f 847
107b5792
RL
848$config{libdir}="lib$target{multilib}" if $config{libdir} eq "";
849$config{enginesdir}=$config{prefix} . "/" . $config{libdir} . "/engines";
6a9d28f9 850
107b5792 851$config{cflags} .= "$exp_cflags";
7a762197 852
107b5792 853if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` !~ m/-mno-cygwin/m)
cbecd29a 854 {
107b5792
RL
855 $config{cflags} =~ s/-mno-cygwin\s*//;
856 $target{shared_ldflag} =~ s/-mno-cygwin\s*//;
cbecd29a
AP
857 }
858
107b5792 859if ($target =~ /linux.*-mips/ && !$no_asm && $flags !~ /-m(ips|arch=)/) {
63d8834c 860 # minimally required architecture flags for assembly modules
107b5792
RL
861 $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
862 $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
63d8834c
AP
863}
864
2964ba8c 865my $no_shared_warn=0;
14bcdb08 866my $no_user_cflags=0;
2964ba8c 867
107b5792 868if ($flags ne "") { $config{cflags}="$flags$config{cflags}"; }
14bcdb08 869else { $no_user_cflags=1; }
5f8d5c96 870
bc2aadad
GT
871# The DSO code currently always implements all functions so that no
872# applications will have to worry about that from a compilation point
873# of view. However, the "method"s may return zero unless that platform
874# has support compiled in for them. Currently each method is enabled
875# by a define "DSO_<name>" ... we translate the "dso_scheme" config
876# string entry into using the following logic;
eca57e92 877my $dso_cflags;
291e94df 878if (!$no_dso && $target{dso_scheme} ne "")
bc2aadad 879 {
291e94df
RL
880 $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
881 if ($target{dso_scheme} eq "DLFCN")
bc2aadad 882 {
eca57e92 883 $dso_cflags = "-DDSO_DLFCN -DHAVE_DLFCN_H";
bc2aadad 884 }
291e94df 885 elsif ($target{dso_scheme} eq "DLFCN_NO_H")
bc2aadad 886 {
eca57e92 887 $dso_cflags = "-DDSO_DLFCN";
bc2aadad
GT
888 }
889 else
890 {
291e94df 891 $dso_cflags = "-DDSO_$target{dso_scheme}";
bc2aadad 892 }
107b5792 893 $config{cflags} = "$dso_cflags $config{cflags}";
bc2aadad 894 }
9ec0126e 895
421e30ec 896my $thread_cflags = "";
7d130f68 897my @thread_defines;
291e94df 898if ($target{thread_cflag} ne "(unknown)" && !$no_threads)
5f8d5c96
BM
899 {
900 # If we know how to do it, support threads by default.
901 $threads = 1;
902 }
291e94df 903if ($target{thread_cflag} eq "(unknown)" && $threads)
5f8d5c96 904 {
14bcdb08
AP
905 # If the user asked for "threads", [s]he is also expected to
906 # provide any system-dependent compiler options that are
907 # necessary.
908 if ($no_user_cflags)
909 {
910 print "You asked for multi-threading support, but didn't\n";
911 print "provide any system-specific compiler options\n";
912 exit(1);
913 }
421e30ec 914 $thread_cflags="-DOPENSSL_THREADS" ;
7d130f68 915 push @thread_defines, "OPENSSL_THREADS";
5f8d5c96
BM
916 }
917else
918 {
421e30ec 919 $thread_cflags="-DOPENSSL_THREADS $target{thread_cflag}";
7d130f68 920 push @thread_defines, "OPENSSL_THREADS";
fce0ba5f 921 }
5f8d5c96 922
1740c162 923$config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
d02b48c6 924
dfeab068
RE
925if ($no_asm)
926 {
107b5792 927 $config{cflags}=~s/-D[BL]_ENDIAN// if ($config{fips});
dfeab068 928 }
6f7ac8e1 929
5f8d5c96
BM
930if ($threads)
931 {
421e30ec 932 $config{cflags} = "$thread_cflags $config{cflags}" if $thread_cflags;
7d130f68 933 push @{$config{openssl_thread_defines}}, @thread_defines;
e452de9d
RL
934 }
935
936if ($zlib)
937 {
107b5792 938 $config{cflags} = "-DZLIB $config{cflags}";
c9a112f5
BM
939 if (defined($disabled{"zlib-dynamic"}))
940 {
20a5819f 941 if (defined($withargs{zlib_lib}))
cc7399e7 942 {
20a5819f 943 $config{ex_libs} .= " -L" . $withargs{zlib_lib} . " -lz";
cc7399e7
DSH
944 }
945 else
946 {
1740c162 947 $config{ex_libs} .= " -lz";
cc7399e7 948 }
c9a112f5
BM
949 }
950 else
951 {
107b5792 952 $config{cflags} = "-DZLIB_SHARED $config{cflags}";
c9a112f5 953 }
5f8d5c96
BM
954 }
955
98186eb4
VD
956# With "deprecated" disable all deprecated features.
957if (defined($disabled{"deprecated"})) {
107b5792 958 $config{api} = $maxapi;
98186eb4 959}
07c4c14c 960
291e94df 961if ($target{shared_target} eq "")
6f7ac8e1 962 {
107b5792 963 $no_shared_warn = 1 if !$config{no_shared} && !$config{fips};
83365051 964 $config{no_shared} = 1;
6f7ac8e1 965 }
83365051 966if (!$config{no_shared})
b436a982 967 {
291e94df 968 if ($target{shared_cflag} ne "")
a22fb399 969 {
107b5792 970 $config{cflags} = "$target{shared_cflag} -DOPENSSL_PIC $config{cflags}";
a22fb399 971 }
d2dcf4f4 972 }
b436a982 973
291e94df 974if ($target{build_scheme}->[0] ne "mk1mf")
ecd45314 975 {
4c1a6e00 976 # add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
83365051 977 if ($config{no_shared})
fbf002bb 978 {
7d130f68 979 push @{$config{openssl_other_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
3fa04f0d 980 $config{options}.=" static-engine";
fbf002bb
DSH
981 }
982 else
983 {
7d130f68 984 push @{$config{openssl_other_defines}}, "OPENSSL_NO_STATIC_ENGINE";
3fa04f0d 985 $config{options}.=" no-static-engine";
fbf002bb 986 }
6cb68620 987 }
ecd45314 988
c313e32a
AP
989#
990# Platform fix-ups
991#
c313e32a
AP
992# Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
993# linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
994# .so objects. Apparently application RPATH is not global and does
995# not apply to .so linked with other .so. Problem manifests itself
996# when libssl.so fails to load libcrypto.so. One can argue that we
997# should engrave this into Makefile.shared rules or into BSD-* config
998# lines above. Meanwhile let's try to be cautious and pass -rpath to
999# linker only when --prefix is not /usr.
107b5792 1000if ($target =~ /^BSD-/)
c313e32a 1001 {
291e94df 1002 $target{shared_ldflag}.=" -Wl,-rpath,\$\$(LIBRPATH)" if ($config{prefix} !~ m|^/usr[/]*$|);
c313e32a
AP
1003 }
1004
291e94df 1005if ($target{sys_id} ne "")
cf1b7d96 1006 {
107b5792 1007 #$config{cflags}="-DOPENSSL_SYS_$target{sys_id} $config{cflags}";
642a6138 1008 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
cf1b7d96
RL
1009 }
1010
291e94df 1011if ($target{ranlib} eq "")
0396479d 1012 {
291e94df 1013 $target{ranlib} = $default_ranlib;
0396479d
BM
1014 }
1015
9e0724a1 1016if (!$no_asm) {
9fe2bb77
RL
1017 $target{cpuid_asm_src}=$table{BASE}->{cpuid_asm_src} if ($config{processor} eq "386");
1018 $target{cpuid_asm_src}.=" uplink.c uplink-x86.s" if ($config{cflags} =~ /-DOPENSSL_USE_APPLINK/);
1750ebcb 1019
9fe2bb77 1020 $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
f8c469de 1021
9e0724a1 1022 # bn-586 is the only one implementing bn_*_part_words
9fe2bb77
RL
1023 $config{cflags}.=" -DOPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1024 $config{cflags}.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
dfeab068 1025
9fe2bb77
RL
1026 $config{cflags}.=" -DOPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1027 $config{cflags}.=" -DOPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1028 $config{cflags}.=" -DOPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
5ac7bde7 1029
107b5792 1030 if ($config{fips}) {
7d130f68 1031 push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
9e0724a1 1032 }
1ab2f7f1 1033
9fe2bb77
RL
1034 if ($target{sha1_asm_src}) {
1035 $config{cflags}.=" -DSHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1036 $config{cflags}.=" -DSHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1037 $config{cflags}.=" -DSHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
9e0724a1 1038 }
9fe2bb77 1039 if ($target{md5_asm_src}) {
107b5792 1040 $config{cflags}.=" -DMD5_ASM";
9e0724a1 1041 }
9fe2bb77
RL
1042 $target{cast_asm_src}=$table{BASE}->{cast_asm_src} if (!$config{no_shared}); # CAST assembler is not PIC
1043 if ($target{rmd160_asm_src}) {
107b5792 1044 $config{cflags}.=" -DRMD160_ASM";
9e0724a1 1045 }
9fe2bb77
RL
1046 if ($target{aes_asm_src}) {
1047 $config{cflags}.=" -DAES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1048 # aes-ctr.fake is not a real file, only indication that assembler
874a3757 1049 # module implements AES_ctr32_encrypt...
9fe2bb77
RL
1050 $config{cflags}.=" -DAES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1051 # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1052 $config{cflags}.=" -DAES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1053 $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1054 $config{cflags}.=" -DVPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1055 $config{cflags}.=" -DBSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
9e0724a1 1056 }
9fe2bb77 1057 if ($target{wp_asm_src} =~ /mmx/) {
46d4d865 1058 if ($config{processor} eq "386") {
9fe2bb77 1059 $target{wp_asm_src}=$table{BASE}->{wp_asm_src};
46d4d865
AP
1060 } elsif (!$disabled{"whirlpool"}) {
1061 $config{cflags}.=" -DWHIRLPOOL_ASM";
1062 }
9e0724a1 1063 }
9fe2bb77 1064 if ($target{modes_asm_src} =~ /ghash-/) {
107b5792 1065 $config{cflags}.=" -DGHASH_ASM";
9e0724a1 1066 }
9fe2bb77 1067 if ($target{ec_asm_src} =~ /ecp_nistz256/) {
107b5792 1068 $config{cflags}.=" -DECP_NISTZ256_ASM";
9e0724a1 1069 }
9fe2bb77 1070 if ($target{poly1305_asm_src} ne "") {
107b5792 1071 $config{cflags}.=" -DPOLY1305_ASM";
9e0724a1
RL
1072 }
1073}
d02b48c6 1074
f1f07a23
RS
1075# Is the compiler gcc or clang? $ecc is used below to see if error-checking
1076# can be turned on.
8ed40b83 1077my $ecc = $target{cc};
f1f07a23
RS
1078my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1079$config{makedepprog} = 'makedepend';
1080open(PIPE, "$ccpcc --version 2>&1 | head -2 |");
1081while ( <PIPE> ) {
1082 $config{makedepprog} = $ccpcc if /clang|gcc/;
1083 $ecc = "clang" if /clang/;
1084 $ecc = "gcc" if /gcc/;
1085}
1086close(PIPE);
8ed40b83 1087
107b5792
RL
1088$config{depflags} =~ s/^\s*//;
1089
7d130f68
RL
1090
1091# Deal with bn_ops ###################################################
1092
7d130f68 1093$config{bn_ll} =0;
7d130f68
RL
1094$config{export_var_as_fn} =0;
1095my $def_int="unsigned int";
1096$config{rc4_int} =$def_int;
b4f35e5e 1097($config{b64l},$config{b64},$config{b32})=(0,0,1);
7d130f68 1098
94af0cd7 1099my $count = 0;
7d130f68 1100foreach (sort split(/\s+/,$target{bn_ops})) {
94af0cd7
RS
1101 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1102 $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN';
1103 $config{bn_ll}=1 if $_ eq 'BN_LLONG';
1104 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
1105 ($config{b64l},$config{b64},$config{b32})
1106 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
1107 ($config{b64l},$config{b64},$config{b32})
1108 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
1109 ($config{b64l},$config{b64},$config{b32})
1110 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
7d130f68 1111}
94af0cd7
RS
1112die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1113 if $count > 1;
7d130f68
RL
1114
1115
1116# Hack cflags for better warnings (dev option) #######################
1117
1ed0c662
RL
1118# "Stringify" the C flags string. This permits it to be made part of a string
1119# and works as well on command lines.
107b5792 1120$config{cflags} =~ s/([\\\"])/\\\1/g;
b436a982 1121
107b5792
RL
1122if (defined($config{api})) {
1123 $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1124 my $apiflag = sprintf("-DOPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
98186eb4 1125 $default_depflags .= " $apiflag";
107b5792 1126 $config{cflags} .= " $apiflag";
98186eb4
VD
1127}
1128
0c28f277
DSH
1129if ($strict_warnings)
1130 {
1131 my $wopt;
f1f07a23
RS
1132 die "ERROR --strict-warnings requires gcc or clang"
1133 unless $ecc eq 'gcc' || $ecc eq 'clang';
0c28f277
DSH
1134 foreach $wopt (split /\s+/, $gcc_devteam_warn)
1135 {
107b5792 1136 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(^|\s)$wopt(\s|$)/)
0c28f277 1137 }
190c8c60
BL
1138 if ($ecc eq "clang")
1139 {
1140 foreach $wopt (split /\s+/, $clang_devteam_warn)
1141 {
107b5792 1142 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(^|\s)$wopt(\s|$)/)
190c8c60
BL
1143 }
1144 }
a1d3f3d1
RL
1145 if ($target !~ /^mingw/)
1146 {
1147 foreach $wopt (split /\s+/, $memleak_devteam_backtrace)
1148 {
107b5792 1149 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(^|\s)$wopt(\s|$)/)
a1d3f3d1 1150 }
291e94df
RL
1151 if ($target =~ /^BSD-/)
1152 {
1740c162 1153 $config{ex_libs} .= " -lexecinfo";
291e94df
RL
1154 }
1155 }
0c28f277
DSH
1156 }
1157
9fe2bb77
RL
1158# If we use the unified build, collect information from build.info files
1159my %unified_info = ();
1160
1161if ($target{build_scheme}->[0] eq "unified") {
1162 use lib catdir(dirname(__FILE__),"util");
1163 use with_fallback qw(Text::Template);
1164
1165 # Helpers to produce clean paths with no /../ in the middle and so on.
1166 sub int_absolutedir {
1167 my $dir = shift;
1168
1169 # Required, because realpath only works properly with existing dirs
1170 make_path($dir);
1171
1172 my $res = realpath($dir);
1173 return $res;
1174 }
1175
1176 sub cleandir {
1177 my $dir = shift;
1178 my $base = shift || ".";
1179
1180 my $res = abs2rel(int_absolutedir($dir), rel2abs($base));
1181 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1182 return $res;
1183 }
1184
1185 sub cleanfile {
1186 my $file = shift;
1187 my $base = shift || ".";
1188 my $d = dirname($file);
1189 my $f = basename($file);
1190
1191 my $res = abs2rel(catfile(int_absolutedir($d), $f), rel2abs($base));
1192 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1193 return $res;
1194 }
1195
1196 my @build_infos = ( [ ".", "build.info" ] );
1197 foreach (@{$config{dirs}}) {
1198 push @build_infos, [ $_, "build.info" ]
1199 if (-f catfile($srcdir, $_, "build.info"));
1200 }
1201 foreach (@{$config{sdirs}}) {
1202 push @build_infos, [ catdir("crypto", $_), "build.info" ]
1203 if (-f catfile($srcdir, "crypto", $_, "build.info"));
1204 }
1205 foreach (@{$config{engdirs}}) {
1206 push @build_infos, [ catdir("engines", $_), "build.info" ]
1207 if (-f catfile($srcdir, "engines", $_, "build.info"));
1208 }
1209
1210 foreach (@build_infos) {
1211 my $sourced = catdir($srcdir, $_->[0]);
1212 my $buildd = catdir($blddir, $_->[0]);
1213
1214 make_path($buildd);
1215
1216 my $f = $_->[1];
1217 # The basic things we're trying to build
1218 my @programs = ();
1219 my @libraries = ();
1220 my @engines = ();
1221 my @scripts = ();
1222 my @extra = ();
1223 my @intermediates = ();
1224 my @rawlines = ();
1225
1226 my %ordinals = ();
1227 my %sources = ();
1228 my %includes = ();
1229 my %depends = ();
1230 my %renames = ();
1231 my %sharednames = ();
1232
1233 my $template = Text::Template->new(TYPE => 'FILE',
1234 SOURCE => catfile($sourced, $f));
1235 die "Something went wrong with $sourced/$f: $!\n" unless $template;
1236 my @text =
1237 split /^/m,
1238 $template->fill_in(HASH => { config => \%config,
1239 target => \%target,
1240 builddir => abs2rel($buildd, $blddir),
1241 sourcedir => abs2rel($sourced, $blddir),
1242 buildtop => abs2rel($blddir, $blddir),
1243 sourcetop => abs2rel($srcdir, $blddir) },
1244 DELIMITERS => [ "{-", "-}" ]);
1245
1246 # The top item of this stack has the following values
1247 # -2 positive already run and we found ELSE (following ELSIF should fail)
1248 # -1 positive already run (skip until ENDIF)
1249 # 0 negatives so far (if we're at a condition, check it)
1250 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1251 # 2 positive ELSE (following ELSIF should fail)
1252 my @skip = ();
1253 collect_information(
1254 collect_from_array([ @text ],
1255 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1256 $l1 =~ s/\\$//; $l1.$l2 }),
1257 # Info we're looking for
1258 qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1259 => sub { push @skip, !! $1; },
1260 qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1261 => sub { die "ELSIF out of scope" if ! @skip;
1262 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1263 $skip[$#skip] = -1 if $skip[$#skip] != 0;
1264 $skip[$#skip] = !! $1
1265 if $skip[$#skip] == 0; },
1266 qr/^\s*ELSE\s*$/
1267 => sub { die "ELSE out of scope" if ! @skip;
1268 $skip[$#skip] = -2 if $skip[$#skip] != 0;
1269 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1270 qr/^\s*ENDIF\s*$/
1271 => sub { die "ENDIF out of scope" if ! @skip;
1272 pop @skip; },
1273 qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
1274 => sub { push @programs, split(/\s+/, $1)
1275 if !@skip || $skip[$#skip] > 0 },
1276 qr/^\s*LIBS\s*=\s*(.*)\s*$/
1277 => sub { push @libraries, split(/\s+/, $1)
1278 if !@skip || $skip[$#skip] > 0 },
1279 qr/^\s*ENGINES\s*=\s*(.*)\s*$/
1280 => sub { push @engines, split(/\s+/, $1)
1281 if !@skip || $skip[$#skip] > 0 },
1282 qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
1283 => sub { push @scripts, split(/\s+/, $1)
1284 if !@skip || $skip[$#skip] > 0 },
1285 qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1286 => sub { push @extra, split(/\s+/, $1)
1287 if !@skip || $skip[$#skip] > 0 },
1288
1289 qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1290 => sub { push @{$ordinals{$1}}, split(/\s+/, $2)
1291 if !@skip || $skip[$#skip] > 0 },
1292 qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1293 => sub { push @{$sources{$1}}, split(/\s+/, $2)
1294 if !@skip || $skip[$#skip] > 0 },
1295 qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1296 => sub { push @{$includes{$1}}, split(/\s+/, $2)
1297 if !@skip || $skip[$#skip] > 0 },
1298 qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1299 => sub { push @{$depends{$1}}, split(/\s+/, $2)
1300 if !@skip || $skip[$#skip] > 0 },
1301 qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1302 => sub { push @{$renames{$1}}, split(/\s+/, $2)
1303 if !@skip || $skip[$#skip] > 0 },
1304 qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1305 => sub { push @{$sharednames{$1}}, split(/\s+/, $2)
1306 if !@skip || $skip[$#skip] > 0 },
1307 qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1308 => sub {
1309 my $lineiterator = shift;
1310 my $target_kind = $1;
1311 while (defined $lineiterator->()) {
1312 chomp;
1313 if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1314 die "ENDRAW doesn't match BEGINRAW"
1315 if $1 ne $target_kind;
1316 last;
1317 }
1318 next if @skip && $skip[$#skip] <= 0;
1319 push @rawlines, $_
1320 if ($target_kind eq $target{build_file}
1321 || $target_kind eq $target{build_file}."(".$target{build_scheme}->[1].")");
1322 }
1323 },
1324 qr/^(?:#.*|\s*)$/ => sub { },
1325 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }
1326 );
1327 die "runaway IF?" if (@skip);
1328
1329 foreach (keys %renames) {
1330 die "$_ renamed to more than one thing: "
1331 ,join(" ", @{$renames{$_}}),"\n"
1332 if scalar @{$renames{$_}} > 1;
1333 my $dest = cleanfile(catfile($buildd, $_), $blddir);
1334 my $to = cleanfile(catfile($buildd, $renames{$_}->[0]), $blddir);
1335 die "$dest renamed to more than one thing: "
1336 ,$unified_info{rename}->{$dest}, $to
1337 unless !defined($unified_info{rename}->{$dest})
1338 or $unified_info{rename}->{$dest} eq $to;
1339 $unified_info{rename}->{$dest} = $to;
1340 }
1341
1342 foreach (@programs) {
1343 my $program = cleanfile(catfile($buildd, $_), $blddir);
1344 if ($unified_info{rename}->{$program}) {
1345 $program = $unified_info{rename}->{$program};
1346 }
1347 $unified_info{programs}->{$program} = 1;
1348 }
1349
1350 foreach (@libraries) {
1351 my $library = cleanfile(catfile($buildd, $_), $blddir);
1352 if ($unified_info{rename}->{$library}) {
1353 $library = $unified_info{rename}->{$library};
1354 }
1355 $unified_info{libraries}->{$library} = 1;
1356 }
1357
1358 die <<"EOF" if $config{no_shared} && scalar @engines;
1359ENGINES can only be used if configured with 'shared'.
1360This is usually a fault in a build.info file.
1361EOF
1362 foreach (@engines) {
1363 my $library = cleanfile(catfile($buildd, $_), $blddir);
1364 if ($unified_info{rename}->{$library}) {
1365 $library = $unified_info{rename}->{$library};
1366 }
1367 $unified_info{engines}->{$library} = 1;
1368 }
1369
1370 foreach (@scripts) {
1371 my $script = cleanfile(catfile($buildd, $_), $blddir);
1372 if ($unified_info{rename}->{$script}) {
1373 $script = $unified_info{rename}->{$script};
1374 }
1375 $unified_info{scripts}->{$script} = 1;
1376 }
1377
1378 foreach (@extra) {
1379 my $extra = cleanfile(catfile($buildd, $_), $blddir);
1380 $unified_info{extra}->{$extra} = 1;
1381 }
1382
1383 push @{$unified_info{rawlines}}, @rawlines;
1384
1385 if (!$config{no_shared}) {
1386 # Check sharednames.
1387 foreach (keys %sharednames) {
1388 my $dest = cleanfile(catfile($buildd, $_), $blddir);
1389 if ($unified_info{rename}->{$dest}) {
1390 $dest = $unified_info{rename}->{$dest};
1391 }
1392 die "shared_name for $dest with multiple values: "
1393 ,join(" ", @{$sharednames{$_}}),"\n"
1394 if scalar @{$sharednames{$_}} > 1;
1395 my $to = cleanfile(catfile($buildd, $sharednames{$_}->[0]),
1396 $blddir);
1397 die "shared_name found for a library $dest that isn't defined\n"
1398 unless $unified_info{libraries}->{$dest};
1399 die "shared_name for $dest with multiple values: "
1400 ,$unified_info{sharednames}->{$dest}, ", ", $to
1401 unless !defined($unified_info{sharednames}->{$dest})
1402 or $unified_info{sharednames}->{$dest} eq $to;
1403 $unified_info{sharednames}->{$dest} = $to;
1404 }
1405
1406 # Additionally, we set up sharednames for libraries that don't
1407 # have any, as themselves.
1408 foreach (keys %{$unified_info{libraries}}) {
1409 if (!defined $unified_info{sharednames}->{$_}) {
1410 $unified_info{sharednames}->{$_} = $_
1411 }
1412 }
1413 }
1414
1415 foreach (keys %ordinals) {
1416 my $dest = $_;
1417 my $ddest = cleanfile(catfile($buildd, $_), $blddir);
1418 if ($unified_info{rename}->{$ddest}) {
1419 $ddest = $unified_info{rename}->{$ddest};
1420 }
1421 foreach (@{$ordinals{$dest}}) {
1422 my %known_ordinals =
1423 (
1424 crypto =>
1425 cleanfile(catfile($sourced, "util", "libeay.num"), $blddir),
1426 ssl =>
1427 cleanfile(catfile($sourced, "util", "ssleay.num"), $blddir)
1428 );
1429 my $o = $known_ordinals{$_};
1430 die "Ordinals for $ddest defined more than once\n"
1431 if $unified_info{ordinals}->{$ddest};
1432 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1433 }
1434 }
1435
1436 foreach (keys %sources) {
1437 my $dest = $_;
1438 my $ddest = cleanfile(catfile($buildd, $_), $blddir);
1439 if ($unified_info{rename}->{$ddest}) {
1440 $ddest = $unified_info{rename}->{$ddest};
1441 }
1442 foreach (@{$sources{$dest}}) {
1443 my $s = cleanfile(catfile($sourced, $_), $blddir);
1444
1445 # If it isn't in the source tree, we assume it's generated
1446 # in the build tree
1447 if (! -f $s) {
1448 $s = cleanfile(catfile($buildd, $_), $blddir);
1449 }
1450 # We recognise C and asm files
1451 if ($s =~ /\.[csS]\b$/) {
1452 (my $o = $_) =~ s/\.[csS]\b$/.o/;
1453 $o = cleanfile(catfile($buildd, $o), $blddir);
1454 $unified_info{sources}->{$ddest}->{$o} = 1;
1455 $unified_info{sources}->{$o}->{$s} = 1;
1456 } else {
1457 $unified_info{sources}->{$ddest}->{$s} = 1;
1458 }
1459 }
1460 }
1461
1462 foreach (keys %depends) {
1463 my $dest = $_;
1464 my $ddest = cleanfile(catfile($buildd, $_), $blddir);
1465 if ($unified_info{rename}->{$ddest}) {
1466 $ddest = $unified_info{rename}->{$ddest};
1467 }
1468 foreach (@{$depends{$dest}}) {
1469 my $d = cleanfile(catfile($sourced, $_), $blddir);
1470
1471 # If it isn't found in the source, let's assume it's generated
1472 # and that the Makefile template has the lines
1473 if (! -f $d) {
1474 $d = cleanfile(catfile($buildd, $_), $blddir);
1475 }
1476 # Take note if the file to depend on is being renamed
1477 if ($unified_info{rename}->{$d}) {
1478 $d = $unified_info{rename}->{$d};
1479 }
1480 $unified_info{depends}->{$ddest}->{$d} = 1;
1481 # If we depend on a header file, let's make sure it
1482 # can get included
1483 if ($d =~ /\.h$/) {
1484 my $i = dirname($d);
1485 push @{$unified_info{includes}->{$ddest}}, $i
1486 unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1487 }
1488 }
1489 }
1490
1491 foreach (keys %includes) {
1492 my $dest = $_;
1493 my $ddest = cleanfile(catfile($buildd, $_), $blddir);
1494 if ($unified_info{rename}->{$ddest}) {
1495 $ddest = $unified_info{rename}->{$ddest};
1496 }
1497 foreach (@{$includes{$dest}}) {
1498 my $i = cleandir(catdir($sourced, $_), $blddir);
1499 push @{$unified_info{includes}->{$ddest}}, $i
1500 unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1501 }
1502 }
1503 }
1504
1505 ### Make unified_info a bit more efficient
1506 # One level structures
1507 foreach (("programs", "libraries", "engines", "scripts", "extra")) {
1508 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1509 }
1510 # Two level structures
1511 foreach my $l1 (("sources", "ldadd", "depends")) {
1512 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1513 $unified_info{$l1}->{$l2} =
1514 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1515 }
1516 }
1517}
1518
1519# For the schemes that need it, we provide the old *_obj configs
1520# from the *_asm_obj ones
1521foreach (grep /_asm_src$/, keys %target) {
1522 my $src = $_;
1523 (my $obj = $_) =~ s/_asm_src$/_obj/;
1524 ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1525}
1526
291e94df
RL
1527# Write down our configuration where it fits #########################
1528
1529open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1530print OUT <<"EOF";
1531package configdata;
1532
1533use strict;
1534use warnings;
1535
1536use Exporter;
1537#use vars qw(\@ISA \@EXPORT);
1538our \@ISA = qw(Exporter);
9fe2bb77 1539our \@EXPORT = qw(\%config \%target %withargs %unified_info);
291e94df
RL
1540
1541EOF
1542print OUT "our %config = (\n";
1543foreach (sort keys %config) {
1544 if (ref($config{$_}) eq "ARRAY") {
1545 print OUT " ", $_, " => [ ", join(", ",
1546 map { quotify("perl", $_) }
1547 @{$config{$_}}), " ],\n";
1548 } else {
1549 print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1550 }
1551}
1552print OUT <<"EOF";
1553);
1554
1555EOF
1556print OUT "our %target = (\n";
1557foreach (sort keys %target) {
1558 if (ref($target{$_}) eq "ARRAY") {
1559 print OUT " ", $_, " => [ ", join(", ",
1560 map { quotify("perl", $_) }
1561 @{$target{$_}}), " ],\n";
1562 } else {
1563 print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1564 }
1565}
1566print OUT <<"EOF";
1567);
1568
96d2d7bc
RL
1569EOF
1570print OUT "our \%available_protocols = (\n";
1571print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1572print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1573print OUT <<"EOF";
1574);
1575
1576EOF
1577print OUT "our \%disabled = (\n";
1578foreach (sort keys %disabled) {
1579 print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1580}
1581print OUT <<"EOF";
1582);
1583
291e94df 1584EOF
107b5792
RL
1585print OUT "our %withargs = (\n";
1586foreach (sort keys %withargs) {
1587 if (ref($withargs{$_}) eq "ARRAY") {
1588 print OUT " ", $_, " => [ ", join(", ",
1589 map { quotify("perl", $_) }
1590 @{$withargs{$_}}), " ],\n";
1591 } else {
1592 print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1593 }
1594}
1595print OUT <<"EOF";
1596);
edd4d402 1597
107b5792 1598EOF
9fe2bb77
RL
1599if ($target{build_scheme}->[0] eq "unified") {
1600 my $recurse;
1601 $recurse = sub {
1602 my $indent = shift;
1603 foreach (@_) {
1604 if (ref $_ eq "ARRAY") {
1605 print OUT " "x$indent, "[\n";
1606 foreach (@$_) {
1607 $recurse->($indent + 4, $_);
1608 }
1609 print OUT " "x$indent, "],\n";
1610 } elsif (ref $_ eq "HASH") {
1611 my %h = %$_;
1612 print OUT " "x$indent, "{\n";
1613 foreach (sort keys %h) {
1614 if (ref $h{$_} eq "") {
1615 print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1616 } else {
1617 print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1618 $recurse->($indent + 8, $h{$_});
1619 }
1620 }
1621 print OUT " "x$indent, "},\n";
1622 } else {
1623 print OUT " "x$indent, quotify("perl", $_), ",\n";
1624 }
1625 }
1626 };
1627 print OUT "our %unified_info = (\n";
1628 foreach (sort keys %unified_info) {
1629 if (ref $unified_info{$_} eq "") {
1630 print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1631 } else {
1632 print OUT " "x4, quotify("perl", $_), " =>\n";
1633 $recurse->(8, $unified_info{$_});
1634 }
1635 }
1636 print OUT <<"EOF";
1637);
1638
1639EOF
1640}
1641print OUT "1;\n";
d02b48c6 1642close(OUT);
f2d4be3b 1643
9fe2bb77
RL
1644die <<"EOF" if $target{build_scheme}->[0] ne "unified" && $srcdir ne $blddir;
1645
1646***** Trying building anywhere else than in the source tree will not
1647***** work for target $config{target}. To make it possible, it needs
1648***** to use the "unified" build scheme.
1649
1650EOF
1651
291e94df
RL
1652print "IsMK1MF =", ($target{build_scheme}->[0] eq "mk1mf" ? "yes" : "no"), "\n";
1653print "CC =$target{cc}\n";
107b5792 1654print "CFLAG =$config{cflags}\n";
1740c162
RL
1655print "LFLAGS =$config{lflags}\n";
1656print "EX_LIBS =$config{ex_libs}\n";
291e94df
RL
1657print "CPUID_OBJ =$target{cpuid_obj}\n";
1658print "BN_ASM =$target{bn_obj}\n";
1659print "EC_ASM =$target{ec_obj}\n";
1660print "DES_ENC =$target{des_obj}\n";
1661print "AES_ENC =$target{aes_obj}\n";
1662print "BF_ENC =$target{bf_obj}\n";
1663print "CAST_ENC =$target{cast_obj}\n";
1664print "RC4_ENC =$target{rc4_obj}\n";
1665print "RC5_ENC =$target{rc5_obj}\n";
1666print "MD5_OBJ_ASM =$target{md5_obj}\n";
1667print "SHA1_OBJ_ASM =$target{sha1_obj}\n";
1668print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
1669print "CMLL_ENC =$target{cmll_obj}\n";
1670print "MODES_OBJ =$target{modes_obj}\n";
f0bd4686 1671print "PADLOCK_OBJ =$target{padlock_obj}\n";
291e94df
RL
1672print "CHACHA_ENC =$target{chacha_obj}\n";
1673print "POLY1305_OBJ =$target{poly1305_obj}\n";
7d130f68 1674print "PROCESSOR =$config{processor}\n";
291e94df
RL
1675print "RANLIB =$target{ranlib}\n";
1676print "ARFLAGS =$target{arflags}\n";
1677print "PERL =$config{perl}\n";
f0bd4686 1678print "\n";
7d130f68
RL
1679print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
1680print "SIXTY_FOUR_BIT mode\n" if $config{b64};
1681print "THIRTY_TWO_BIT mode\n" if $config{b32};
7d130f68
RL
1682print "BN_LLONG mode\n" if $config{bn_ll};
1683print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} != $def_int;
cba5068d 1684
9fe2bb77
RL
1685make_path(catdir($blddir, "include/openssl"));
1686run_dofile(catfile($blddir, "include/openssl/opensslconf.h"),
1687 catfile($srcdir, "include/openssl/opensslconf.h.in"));
f0bd4686 1688
9fe2bb77 1689make_path(catdir($blddir, "crypto/include/internal"));
3e9e810f 1690foreach my $alg ( 'bn' ) {
9fe2bb77
RL
1691 run_dofile(catfile($blddir, "crypto/include/internal/${alg}_conf.h"),
1692 catfile($srcdir, "crypto/include/internal/${alg}_conf.h.in"));
f0bd4686
RL
1693}
1694
9fe2bb77
RL
1695###
1696### When the old "unixmake" scheme goes away, so does this function
1697###
1698sub build_Makefile {
1699 run_dofile("Makefile","Makefile.in");
1700
1701 # Copy all Makefile.in to Makefile (except top-level)
1702 use File::Find;
1703 use IO::File;
1704 find(
1705 {
1706 preprocess => sub {
1707 grep(!/^\./, @_);
1708 },
1709 wanted => sub {
1710 return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
1711 my $in = IO::File->new($_, "r") or
1712 die sprintf "Error reading Makefile.in in %s: !$\n",
1713 $File::Find::dir;
1714 my $out = IO::File->new("Makefile", "w") or
1715 die sprintf "Error writing Makefile in %s: !$\n",
1716 $File::Find::dir;
1717 print $out "# Generated from $_, do not edit\n";
1718 while (my $line = <$in>) { print $out $line }
1719 $in->close() or
1720 die sprintf "Error reading Makefile.in in %s: !$\n",
1721 $File::Find::dir;
1722 $out->close() or
1723 die sprintf "Error writing Makefile in %s: !$\n",
1724 $File::Find::dir;
1725 },
fb36ca12 1726 },
9fe2bb77
RL
1727 ".");
1728}
d10dac11 1729
88087414 1730my %builders = (
9fe2bb77
RL
1731 unified => sub {
1732 die "unified build currently does nothing";
1733 },
88087414 1734 unixmake => sub {
9fe2bb77
RL
1735 build_Makefile();
1736
1737 run_dofile("util/domd", "util/domd.in");
1738 chmod 0755, "util/domd";
1739
291e94df 1740 my $make_command = "$make PERL=\'$config{perl}\'";
88087414 1741 my $make_targets = "";
107b5792 1742 $make_targets .= " depend" if $config{depflags} ne $default_depflags && $make_depend;
88087414
RL
1743 (system $make_command.$make_targets) == 0 or die "make $make_targets failed"
1744 if $make_targets ne "";
107b5792 1745 if ($config{depflags} ne $default_depflags && !$make_depend) {
88087414
RL
1746 $warn_make_depend++;
1747 }
1748 },
1749 mk1mf => sub {
9fe2bb77
RL
1750 # The only reason we do this is to have something to build MINFO from
1751 build_Makefile();
1752
664b9985 1753 open (OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
76ffb43d 1754 printf OUT <<"EOF";
57119943
BM
1755#ifndef MK1MF_BUILD
1756 /* auto-generated by Configure for crypto/cversion.c:
1757 * for Unix builds, crypto/Makefile.ssl generates functional definitions;
1758 * Windows builds (and other mk1mf builds) compile cversion.c with
1759 * -DMK1MF_BUILD and use definitions added to this file by util/mk1mf.pl. */
1760 #error "Windows builds (PLATFORM=$target) use mk1mf.pl-created Makefiles"
1761#endif
9e935d7e 1762EOF
8e10f2b3 1763 close(OUT);
8e10f2b3 1764
88087414 1765 # create the ms/version32.rc file if needed
291e94df 1766 if (! grep /^netware/, @{$target{build_scheme}}) {
88087414 1767 my ($v1, $v2, $v3, $v4);
3fa04f0d 1768 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
1769 $v1=hex $1;
1770 $v2=hex $2;
1771 $v3=hex $3;
1772 $v4=hex $4;
88087414
RL
1773 }
1774 open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
1775 print OUT <<"EOF";
fc6a6a10
DSH
1776#include <winver.h>
1777
1778LANGUAGE 0x09,0x01
1779
17801 VERSIONINFO
1781 FILEVERSION $v1,$v2,$v3,$v4
1782 PRODUCTVERSION $v1,$v2,$v3,$v4
1783 FILEFLAGSMASK 0x3fL
1784#ifdef _DEBUG
1785 FILEFLAGS 0x01L
1786#else
1787 FILEFLAGS 0x00L
1788#endif
1789 FILEOS VOS__WINDOWS32
1790 FILETYPE VFT_DLL
1791 FILESUBTYPE 0x0L
1792BEGIN
1793 BLOCK "StringFileInfo"
1794 BEGIN
1795 BLOCK "040904b0"
1796 BEGIN
fce0ba5f 1797 // Required:
fc6a6a10
DSH
1798 VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
1799 VALUE "FileDescription", "OpenSSL Shared Library\\0"
3fa04f0d 1800 VALUE "FileVersion", "$config{version}\\0"
fc6a6a10
DSH
1801#if defined(CRYPTO)
1802 VALUE "InternalName", "libeay32\\0"
1803 VALUE "OriginalFilename", "libeay32.dll\\0"
1804#elif defined(SSL)
1805 VALUE "InternalName", "ssleay32\\0"
1806 VALUE "OriginalFilename", "ssleay32.dll\\0"
a479d72d 1807#endif
fc6a6a10 1808 VALUE "ProductName", "The OpenSSL Toolkit\\0"
3fa04f0d 1809 VALUE "ProductVersion", "$config{version}\\0"
fc6a6a10
DSH
1810 // Optional:
1811 //VALUE "Comments", "\\0"
51cbee35 1812 VALUE "LegalCopyright", "Copyright © 1998-2015 The OpenSSL Project. Copyright © 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
fc6a6a10
DSH
1813 //VALUE "LegalTrademarks", "\\0"
1814 //VALUE "PrivateBuild", "\\0"
1815 //VALUE "SpecialBuild", "\\0"
1816 END
1817 END
1818 BLOCK "VarFileInfo"
1819 BEGIN
1820 VALUE "Translation", 0x409, 0x4b0
1821 END
1822END
1823EOF
88087414
RL
1824 close(OUT);
1825 }
1826 },
1827 );
1828
291e94df 1829my ($builder, @builder_opts) = @{$target{build_scheme}};
88087414 1830$builders{$builder}->(@builder_opts);
fce0ba5f 1831
76ffb43d 1832print <<"EOF";
63d3f44a 1833
89ec98e0 1834Configured for $target.
63d3f44a 1835EOF
5f8d5c96 1836
76ffb43d 1837print <<"EOF" if (!$no_threads && !$threads);
5f8d5c96
BM
1838
1839The library could not be configured for supporting multi-threaded
1840applications as the compiler options required on this system are not known.
ff1b7e09 1841See file INSTALL for details if you need multi-threading.
ec577822
BM
1842EOF
1843
76ffb43d 1844print <<"EOF" if ($no_shared_warn);
2964ba8c 1845
2e31ef03
RS
1846You gave the option 'shared', which is not supported on this platform, so
1847we will pretend you gave the option 'no-shared'. If you know how to implement
1848shared libraries, please let us know (but please first make sure you have
1849tried with a current version of OpenSSL).
1850EOF
1851
76ffb43d 1852print <<"EOF" if ($warn_make_depend);
2e31ef03
RS
1853
1854*** Because of configuration changes, you MUST do the following before
1855*** building:
1856
1857 make depend
2964ba8c
RL
1858EOF
1859
d02b48c6
RE
1860exit(0);
1861
bd5192b1
RL
1862######################################################################
1863#
1864# Helpers and utility functions
1865#
1866
1867# Configuration file reading #########################################
1868
1869# Helper function to implement conditional inheritance depending on the
1870# value of $no_asm. Used in inherit_from values as follows:
1871#
1872# inherit_from => [ "template", asm("asm_tmpl") ]
1873#
1874sub asm {
1875 my @x = @_;
1876 sub {
1877 $no_asm ? () : @x;
1878 }
1879}
1880
88087414
RL
1881# Helper function to implement adding values to already existing configuration
1882# values. It handles elements that are ARRAYs, CODEs and scalars
1883sub _add {
1884 my $separator = shift;
1885
1886 # If there's any ARRAY in the collection of values, we will return
1887 # an ARRAY of combined values, otherwise a string of joined values
1888 # with $separator as the separator.
1889 my $found_array = 0;
1890
1891 my @values =
1892 map {
1893 if (ref($_) eq "ARRAY") {
1894 $found_array = 1;
1895 @$_;
1896 } else {
1897 $_;
1898 }
1899 } (@_);
1900
1901 if ($found_array) {
1902 [ @values ];
1903 } else {
1904 join($separator, @values);
1905 }
1906}
1907sub add_before {
1908 my $separator = shift;
1909 my @x = @_;
1910 sub { _add($separator, @x, @_) };
1911}
1912sub add {
1913 my $separator = shift;
1914 my @x = @_;
1915 sub { _add($separator, @_, @x) };
1916}
1917
bd5192b1
RL
1918# configuration reader, evaluates the input file as a perl script and expects
1919# it to fill %targets with target configurations. Those are then added to
1920# %table.
1921sub read_config {
1922 my $fname = shift;
1923 open(CONFFILE, "< $fname")
1924 or die "Can't open configuration file '$fname'!\n";
1925 my $x = $/;
1926 undef $/;
1927 my $content = <CONFFILE>;
1928 $/ = $x;
1929 close(CONFFILE);
1930 my %targets = ();
1931 {
1932 local %table = %::table; # Protect %table from tampering
1933
1934 eval $content;
1935 warn $@ if $@;
1936 }
1937
1938 # For each target, check that it's configured with a hash table.
1939 foreach (keys %targets) {
1940 if (ref($targets{$_}) ne "HASH") {
1941 if (ref($targets{$_}) eq "") {
1942 warn "Deprecated target configuration for $_, ignoring...\n";
1943 } else {
1944 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
1945 }
1946 delete $targets{$_};
1947 }
1948 }
1949
1950 %table = (%table, %targets);
1951
1952}
1953
1954# configuration resolver. Will only resolve all the lazy evalutation
1955# codeblocks for the chozen target and all those it inherits from,
1956# recursively
1957sub resolve_config {
1958 my $target = shift;
1959 my @breadcrumbs = @_;
1960
1961 if (grep { $_ eq $target } @breadcrumbs) {
1962 die "inherit_from loop! target backtrace:\n "
1963 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
1964 }
1965
1966 if (!defined($table{$target})) {
1967 warn "Warning! target $target doesn't exist!\n";
1968 return ();
1969 }
1970 # Recurse through all inheritances. They will be resolved on the
1971 # fly, so when this operation is done, they will all just be a
1972 # bunch of attributes with string values.
1973 # What we get here, though, are keys with references to lists of
1974 # the combined values of them all. We will deal with lists after
1975 # this stage is done.
1976 my %combined_inheritance = ();
1977 if ($table{$target}->{inherit_from}) {
1978 my @inherit_from =
1979 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
1980 foreach (@inherit_from) {
1981 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
1982
1983 # 'template' is a marker that's considered private to
1984 # the config that had it.
1985 delete $inherited_config{template};
1986
1987 map {
1988 if (!$combined_inheritance{$_}) {
1989 $combined_inheritance{$_} = [];
1990 }
1991 push @{$combined_inheritance{$_}}, $inherited_config{$_};
1992 } keys %inherited_config;
1993 }
1994 }
1995
1996 # We won't need inherit_from in this target any more, since we've
1997 # resolved all the inheritances that lead to this
1998 delete $table{$target}->{inherit_from};
1999
2000 # Now is the time to deal with those lists. Here's the place to
2001 # decide what shall be done with those lists, all based on the
2002 # values of the target we're currently dealing with.
2003 # - If a value is a coderef, it will be executed with the list of
2004 # inherited values as arguments.
2005 # - If the corresponding key doesn't have a value at all or is the
2006 # emoty string, the inherited value list will be run through the
2007 # default combiner (below), and the result becomes this target's
2008 # value.
2009 # - Otherwise, this target's value is assumed to be a string that
2010 # will simply override the inherited list of values.
88087414 2011 my $default_combiner = add(" ");
bd5192b1
RL
2012
2013 my %all_keys =
2014 map { $_ => 1 } (keys %combined_inheritance,
2015 keys %{$table{$target}});
2016 foreach (sort keys %all_keys) {
2017
2018 # Current target doesn't have a value for the current key?
2019 # Assign it the default combiner, the rest of this loop body
2020 # will handle it just like any other coderef.
2021 if (!exists $table{$target}->{$_}) {
2022 $table{$target}->{$_} = $default_combiner;
2023 }
2024
2025 my $valuetype = ref($table{$target}->{$_});
2026 if ($valuetype eq "CODE") {
2027 # CODE reference, execute it with the inherited values as
2028 # arguments.
2029 $table{$target}->{$_} =
2030 $table{$target}->{$_}->(@{$combined_inheritance{$_}});
88087414
RL
2031 } elsif ($valuetype eq "ARRAY" || $valuetype eq "") {
2032 # ARRAY or Scalar, just leave it as is.
bd5192b1
RL
2033 } else {
2034 # Some other type of reference that we don't handle.
2035 # Better to abort at this point.
2036 die "cannot handle reference type $valuetype,"
2037 ," found in target $target -> $_\n";
2038 }
2039 }
2040
2041 # Finally done, return the result.
2042 return %{$table{$target}};
2043}
2044
462ba4f6 2045sub usage
d02b48c6 2046 {
462ba4f6 2047 print STDERR $usage;
10a926c1 2048 print STDERR "\npick os/compiler from:\n";
1641cb60 2049 my $j=0;
6457ad15 2050 my $i;
10a926c1 2051 my $k=0;
6457ad15 2052 foreach $i (sort keys %table)
d02b48c6 2053 {
bd5192b1 2054 next if $table{$i}->{template};
462ba4f6 2055 next if $i =~ /^debug/;
10a926c1
UM
2056 $k += length($i) + 1;
2057 if ($k > 78)
2058 {
2059 print STDERR "\n";
2060 $k=length($i);
2061 }
2062 print STDERR $i . " ";
462ba4f6
UM
2063 }
2064 foreach $i (sort keys %table)
2065 {
bd5192b1 2066 next if $table{$i}->{template};
462ba4f6 2067 next if $i !~ /^debug/;
10a926c1
UM
2068 $k += length($i) + 1;
2069 if ($k > 78)
2070 {
2071 print STDERR "\n";
2072 $k=length($i);
2073 }
2074 print STDERR $i . " ";
d02b48c6 2075 }
10a926c1 2076 print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
462ba4f6 2077 exit(1);
d02b48c6
RE
2078 }
2079
107b5792
RL
2080sub run_dofile()
2081{
107b5792 2082 my $out = shift;
9fe2bb77 2083 my @templates = @_;
107b5792 2084
ced2c2c5
RS
2085 unlink $out || warn "Can't remove $out, $!"
2086 if -f $out;
9fe2bb77
RL
2087 foreach (@templates) {
2088 die "Can't open $_, $!" unless -f $_;
2089 }
2090 my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" $dofile -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2091 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2092 system($cmd);
107b5792
RL
2093 exit 1 if $? != 0;
2094 rename("$out.new", $out) || die "Can't rename $out.new, $!";
2095}
2096
00ae96ca
RL
2097# Configuration printer ##############################################
2098
2099sub print_table_entry
2100{
2101 my $target = shift;
2102 my %target = resolve_config($target);
2103 my $type = shift;
2104
2105 # Don't print the templates
2106 return if $target{template};
2107
2108 my @sequence = (
f0bd4686 2109 "sys_id",
00ae96ca
RL
2110 "cc",
2111 "cflags",
2112 "debug_cflags",
2113 "release_cflags",
00ae96ca 2114 "thread_cflag",
f0bd4686
RL
2115 "unistd",
2116 "ld",
00ae96ca 2117 "lflags",
1740c162 2118 "ex_libs",
00ae96ca 2119 "debug_lflags",
1740c162 2120 "debug_ex_libs",
00ae96ca 2121 "release_lflags",
1740c162 2122 "release_ex_libs",
00ae96ca
RL
2123 "bn_ops",
2124 "cpuid_obj",
2125 "bn_obj",
2126 "ec_obj",
2127 "des_obj",
2128 "aes_obj",
2129 "bf_obj",
2130 "md5_obj",
2131 "sha1_obj",
2132 "cast_obj",
2133 "rc4_obj",
2134 "rmd160_obj",
2135 "rc5_obj",
2136 "wp_obj",
2137 "cmll_obj",
2138 "modes_obj",
f0bd4686 2139 "padlock_obj",
00ae96ca
RL
2140 "perlasm_scheme",
2141 "dso_scheme",
2142 "shared_target",
2143 "shared_cflag",
2144 "shared_ldflag",
2145 "shared_extension",
f0bd4686
RL
2146 "obj_extension",
2147 "exe_extension",
00ae96ca 2148 "ranlib",
f0bd4686 2149 "ar",
00ae96ca
RL
2150 "arflags",
2151 "multilib",
f0bd4686 2152 "build_scheme",
00ae96ca
RL
2153 );
2154
2155 if ($type eq "TABLE") {
2156 print "\n";
2157 print "*** $target\n";
2158 printf "\$%-12s = %s\n", $_, $target{$_} foreach (@sequence);
2159 } elsif ($type eq "HASH") {
2160 my $largest =
2161 length((sort { length($a) <=> length($b) } @sequence)[-1]);
2162 print " '$target' => {\n";
2163 foreach (@sequence) {
2164 if ($target{$_}) {
2165 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2166 }
2167 }
2168 print " },\n";
2169 }
2170}
2171
2172# Utility routines ###################################################
2173
99aab161
UM
2174sub which
2175 {
2176 my($name)=@_;
2177 my $path;
2178 foreach $path (split /:/, $ENV{PATH})
2179 {
107b5792 2180 if (-f "$path/$name$target{exe_extension}" and -x _)
99aab161 2181 {
107b5792
RL
2182 return "$path/$name$target{exe_extension}" unless ($name eq "perl" and
2183 system("$path/$name$target{exe_extension} -e " . '\'exit($]<5.0);\''));
99aab161
UM
2184 }
2185 }
2186 }
2187
fe05264e
RL
2188sub quotify {
2189 my %processors = (
2190 perl => sub { my $x = shift;
2191 $x =~ s/([\\\$\@"])/\\$1/g;
2192 return '"'.$x.'"'; },
2193 );
2194 my $for = shift;
2195 my $processor =
2196 defined($processors{$for}) ? $processors{$for} : sub { shift; };
2197
2198 map { $processor->($_); } @_;
2199}
107b5792 2200
9fe2bb77
RL
2201# collect_from_file($filename, $line_concat_cond_re, $line_concat)
2202# $filename is a file name to read from
2203# $line_concat_cond_re is a regexp detecting a line continuation ending
2204# $line_concat is a CODEref that takes care of concatenating two lines
2205sub collect_from_file {
2206 my $filename = shift;
2207 my $line_concat_cond_re = shift;
2208 my $line_concat = shift;
2209
2210 open my $fh, $filename || die "unable to read $filename: $!\n";
2211 return sub {
2212 my $saved_line = "";
2213 $_ = "";
2214 while (<$fh>) {
2215 chomp;
2216 if (defined $line_concat) {
2217 $_ = $line_concat->($saved_line, $_);
2218 $saved_line = "";
2219 }
2220 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2221 $saved_line = $_;
2222 next;
2223 }
2224 return $_;
2225 }
2226 die "$filename ending with continuation line\n" if $_;
2227 close $fh;
2228 return undef;
2229 }
2230}
2231
2232# collect_from_array($array, $line_concat_cond_re, $line_concat)
2233# $array is an ARRAYref of lines
2234# $line_concat_cond_re is a regexp detecting a line continuation ending
2235# $line_concat is a CODEref that takes care of concatenating two lines
2236sub collect_from_array {
2237 my $array = shift;
2238 my $line_concat_cond_re = shift;
2239 my $line_concat = shift;
2240 my @array = (@$array);
2241
2242 return sub {
2243 my $saved_line = "";
2244 $_ = "";
2245 while (defined($_ = shift @array)) {
2246 chomp;
2247 if (defined $line_concat) {
2248 $_ = $line_concat->($saved_line, $_);
2249 $saved_line = "";
2250 }
2251 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2252 $saved_line = $_;
2253 next;
2254 }
2255 return $_;
2256 }
2257 die "input text ending with continuation line\n" if $_;
2258 return undef;
2259 }
2260}
2261
2262# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2263# $lineiterator is a CODEref that delivers one line at a time.
107b5792
RL
2264# All following arguments are regex/CODEref pairs, where the regexp detects a
2265# line and the CODEref does something with the result of the regexp.
2266sub collect_information {
9fe2bb77 2267 my $lineiterator = shift;
107b5792
RL
2268 my %collectors = @_;
2269
9fe2bb77
RL
2270 while(defined($_ = $lineiterator->())) {
2271 chomp;
2272 my $found = 0;
2273 foreach my $re (keys %collectors) {
2274 if ($re ne "OTHERWISE" && /$re/) {
2275 $collectors{$re}->($lineiterator);
2276 $found = 1;
2277 };
2278 }
2279 if ($collectors{"OTHERWISE"}) {
2280 $collectors{"OTHERWISE"}->($lineiterator, $_)
2281 unless $found || !defined $collectors{"OTHERWISE"};
2282 }
107b5792 2283 }
107b5792 2284}