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