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