]> git.ipfire.org Git - thirdparty/openssl.git/blob - Configure
Add final(?) set of copyrights.
[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 },
1974 );
1975
1976 $builders{$builder}->($builder_platform, @builder_opts);
1977
1978 print <<"EOF";
1979
1980 Configured for $target.
1981 EOF
1982
1983 print <<"EOF" if ($disabled{threads} eq "unavailable");
1984
1985 The library could not be configured for supporting multi-threaded
1986 applications as the compiler options required on this system are not known.
1987 See file INSTALL for details if you need multi-threading.
1988 EOF
1989
1990 print <<"EOF" if ($no_shared_warn);
1991
1992 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
1993 platform, so we will pretend you gave the option 'no-pic', which also disables
1994 'shared' and 'dynamic-engine'. If you know how to implement shared libraries
1995 or position independent code, please let us know (but please first make sure
1996 you have tried with a current version of OpenSSL).
1997 EOF
1998
1999 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2000
2001 WARNING: there are indications that another build was made in the source
2002 directory. This build may have picked up artifacts from that build, the
2003 safest course of action is to clean the source directory and redo this
2004 configuration.
2005 EOF
2006
2007 exit(0);
2008
2009 ######################################################################
2010 #
2011 # Helpers and utility functions
2012 #
2013
2014 # Configuration file reading #########################################
2015
2016 # Note: All of the helper functions are for lazy evaluation. They all
2017 # return a CODE ref, which will return the intended value when evaluated.
2018 # Thus, whenever there's mention of a returned value, it's about that
2019 # intended value.
2020
2021 # Helper function to implement conditional inheritance depending on the
2022 # value of $disabled{asm}. Used in inherit_from values as follows:
2023 #
2024 # inherit_from => [ "template", asm("asm_tmpl") ]
2025 #
2026 sub asm {
2027 my @x = @_;
2028 sub {
2029 $disabled{asm} ? () : @x;
2030 }
2031 }
2032
2033 # Helper function to implement conditional value variants, with a default
2034 # plus additional values based on the value of $config{build_type}.
2035 # Arguments are given in hash table form:
2036 #
2037 # picker(default => "Basic string: ",
2038 # debug => "debug",
2039 # release => "release")
2040 #
2041 # When configuring with --debug, the resulting string will be
2042 # "Basic string: debug", and when not, it will be "Basic string: release"
2043 #
2044 # This can be used to create variants of sets of flags according to the
2045 # build type:
2046 #
2047 # cflags => picker(default => "-Wall",
2048 # debug => "-g -O0",
2049 # release => "-O3")
2050 #
2051 sub picker {
2052 my %opts = @_;
2053 return sub { add($opts{default} || (),
2054 $opts{$config{build_type}} || ())->(); }
2055 }
2056
2057 # Helper function to combine several values of different types into one.
2058 # This is useful if you want to combine a string with the result of a
2059 # lazy function, such as:
2060 #
2061 # cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2062 #
2063 sub combine {
2064 my @stuff = @_;
2065 return sub { add(@stuff)->(); }
2066 }
2067
2068 # Helper function to implement conditional values depending on the value
2069 # of $disabled{threads}. Can be used as follows:
2070 #
2071 # cflags => combine("-Wall", threads("-pthread"))
2072 #
2073 sub threads {
2074 my @flags = @_;
2075 return sub { add($disabled{threads} ? () : @flags)->(); }
2076 }
2077
2078
2079
2080 our $add_called = 0;
2081 # Helper function to implement adding values to already existing configuration
2082 # values. It handles elements that are ARRAYs, CODEs and scalars
2083 sub _add {
2084 my $separator = shift;
2085
2086 # If there's any ARRAY in the collection of values OR the separator
2087 # is undef, we will return an ARRAY of combined values, otherwise a
2088 # string of joined values with $separator as the separator.
2089 my $found_array = !defined($separator);
2090
2091 my @values =
2092 map {
2093 my $res = $_;
2094 while (ref($res) eq "CODE") {
2095 $res = $res->();
2096 }
2097 if (defined($res)) {
2098 if (ref($res) eq "ARRAY") {
2099 $found_array = 1;
2100 @$res;
2101 } else {
2102 $res;
2103 }
2104 } else {
2105 ();
2106 }
2107 } (@_);
2108
2109 $add_called = 1;
2110
2111 if ($found_array) {
2112 [ @values ];
2113 } else {
2114 join($separator, grep { defined($_) && $_ ne "" } @values);
2115 }
2116 }
2117 sub add_before {
2118 my $separator = " ";
2119 if (ref($_[$#_]) eq "HASH") {
2120 my $opts = pop;
2121 $separator = $opts->{separator};
2122 }
2123 my @x = @_;
2124 sub { _add($separator, @x, @_) };
2125 }
2126 sub add {
2127 my $separator = " ";
2128 if (ref($_[$#_]) eq "HASH") {
2129 my $opts = pop;
2130 $separator = $opts->{separator};
2131 }
2132 my @x = @_;
2133 sub { _add($separator, @_, @x) };
2134 }
2135
2136 # configuration reader, evaluates the input file as a perl script and expects
2137 # it to fill %targets with target configurations. Those are then added to
2138 # %table.
2139 sub read_config {
2140 my $fname = shift;
2141 open(CONFFILE, "< $fname")
2142 or die "Can't open configuration file '$fname'!\n";
2143 my $x = $/;
2144 undef $/;
2145 my $content = <CONFFILE>;
2146 $/ = $x;
2147 close(CONFFILE);
2148 my %targets = ();
2149 {
2150 local %table = %::table; # Protect %table from tampering
2151
2152 eval $content;
2153 warn $@ if $@;
2154 }
2155
2156 # For each target, check that it's configured with a hash table.
2157 foreach (keys %targets) {
2158 if (ref($targets{$_}) ne "HASH") {
2159 if (ref($targets{$_}) eq "") {
2160 warn "Deprecated target configuration for $_, ignoring...\n";
2161 } else {
2162 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2163 }
2164 delete $targets{$_};
2165 }
2166 }
2167
2168 %table = (%table, %targets);
2169
2170 }
2171
2172 # configuration resolver. Will only resolve all the lazy evaluation
2173 # codeblocks for the chosen target and all those it inherits from,
2174 # recursively
2175 sub resolve_config {
2176 my $target = shift;
2177 my @breadcrumbs = @_;
2178
2179 # my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2180
2181 if (grep { $_ eq $target } @breadcrumbs) {
2182 die "inherit_from loop! target backtrace:\n "
2183 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
2184 }
2185
2186 if (!defined($table{$target})) {
2187 warn "Warning! target $target doesn't exist!\n";
2188 return ();
2189 }
2190 # Recurse through all inheritances. They will be resolved on the
2191 # fly, so when this operation is done, they will all just be a
2192 # bunch of attributes with string values.
2193 # What we get here, though, are keys with references to lists of
2194 # the combined values of them all. We will deal with lists after
2195 # this stage is done.
2196 my %combined_inheritance = ();
2197 if ($table{$target}->{inherit_from}) {
2198 my @inherit_from =
2199 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2200 foreach (@inherit_from) {
2201 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2202
2203 # 'template' is a marker that's considered private to
2204 # the config that had it.
2205 delete $inherited_config{template};
2206
2207 foreach (keys %inherited_config) {
2208 if (!$combined_inheritance{$_}) {
2209 $combined_inheritance{$_} = [];
2210 }
2211 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2212 }
2213 }
2214 }
2215
2216 # We won't need inherit_from in this target any more, since we've
2217 # resolved all the inheritances that lead to this
2218 delete $table{$target}->{inherit_from};
2219
2220 # Now is the time to deal with those lists. Here's the place to
2221 # decide what shall be done with those lists, all based on the
2222 # values of the target we're currently dealing with.
2223 # - If a value is a coderef, it will be executed with the list of
2224 # inherited values as arguments.
2225 # - If the corresponding key doesn't have a value at all or is the
2226 # empty string, the inherited value list will be run through the
2227 # default combiner (below), and the result becomes this target's
2228 # value.
2229 # - Otherwise, this target's value is assumed to be a string that
2230 # will simply override the inherited list of values.
2231 my $default_combiner = add();
2232
2233 my %all_keys =
2234 map { $_ => 1 } (keys %combined_inheritance,
2235 keys %{$table{$target}});
2236
2237 sub process_values {
2238 my $object = shift;
2239 my $inherited = shift; # Always a [ list ]
2240 my $target = shift;
2241 my $entry = shift;
2242
2243 $add_called = 0;
2244
2245 while(ref($object) eq "CODE") {
2246 $object = $object->(@$inherited);
2247 }
2248 if (!defined($object)) {
2249 return ();
2250 }
2251 elsif (ref($object) eq "ARRAY") {
2252 local $add_called; # To make sure recursive calls don't affect it
2253 return [ map { process_values($_, $inherited, $target, $entry) }
2254 @$object ];
2255 } elsif (ref($object) eq "") {
2256 return $object;
2257 } else {
2258 die "cannot handle reference type ",ref($object)
2259 ," found in target ",$target," -> ",$entry,"\n";
2260 }
2261 }
2262
2263 foreach (sort keys %all_keys) {
2264 my $previous = $combined_inheritance{$_};
2265
2266 # Current target doesn't have a value for the current key?
2267 # Assign it the default combiner, the rest of this loop body
2268 # will handle it just like any other coderef.
2269 if (!exists $table{$target}->{$_}) {
2270 $table{$target}->{$_} = $default_combiner;
2271 }
2272
2273 $table{$target}->{$_} = process_values($table{$target}->{$_},
2274 $combined_inheritance{$_},
2275 $target, $_);
2276 unless(defined($table{$target}->{$_})) {
2277 delete $table{$target}->{$_};
2278 }
2279 # if ($extra_checks &&
2280 # $previous && !($add_called || $previous ~~ $table{$target}->{$_})) {
2281 # warn "$_ got replaced in $target\n";
2282 # }
2283 }
2284
2285 # Finally done, return the result.
2286 return %{$table{$target}};
2287 }
2288
2289 sub usage
2290 {
2291 print STDERR $usage;
2292 print STDERR "\npick os/compiler from:\n";
2293 my $j=0;
2294 my $i;
2295 my $k=0;
2296 foreach $i (sort keys %table)
2297 {
2298 next if $table{$i}->{template};
2299 next if $i =~ /^debug/;
2300 $k += length($i) + 1;
2301 if ($k > 78)
2302 {
2303 print STDERR "\n";
2304 $k=length($i);
2305 }
2306 print STDERR $i . " ";
2307 }
2308 foreach $i (sort keys %table)
2309 {
2310 next if $table{$i}->{template};
2311 next if $i !~ /^debug/;
2312 $k += length($i) + 1;
2313 if ($k > 78)
2314 {
2315 print STDERR "\n";
2316 $k=length($i);
2317 }
2318 print STDERR $i . " ";
2319 }
2320 print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2321 exit(1);
2322 }
2323
2324 sub run_dofile
2325 {
2326 my $out = shift;
2327 my @templates = @_;
2328
2329 unlink $out || warn "Can't remove $out, $!"
2330 if -f $out;
2331 foreach (@templates) {
2332 die "Can't open $_, $!" unless -f $_;
2333 }
2334 my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2335 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2336 system($cmd);
2337 exit 1 if $? != 0;
2338 rename("$out.new", $out) || die "Can't rename $out.new, $!";
2339 }
2340
2341 sub which
2342 {
2343 my ($name)=@_;
2344
2345 if (eval { require IPC::Cmd; 1; }) {
2346 IPC::Cmd->import();
2347 return scalar IPC::Cmd::can_run($name);
2348 } else {
2349 # if there is $directories component in splitpath,
2350 # then it's not something to test with $PATH...
2351 return $name if (File::Spec->splitpath($name))[1];
2352
2353 foreach (File::Spec->path()) {
2354 my $fullpath = catfile($_, "$name$target{exe_extension}");
2355 if (-f $fullpath and -x $fullpath) {
2356 return $fullpath;
2357 }
2358 }
2359 }
2360 }
2361
2362 # Configuration printer ##############################################
2363
2364 sub print_table_entry
2365 {
2366 my $target = shift;
2367 my %target = resolve_config($target);
2368 my $type = shift;
2369
2370 # Don't print the templates
2371 return if $target{template};
2372
2373 my @sequence = (
2374 "sys_id",
2375 "cc",
2376 "cflags",
2377 "defines",
2378 "unistd",
2379 "ld",
2380 "lflags",
2381 "plib_lflags",
2382 "ex_libs",
2383 "bn_ops",
2384 "cpuid_obj",
2385 "bn_obj",
2386 "ec_obj",
2387 "des_obj",
2388 "aes_obj",
2389 "bf_obj",
2390 "md5_obj",
2391 "sha1_obj",
2392 "cast_obj",
2393 "rc4_obj",
2394 "rmd160_obj",
2395 "rc5_obj",
2396 "wp_obj",
2397 "cmll_obj",
2398 "modes_obj",
2399 "padlock_obj",
2400 "thread_scheme",
2401 "perlasm_scheme",
2402 "dso_scheme",
2403 "shared_target",
2404 "shared_cflag",
2405 "shared_ldflag",
2406 "shared_rcflag",
2407 "shared_extension",
2408 "shared_extension_simple",
2409 "shared_import_extension",
2410 "dso_extension",
2411 "obj_extension",
2412 "exe_extension",
2413 "ranlib",
2414 "ar",
2415 "arflags",
2416 "multilib",
2417 "build_scheme",
2418 );
2419
2420 if ($type eq "TABLE") {
2421 print "\n";
2422 print "*** $target\n";
2423 foreach (@sequence) {
2424 if (ref($target{$_}) eq "ARRAY") {
2425 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2426 } else {
2427 printf "\$%-12s = %s\n", $_, $target{$_};
2428 }
2429 }
2430 } elsif ($type eq "HASH") {
2431 my $largest =
2432 length((sort { length($a) <=> length($b) } @sequence)[-1]);
2433 print " '$target' => {\n";
2434 foreach (@sequence) {
2435 if ($target{$_}) {
2436 if (ref($target{$_}) eq "ARRAY") {
2437 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2438 } else {
2439 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2440 }
2441 }
2442 }
2443 print " },\n";
2444 }
2445 }
2446
2447 # Utility routines ###################################################
2448
2449 # On VMS, if the given file is a logical name, File::Spec::Functions
2450 # will consider it an absolute path. There are cases when we want a
2451 # purely syntactic check without checking the environment.
2452 sub isabsolute {
2453 my $file = shift;
2454
2455 # On non-platforms, we just use file_name_is_absolute().
2456 return file_name_is_absolute($file) unless $^O eq "VMS";
2457
2458 # If the file spec includes a device or a directpry spec,
2459 # file_name_is_absolute() is perfectly safe.
2460 return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2461
2462 # Here, we know the given file spec isn't absolute
2463 return 0;
2464 }
2465
2466 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2467 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2468 # realpath() requires that at least all path components except the last is an
2469 # existing directory. On VMS, the last component of the directory spec must
2470 # exist.
2471 sub absolutedir {
2472 my $dir = shift;
2473
2474 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
2475 # will return the volume name for the device, no matter what. Also,
2476 # it will return an incorrect directory spec if the argument is a
2477 # directory that doesn't exist.
2478 if ($^O eq "VMS") {
2479 return rel2abs($dir);
2480 }
2481
2482 # We use realpath() on Unix, since no other will properly clean out
2483 # a directory spec.
2484 use Cwd qw/realpath/;
2485
2486 return realpath($dir);
2487 }
2488
2489 sub quotify {
2490 my %processors = (
2491 perl => sub { my $x = shift;
2492 $x =~ s/([\\\$\@"])/\\$1/g;
2493 return '"'.$x.'"'; },
2494 );
2495 my $for = shift;
2496 my $processor =
2497 defined($processors{$for}) ? $processors{$for} : sub { shift; };
2498
2499 return map { $processor->($_); } @_;
2500 }
2501
2502 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2503 # $filename is a file name to read from
2504 # $line_concat_cond_re is a regexp detecting a line continuation ending
2505 # $line_concat is a CODEref that takes care of concatenating two lines
2506 sub collect_from_file {
2507 my $filename = shift;
2508 my $line_concat_cond_re = shift;
2509 my $line_concat = shift;
2510
2511 open my $fh, $filename || die "unable to read $filename: $!\n";
2512 return sub {
2513 my $saved_line = "";
2514 $_ = "";
2515 while (<$fh>) {
2516 s|\R$||;
2517 if (defined $line_concat) {
2518 $_ = $line_concat->($saved_line, $_);
2519 $saved_line = "";
2520 }
2521 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2522 $saved_line = $_;
2523 next;
2524 }
2525 return $_;
2526 }
2527 die "$filename ending with continuation line\n" if $_;
2528 close $fh;
2529 return undef;
2530 }
2531 }
2532
2533 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2534 # $array is an ARRAYref of lines
2535 # $line_concat_cond_re is a regexp detecting a line continuation ending
2536 # $line_concat is a CODEref that takes care of concatenating two lines
2537 sub collect_from_array {
2538 my $array = shift;
2539 my $line_concat_cond_re = shift;
2540 my $line_concat = shift;
2541 my @array = (@$array);
2542
2543 return sub {
2544 my $saved_line = "";
2545 $_ = "";
2546 while (defined($_ = shift @array)) {
2547 s|\R$||;
2548 if (defined $line_concat) {
2549 $_ = $line_concat->($saved_line, $_);
2550 $saved_line = "";
2551 }
2552 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2553 $saved_line = $_;
2554 next;
2555 }
2556 return $_;
2557 }
2558 die "input text ending with continuation line\n" if $_;
2559 return undef;
2560 }
2561 }
2562
2563 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2564 # $lineiterator is a CODEref that delivers one line at a time.
2565 # All following arguments are regex/CODEref pairs, where the regexp detects a
2566 # line and the CODEref does something with the result of the regexp.
2567 sub collect_information {
2568 my $lineiterator = shift;
2569 my %collectors = @_;
2570
2571 while(defined($_ = $lineiterator->())) {
2572 s|\R$||;
2573 my $found = 0;
2574 if ($collectors{"BEFORE"}) {
2575 $collectors{"BEFORE"}->($_);
2576 }
2577 foreach my $re (keys %collectors) {
2578 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2579 $collectors{$re}->($lineiterator);
2580 $found = 1;
2581 };
2582 }
2583 if ($collectors{"OTHERWISE"}) {
2584 $collectors{"OTHERWISE"}->($lineiterator, $_)
2585 unless $found || !defined $collectors{"OTHERWISE"};
2586 }
2587 if ($collectors{"AFTER"}) {
2588 $collectors{"AFTER"}->($_);
2589 }
2590 }
2591 }
2592
2593 # tokenize($line)
2594 # $line is a line of text to split up into tokens
2595 # returns a list of tokens
2596 #
2597 # Tokens are divided by spaces. If the tokens include spaces, they
2598 # have to be quoted with single or double quotes. Double quotes
2599 # inside a double quoted token must be escaped. Escaping is done
2600 # with backslash.
2601 # Basically, the same quoting rules apply for " and ' as in any
2602 # Unix shell.
2603 sub tokenize {
2604 my $line = my $debug_line = shift;
2605 my @result = ();
2606
2607 while ($line =~ s|^\s+||, $line ne "") {
2608 my $token = "";
2609 while ($line ne "" && $line !~ m|^\s|) {
2610 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2611 $token .= $1;
2612 $line = $';
2613 } elsif ($line =~ m/^'([^']*)'/) {
2614 $token .= $1;
2615 $line = $';
2616 } elsif ($line =~ m/^(\S+)/) {
2617 $token .= $1;
2618 $line = $';
2619 }
2620 }
2621 push @result, $token;
2622 }
2623
2624 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2625 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2626 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";
2627 }
2628 return @result;
2629 }