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