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