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