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