3 # Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
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
10 ## Configure -- OpenSSL source tree configuration script
16 use lib
"$FindBin::Bin/util/perl";
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";
22 use OpenSSL
::Template
;
25 # see INSTALL.md for instructions.
27 my $orig_death_handler = $SIG{__DIE__
};
28 $SIG{__DIE__
} = \
&death_handler
;
30 my $usage="Usage: Configure [no-<feature> ...] [enable-<feature> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[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";
34 **********************************************************************
36 *** OpenSSL has been successfully configured ***
38 *** If you encounter a problem while building, please open an ***
39 *** issue on GitHub <https://github.com/openssl/openssl/issues> ***
40 *** and include the output from the following command: ***
42 *** perl configdata.pm --dump ***
44 *** (If you are new to OpenSSL, you might want to consult the ***
45 *** 'Troubleshooting' section in the INSTALL.md file first) ***
47 **********************************************************************
52 # --config add the given configuration file, which will be read after
53 # any "Configurations*" files that are found in the same
54 # directory as this script.
55 # --prefix prefix for the OpenSSL installation, which includes the
56 # directories bin, lib, include, share/man, share/doc/openssl
57 # This becomes the value of INSTALLTOP in Makefile
58 # (Default: /usr/local)
59 # --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys.
60 # If it's a relative directory, it will be added on the directory
61 # given with --prefix.
62 # This becomes the value of OPENSSLDIR in Makefile and in C.
63 # (Default: PREFIX/ssl)
64 # --banner=".." Output specified text instead of default completion banner
66 # -w Don't wait after showing a Configure warning
68 # --cross-compile-prefix Add specified prefix to binutils components.
70 # --api One of 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0, 1.1.1, or 3.0
71 # Define the public APIs as they were for that version
72 # including patch releases. If 'no-deprecated' is also
73 # given, do not compile support for interfaces deprecated
74 # up to and including the specified OpenSSL version.
76 # no-hw-xxx do not compile support for specific crypto hardware.
77 # Generic OpenSSL-style methods relating to this support
78 # are always compiled but return NULL if the hardware
79 # support isn't compiled.
81 # enable-demos Enable the building of the example code in the demos directory
82 # enable-h3demo Enable the http3 demo, which currently only links to the
83 # external nghttp3 library on unix platforms
86 # Enable the building of the hq-interop code for construction
87 # of the interop container
89 # no-hw do not compile support for any crypto hardware.
90 # [no-]threads [don't] try to create a library that is suitable for
91 # multithreaded applications (default is "threads" if we
94 # [don't] allow thread pool functionality
95 # [no-]default-thread-pool
96 # [don't] allow default thread pool functionality
97 # [no-]shared [don't] try to create shared libraries when supported.
98 # [no-]pic [don't] try to build position independent code when supported.
99 # If disabled, it also disables shared and dynamic-engine.
100 # no-asm do not use assembler
101 # no-egd do not compile support for the entropy-gathering daemon APIs
102 # [no-]zlib [don't] compile support for zlib compression.
103 # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
104 # library and will be loaded at run-time by the OpenSSL library.
105 # sctp include SCTP support
106 # no-quic disable QUIC support
107 # no-uplink Don't build support for UPLINK interface.
108 # enable-weak-ssl-ciphers
109 # Enable weak ciphers that are disabled by default.
110 # 386 generate 80386 code in assembly modules
111 # no-sse2 disables IA-32 SSE2 code in assembly modules, the above
112 # mentioned '386' option implies this one
113 # no-<cipher> build without specified algorithm (dsa, idea, rc5, ...)
114 # -<xxx> +<xxx> All options which are unknown to the 'Configure' script are
115 # /<xxx> passed through to the compiler. Unix-style options beginning
116 # with a '-' or '+' are recognized, as well as Windows-style
117 # options beginning with a '/'. If the option contains arguments
118 # separated by spaces, then the URL-style notation %20 can be
119 # used for the space character in order to avoid having to quote
120 # the option. For example, -opt%20arg gets expanded to -opt arg.
121 # In fact, any ASCII character can be encoded as %xx using its
122 # hexadecimal encoding.
123 # -static while -static is also a pass-through compiler option (and
124 # as such is limited to environments where it's actually
125 # meaningful), it triggers a number configuration options,
126 # namely no-pic, no-shared and no-threads. It is
127 # argued that the only reason to produce statically linked
128 # binaries (and in context it means executables linked with
129 # -static flag, and not just executables linked with static
130 # libcrypto.a) is to eliminate dependency on specific run-time,
131 # a.k.a. libc version. The mentioned config options are meant
132 # to achieve just that. Unfortunately on Linux it's impossible
133 # to eliminate the dependency completely for openssl executable
134 # because of getaddrinfo and gethostbyname calls, which can
135 # invoke dynamically loadable library facility anyway to meet
136 # the lookup requests. For this reason on Linux statically
137 # linked openssl executable has rather debugging value than
138 # production quality.
140 # BN_LLONG use the type 'long long' in crypto/bn/bn.h
141 # RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
142 # Following are set automatically by this script
144 # MD5_ASM use some extra md5 assembler,
145 # SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86
146 # RMD160_ASM use some extra ripemd160 assembler,
147 # SHA256_ASM sha256_block is implemented in assembler
148 # SHA512_ASM sha512_block is implemented in assembler
149 # AES_ASM AES_[en|de]crypt is implemented in assembler
151 # Minimum warning options... any contributions to OpenSSL should at least
152 # get past these. Note that we only use these with C compilers, not with
155 # -DPEDANTIC complements -pedantic and is meant to mask code that
156 # is not strictly standard-compliant and/or implementation-specific,
157 # e.g. inline assembly, disregards to alignment requirements, such
158 # that -pedantic would complain about. Incidentally -DPEDANTIC has
159 # to be used even in sanitized builds, because sanitizer too is
160 # supposed to and does take notice of non-standard behaviour. Then
161 # -pedantic with pre-C9x compiler would also complain about 'long
162 # long' not being supported. As 64-bit algorithms are common now,
163 # it grew impossible to resolve this without sizeable additional
164 # code, so we just tell compiler to be pedantic about everything
165 # but 'long long' type.
167 my @gcc_devteam_warn = qw(
168 -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG
170 -Wmissing-declarations
172 -Wno-unused-parameter
173 -Wno-missing-field-initializers
174 -Wno-unterminated-string-initialization
186 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
187 # TODO(openssl-team): fix problems and investigate if (at least) the
188 # following warnings can also be enabled:
190 # -Wunreachable-code -- no, too ugly/compiler-specific
191 # -Wlanguage-extension-token -- no, we use asm()
192 # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
193 # -Wextended-offsetof -- no, needed in CMS ASN1 code
194 my @clang_devteam_warn = qw(
195 -Wno-unknown-warning-option
196 -Wno-parentheses-equality
197 -Wno-language-extension-token
198 -Wno-extended-offsetof
200 -Wno-tautological-constant-out-of-range-compare
201 -Wconditional-uninitialized
202 -Wincompatible-pointer-types-discards-qualifiers
203 -Wmissing-variable-declarations
206 my @cl_devteam_warn = qw(
210 my $strict_warnings = 0;
212 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
213 # which would cover all BSD flavors. -pthread applies to them all,
214 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
215 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
216 # which has to be accompanied by explicit -D_THREAD_SAFE and
217 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
218 # seems to be sufficient?
219 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
222 # API compatibility name to version number mapping.
225 # This table expresses when API additions or changes can occur.
226 # The numbering used changes from 3.0 and on because we updated
227 # (solidified) our version numbering scheme at that point.
229 # From 3.0 and on, we internalise the given version number in decimal
230 # as MAJOR * 10000 + MINOR * 100 + 0
234 # Note that before 3.0, we didn't have the same version number scheme.
235 # Still, the numbering we use here covers what we need.
244 # For OpenSSL::config::get_platform
252 our $now_printing; # set to current entry's name in print_table_entry
253 # (todo: right thing would be to encapsulate name
254 # into %target [class] and make print_table_entry
257 # Forward declarations ###############################################
259 # read_config(filename)
261 # Reads a configuration file and populates %table with the contents
262 # (which the configuration file places in %targets).
265 # resolve_config(target)
267 # Resolves all the late evaluations, inheritances and so on for the
268 # chosen target and any target it inherits from.
272 # Information collection #############################################
274 # Unified build supports separate build dir
275 my $srcdir = catdir
(absolutedir
(dirname
($0))); # catdir ensures local syntax
276 my $blddir = catdir
(absolutedir
(".")); # catdir ensures local syntax
278 # File::Spec::Unix doesn't detect case insensitivity, so we make sure to
279 # check if the source and build directory are really the same, and make
280 # them so. This avoids all kinds of confusion later on.
281 # We must check @File::Spec::ISA rather than using File::Spec->isa() to
282 # know if File::Spec ended up loading File::Spec::Unix.
284 if (grep(/::Unix$/, @File::Spec
::ISA
)
285 && samedir
($srcdir, $blddir));
287 my $dofile = abs2rel
(catfile
($srcdir, "util/dofile.pl"));
289 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
291 $config{sourcedir
} = abs2rel
($srcdir, $blddir);
292 $config{builddir
} = abs2rel
($blddir, $blddir);
293 # echo -n 'holy hand grenade of antioch' | openssl sha256
295 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
297 # Collect reconfiguration information if needed
300 if (grep /^reconf(igure)?$/, @argvcopy) {
301 die "reconfiguring with other arguments present isn't supported"
302 if scalar @argvcopy > 1;
303 if (-f
"./configdata.pm") {
304 my $file = "./configdata.pm";
305 unless (my $return = do $file) {
306 die "couldn't parse $file: $@" if $@
;
307 die "couldn't do $file: $!" unless defined $return;
308 die "couldn't run $file" unless $return;
311 @argvcopy = defined($configdata::config
{perlargv
}) ?
312 @
{$configdata::config
{perlargv
}} : ();
313 die "Incorrect data to reconfigure, please do a normal configuration\n"
314 if (grep(/^reconf/,@argvcopy));
315 $config{perlenv
} = $configdata::config
{perlenv
} // {};
317 die "Insufficient data to reconfigure, please do a normal configuration\n";
321 $config{perlargv
} = [ @argvcopy ];
323 # Historical: if known directories in crypto/ have been removed, it means
324 # that those sub-systems are disabled.
325 # (the other option would be to removed them from the SUBDIRS statement in
327 # We reverse the input list for cosmetic purely reasons, to compensate that
328 # 'unshift' adds at the front of the list (i.e. in reverse input order).
329 foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh',
330 'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2',
331 'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha',
332 'sm2', 'sm3', 'sm4') ) {
333 unshift @argvcopy, "no-$_" if ! -d catdir
($srcdir, 'crypto', $_);
336 # Collect version numbers
340 collect_from_file
(catfile
($srcdir,'VERSION.dat')),
341 qr/\s*(\w+)\s*=\s*(.*?)\s*$/ =>
343 # Only define it if there is a value at all
347 # Some values are quoted. Trim the quotes
348 $v = $1 if $v =~ /^"(.*)"$/;
349 $version{uc $k} = $v;
353 sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" },
356 $config{major
} = $version{MAJOR
} // 'unknown';
357 $config{minor
} = $version{MINOR
} // 'unknown';
358 $config{patch
} = $version{PATCH
} // 'unknown';
359 $config{prerelease
} =
360 defined $version{PRE_RELEASE_TAG
} ?
"-$version{PRE_RELEASE_TAG}" : '';
361 $config{build_metadata
} =
362 defined $version{BUILD_METADATA
} ?
"+$version{BUILD_METADATA}" : '';
363 $config{shlib_version
} = $version{SHLIB_VERSION
} // 'unknown';
364 $config{release_date
} = $version{RELEASE_DATE
} // 'xx XXX xxxx';
366 $config{version
} = "$config{major}.$config{minor}.$config{patch}";
367 $config{full_version
} = "$config{version}$config{prerelease}$config{build_metadata}";
369 die "erroneous version information in VERSION.dat: ",
370 "$config{version}, $config{shlib_version}\n"
371 unless (defined $version{MAJOR
}
372 && defined $version{MINOR
}
373 && defined $version{PATCH
}
374 && defined $version{SHLIB_VERSION
});
376 # Collect target configurations
378 my $pattern = catfile
(dirname
($0), "Configurations", "*.conf");
379 foreach (sort glob($pattern)) {
383 if (defined env
($local_config_envname)) {
385 # VMS environment variables are logical names,
386 # which can be used as is
387 $pattern = $local_config_envname . ':' . '*.conf';
389 $pattern = catfile
(env
($local_config_envname), '*.conf');
392 foreach (sort glob($pattern)) {
397 # Fail if no configuration is apparent
399 print "Failed to find any os/compiler configurations. Please make sure the Configurations directory is included.\n";
403 # Save away perl command information
404 $config{perl_cmd
} = $^X
;
405 $config{perl_version
} = $Config{version
};
406 $config{perl_archname
} = $Config{archname
};
409 $config{openssldir
}="";
410 $config{processor
}="";
412 my $auto_threads=1; # enable threads automatically? true by default
415 # Known TLS and DTLS protocols
416 my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
417 my @dtls = qw(dtls1 dtls1_2);
419 # Explicitly known options that are possible to disable. They can
420 # be regexps, and will be used like this: /^no-${option}$/
421 # For developers: keep it sorted alphabetically
454 "default-thread-pool",
470 "ec_nistp_64_gcc_128",
480 "fips-securitychecks",
488 "integrity-only-ciphers",
560 foreach my $proto ((@tls, @dtls))
562 push(@disablables, $proto);
563 push(@disablables, "$proto-method") unless $proto eq "tls1_3";
566 # Internal disablables, for aliasing purposes. They serve no special
567 # purpose here, but allow scripts to get to know them through configdata.pm,
568 # where these are merged with @disablables.
569 # The actual aliasing mechanism is done via %disable_cascades
570 my @disablables_int = qw(
574 my %deprecated_disablables = (
576 "buf-freelists" => undef,
577 "crypto-mdebug-backtrace" => undef,
578 "hw" => "hw", # causes cascade, but no macro
579 "hw-padlock" => "padlockeng",
580 "ripemd" => "rmd160",
581 "ui" => "ui-console",
582 "heartbeats" => undef,
585 # All of the following are disabled by default:
587 our %disabled = ( # "what" => "comment"
589 "fips-jitter" => "default",
591 "brotli" => "default",
592 "brotli-dynamic" => "default",
593 "buildtest-c++" => "default",
594 "crypto-mdebug" => "default",
595 "crypto-mdebug-backtrace" => "default",
596 "demos" => "default",
597 "h3demo" => "default",
598 "hqinterop" => "default",
599 "devcryptoeng" => "default",
600 "ec_nistp_64_gcc_128" => "default",
602 "external-tests" => "default",
603 "fuzz-afl" => "default",
604 "fuzz-libfuzzer" => "default",
606 "jitter" => "default",
613 "ssl3-method" => "default",
614 "sslkeylog" => "default",
616 "trace" => "default",
617 "ubsan" => "default",
618 "unit-test" => "default",
619 "weak-ssl-ciphers" => "default",
621 "zlib-dynamic" => "default",
623 "zstd-dynamic" => "default",
626 # Note: => pair form used for aesthetics, not to truly make a hash table
627 my @disable_cascades = (
628 # "what" => [ "cascade", ... ]
629 "bulk" => [ "shared", "dso",
630 "aria", "async", "atexit", "autoload-config",
631 "blake2", "bf", "camellia", "cast", "chacha",
632 "cmac", "cms", "cmp", "comp", "ct",
633 "des", "dgram", "dh", "dsa",
637 "md4", "ml-dsa", "ml-kem", "multiblock",
638 "nextprotoneg", "ocsp", "ocb", "poly1305", "psk",
639 "rc2", "rc4", "rmd160",
640 "seed", "siphash", "siv",
642 "srtp", "ssl3-method", "ssl-trace",
644 "ts", "ui-console", "whirlpool",
645 "fips-securitychecks" ],
646 sub { $config{processor
} eq "386" }
649 "ssl3-method" => [ "ssl3" ],
650 "zlib" => [ "zlib-dynamic" ],
651 "brotli" => [ "brotli-dynamic" ],
652 "zstd" => [ "zstd-dynamic" ],
654 "deprecated" => [ "tls-deprecated-ec" ],
655 "ec" => [ qw(ec2m ecdsa ecdh sm2 gost ecx tls-deprecated-ec) ],
656 "dgram" => [ "dtls", "quic", "sctp" ],
657 "sock" => [ "dgram", "tfo" ],
659 sub { 0 == scalar grep { !$disabled{$_} } @dtls }
663 sub { 0 == scalar grep { !$disabled{$_} } @tls }
665 "tls1_3" => [ "quic" ],
666 "quic" => [ "unstable-qlog" ],
668 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
670 "module" => [ "dynamic-engine", "fips" ],
672 # Without shared libraries, dynamic engines aren't possible.
673 # This is due to them having to link with libcrypto and register features
674 # using the ENGINE functionality, and since that relies on global tables,
675 # those *have* to be exactly the same as the ones accessed from the app,
676 # which cannot be guaranteed if shared libraries aren't present.
677 # (note that even with shared libraries, both the app and dynamic engines
678 # must be linked with the same library)
679 "shared" => [ "dynamic-engine", "uplink" ],
680 "dso" => [ "dynamic-engine", "module" ],
681 # Other modules don't necessarily have to link with libcrypto, so shared
682 # libraries do not have to be a condition to produce those.
684 # Without position independent code, there can be no shared libraries
686 "pic" => [ "shared", "module" ],
688 "engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ],
689 "dynamic-engine" => [ "loadereng" ],
690 "hw" => [ "padlockeng" ],
692 # no-autoalginit is only useful when building non-shared
693 "autoalginit" => [ "shared", "apps", "fips" ],
695 "stdio" => [ "apps", "capieng", "egd" ],
696 "apps" => [ "tests" ],
697 "tests" => [ "external-tests" ],
698 "comp" => [ "zlib", "brotli", "zstd" ],
700 sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
702 sub { !$disabled{"msan"} } => [ "asm" ],
705 "legacy" => [ "md2" ],
709 "fips" => [ "fips-securitychecks", "fips-post", "acvp-tests",
712 "threads" => [ "thread-pool" ],
713 "thread-pool" => [ "default-thread-pool" ],
715 "blake2" => [ "argon2" ],
717 "deprecated-3.0" => [ "engine", "srp" ],
722 # Avoid protocol support holes. Also disable all versions below N, if version
723 # N is disabled while N+1 is enabled.
725 my @list = (reverse @tls);
726 while ((my $first, my $second) = (shift @list, shift @list)) {
728 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
730 unshift @list, $second;
732 my @list = (reverse @dtls);
733 while ((my $first, my $second) = (shift @list, shift @list)) {
735 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
737 unshift @list, $second;
740 # Explicit "no-..." options will be collected in %disabled along with the defaults.
741 # To remove something from %disabled, use "enable-foo".
742 # For symmetry, "disable-foo" is a synonym for "no-foo".
744 # For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with
745 # platform specific list separators. Users from those platforms should
746 # recognise those separators from how you set up the PATH to find executables.
747 # The default is the Unix like separator, :, but as an exception, we also
748 # support the space as separator.
749 my $list_separator_re =
750 { VMS
=> qr/(?<!\^),/,
751 MSWin32
=> qr/(?<!\\);/ } -> {$^O
} // qr/(?<!\\)[:\s]/;
752 # All the "make variables" we support
753 # Some get pre-populated for the sake of backward compatibility
754 # (we supported those before the change to "make variable" support.
761 CFLAGS
=> [ env
('CFLAGS') || () ],
763 CXXFLAGS
=> [ env
('CXXFLAGS') || () ],
765 CPPFLAGS
=> [ env
('CPPFLAGS') || () ], # -D, -I, -Wp,
766 CPPDEFINES
=> [], # Alternative for -D
767 CPPINCLUDES
=> [], # Alternative for -I
768 CROSS_COMPILE
=> env
('CROSS_COMPILE'),
769 HASHBANGPERL
=> env
('HASHBANGPERL') || env
('PERL'),
771 LDFLAGS
=> [ env
('LDFLAGS') || () ], # -L, -Wl,
772 LDLIBS
=> [ env
('LDLIBS') || () ], # -l
775 PERL
=> env
('PERL') || ($^O
ne "VMS" ?
$^X
: "perl"),
776 RANLIB
=> env
('RANLIB'),
777 RC
=> env
('RC') || env
('WINDRES'),
778 RCFLAGS
=> [ env
('RCFLAGS') || () ],
782 # Info about what "make variables" may be prefixed with the cross compiler
783 # prefix. This should NEVER mention any such variable with a list for value.
784 my @user_crossable = qw
( AR AS CC CXX CPP LD MT RANLIB RC
);
785 # The same but for flags given as Configure options. These are *additional*
786 # input, as opposed to the VAR=string option that override the corresponding
787 # config target attributes
800 my %user_synonyms = (
801 HASHBANGPERL
=> 'PERL',
805 # Some target attributes have been renamed, this is the translation table
806 my %target_attr_translate =(
812 hashbangperl
=> 'HASHBANGPERL',
820 # Initialisers coming from 'config' scripts
821 $config{defines
} = [ split(/$list_separator_re/, env
('__CNF_CPPDEFINES')) ];
822 $config{includes
} = [ split(/$list_separator_re/, env
('__CNF_CPPINCLUDES')) ];
823 $config{cppflags
} = [ env
('__CNF_CPPFLAGS') || () ];
824 $config{cflags
} = [ env
('__CNF_CFLAGS') || () ];
825 $config{cxxflags
} = [ env
('__CNF_CXXFLAGS') || () ];
826 $config{lflags
} = [ env
('__CNF_LDFLAGS') || () ];
827 $config{ex_libs
} = [ env
('__CNF_LDLIBS') || () ];
829 $config{openssl_api_defines
}=[];
830 $config{openssl_sys_defines
}=[];
831 $config{openssl_feature_defines
}=[];
833 $config{build_type
} = "release";
836 my %cmdvars = (); # Stores FOO='blah' type arguments
837 my %unsupported_options = ();
838 my %deprecated_options = ();
839 # If you change this, update apps/version.c
840 my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu);
841 my @seed_sources = ();
844 $_ = shift @argvcopy;
846 # Support env variable assignments among the options
847 if (m
|^(\w
+)=(.+)?
$|)
850 # Every time a variable is given as a configuration argument,
851 # it acts as a reset if the variable.
852 if (exists $user{$1})
854 $user{$1} = ref $user{$1} eq "ARRAY" ?
[] : undef;
856 #if (exists $useradd{$1})
863 # VMS is a case insensitive environment, and depending on settings
864 # out of our control, we may receive options uppercased. Let's
865 # downcase at least the part before any equal sign.
871 # some people just can't read the instructions, clang people have to...
872 s/^-no-(?!integrated-as)/no-/;
874 # rewrite some options in "enable-..." form
875 s
/^-?-?shared$/enable
-shared
/;
876 s
/^sctp$/enable
-sctp
/;
877 s
/^threads$/enable
-threads
/;
878 s
/^zlib$/enable
-zlib
/;
879 s
/^zlib-dynamic$/enable
-zlib
-dynamic
/;
880 s
/^fips$/enable
-fips
/;
882 if (/^(no|disable|enable)-(.+)$/)
885 if ($word !~ m
|hw
(?
:-.+)| # special treatment for hw regexp opt
886 && !exists $deprecated_disablables{$word}
887 && !grep { $word eq $_ } @disablables)
889 $unsupported_options{$_} = 1;
893 if (/^no-(.+)$/ || /^disable-(.+)$/)
895 foreach my $proto ((@tls, @dtls))
897 if ($1 eq "$proto-method")
899 $disabled{"$proto"} = "option($proto-method)";
905 foreach my $proto (@dtls)
907 $disabled{$proto} = "option(dtls)";
909 $disabled{"dtls"} = "option(dtls)";
913 # Last one of its kind
914 $disabled{"ssl3"} = "option(ssl)";
918 # XXX: Tests will fail if all SSL/TLS
919 # protocols are disabled.
920 foreach my $proto (@tls)
922 $disabled{$proto} = "option(tls)";
925 elsif ($1 eq "static-engine")
927 delete $disabled{"dynamic-engine"};
929 elsif ($1 eq "dynamic-engine")
931 $disabled{"dynamic-engine"} = "option";
933 elsif (exists $deprecated_disablables{$1})
935 $deprecated_options{$_} = 1;
936 if (defined $deprecated_disablables{$1})
938 $disabled{$deprecated_disablables{$1}} = "option";
941 elsif ($1 =~ m
|hw
(?
:-.+)|) # deprecate hw options in regexp form
943 $deprecated_options{$_} = 1;
947 $disabled{$1} = "option";
949 # No longer an automatic choice
950 $auto_threads = 0 if ($1 eq "threads");
952 elsif (/^enable-(.+)$/)
954 if ($1 eq "static-engine")
956 $disabled{"dynamic-engine"} = "option";
958 elsif ($1 eq "dynamic-engine")
960 delete $disabled{"dynamic-engine"};
962 elsif ($1 eq "zlib-dynamic")
964 delete $disabled{"zlib"};
966 elsif ($1 eq "brotli-dynamic")
968 delete $disabled{"brotli"};
972 delete $disabled{"pie"};
974 elsif ($1 eq "zstd-dynamic")
976 delete $disabled{"zstd"};
978 elsif ($1 eq "fips-jitter")
980 delete $disabled{"fips"};
981 delete $disabled{"jitter"};
984 delete $disabled{$algo};
986 # No longer an automatic choice
987 $auto_threads = 0 if ($1 eq "threads");
989 elsif (/^-d$/) # From older 'config'
991 $config{build_type
} = "debug";
993 elsif (/^-v$/) # From older 'config'
995 $guess_opts{verbose
} = 1;
999 $guess_opts{nowait
} = 1;
1001 elsif (/^-t$/) # From older 'config'
1005 elsif (/^--strict-warnings$/)
1007 # Pretend that our strict flags is a C flag, and replace it
1008 # with the proper flags later on
1009 push @
{$useradd{CFLAGS
}}, '--ossl-strict-warnings';
1014 $config{build_type
} = "debug";
1016 elsif (/^--release$/)
1018 $config{build_type
} = "release";
1022 $config{build_type
} = "pgo";
1025 { $config{processor
}=386; }
1028 # No RSAref support any more since it's not needed.
1029 # The check for the option is there so scripts aren't
1034 if (/^--prefix=(.*)$/)
1038 elsif (/^--api=(.*)$/)
1041 die "Unknown API compatibility level $api"
1042 unless defined $apitable->{$api};
1043 $config{api
}=$apitable->{$api};
1045 elsif (/^--libdir=(.*)$/)
1049 elsif (/^--openssldir=(.*)$/)
1051 $config{openssldir
}=$1;
1053 elsif (/^--with-jitter-include=(.*)$/)
1055 $withargs{jitter_include
}=$1;
1057 elsif (/^--with-jitter-lib=(.*)$/)
1059 $withargs{jitter_lib
}=$1;
1061 elsif (/^--with-zlib-lib=(.*)$/)
1063 $withargs{zlib_lib
}=$1;
1065 elsif (/^--with-zlib-include=(.*)$/)
1067 $withargs{zlib_include
}=$1;
1069 elsif (/^--with-brotli-lib=(.*)$/)
1071 $withargs{brotli_lib
}=$1;
1073 elsif (/^--with-brotli-include=(.*)$/)
1075 $withargs{brotli_include
}=$1;
1077 elsif (/^--with-zstd-lib=(.*)$/)
1079 $withargs{zstd_lib
}=$1;
1081 elsif (/^--with-zstd-include=(.*)$/)
1083 $withargs{zstd_include
}=$1;
1085 elsif (/^--with-fuzzer-lib=(.*)$/)
1087 $withargs{fuzzer_lib
}=$1;
1089 elsif (/^--with-fuzzer-include=(.*)$/)
1091 $withargs{fuzzer_include
}=$1;
1093 elsif (/^--with-rand-seed=(.*)$/)
1095 foreach my $x (split(m
|,|, $1))
1097 die "Unknown --with-rand-seed choice $x\n"
1098 if ! grep { $x eq $_ } @known_seed_sources;
1099 push @seed_sources, $x;
1102 elsif (/^--fips-key=(.*)$/)
1104 $user{FIPSKEY
}=lc($1);
1105 die "Non-hex character in FIPS key\n"
1106 if $user{FIPSKEY
} =~ /[^a-f0-9]/;
1107 die "FIPS key must have even number of characters\n"
1109 die "FIPS key too long (64 bytes max)\n"
1112 elsif (/^--banner=(.*)$/)
1114 $banner = $1 . "\n";
1116 elsif (/^--cross-compile-prefix=(.*)$/)
1118 $user{CROSS_COMPILE
}=$1;
1120 elsif (/^--config=(.*)$/)
1126 push @
{$useradd{LDLIBS
}}, $_;
1128 elsif (/^-framework$/)
1130 push @
{$useradd{LDLIBS
}}, $_, shift(@argvcopy);
1132 elsif (/^-L(.*)$/ or /^-Wl,/)
1134 push @
{$useradd{LDFLAGS
}}, $_;
1136 elsif (/^-rpath$/ or /^-R$/)
1137 # -rpath is the OSF1 rpath flag
1138 # -R is the old Solaris rpath flag
1140 my $rpath = shift(@argvcopy) || "";
1141 $rpath .= " " if $rpath ne "";
1142 push @
{$useradd{LDFLAGS
}}, $_, $rpath;
1146 push @
{$useradd{LDFLAGS
}}, $_;
1148 elsif (m
|^[-/]D
(.*)$|)
1150 push @
{$useradd{CPPDEFINES
}}, $1;
1152 elsif (m
|^[-/]I
(.*)$|)
1154 push @
{$useradd{CPPINCLUDES
}}, $1;
1158 push @
{$useradd{CPPFLAGS
}}, $1;
1160 else # common if (/^[-+]/), just pass down...
1162 # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1163 # This provides a simple way to pass options with arguments separated
1164 # by spaces without quoting (e.g. -opt%20arg translates to -opt arg).
1165 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1166 push @
{$useradd{CFLAGS
}}, $_;
1167 push @
{$useradd{CXXFLAGS
}}, $_;
1172 # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1173 # This provides a simple way to pass options with arguments separated
1174 # by spaces without quoting (e.g. /opt%20arg translates to /opt arg).
1175 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1176 push @
{$useradd{CFLAGS
}}, $_;
1177 push @
{$useradd{CXXFLAGS
}}, $_;
1181 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
1184 unless ($_ eq $target || /^no-/ || /^disable-/)
1186 # "no-..." follows later after implied deactivations
1187 # have been derived. (Don't take this too seriously,
1188 # we really only write OPTIONS to the Makefile out of
1191 if ($config{options
} eq "")
1192 { $config{options
} = $_; }
1194 { $config{options
} .= " ".$_; }
1198 if (keys %deprecated_options)
1200 warn "***** Deprecated options: ",
1201 join(", ", keys %deprecated_options), "\n";
1203 if (keys %unsupported_options)
1205 die "***** Unsupported options: ",
1206 join(", ", keys %unsupported_options), "\n";
1209 # If any %useradd entry has been set, we must check that the "make
1210 # variables" haven't been set. We start by checking of any %useradd entry
1212 if (grep { scalar @
$_ > 0 } values %useradd) {
1213 # Hash of env / make variables names. The possible values are:
1215 # 2 - %useradd entry set
1219 $v += 1 if $cmdvars{$_};
1220 $v += 2 if @
{$useradd{$_}};
1224 # If any of the corresponding "make variables" is set, we error
1225 if (grep { $_ & 1 } values %detected_vars) {
1226 my $names = join(', ', grep { $detected_vars{$_} > 0 }
1227 sort keys %detected_vars);
1229 ***** Mixing make variables
and additional compiler
/linker flags as
1230 ***** configure command line option is
not permitted
.
1231 ***** Affected make variables
: $names
1236 # Check through all supported command line variables to see if any of them
1237 # were set, and canonicalise the values we got. If no compiler or linker
1238 # flag or anything else that affects %useradd was set, we also check the
1239 # environment for values.
1241 grep { defined $_ && (ref $_ ne 'ARRAY' || @
$_) } values %useradd;
1242 foreach (keys %user) {
1243 my $value = $cmdvars{$_};
1244 $value //= env
($_) unless $anyuseradd;
1246 defined $user_synonyms{$_} ?
$cmdvars{$user_synonyms{$_}} : undef;
1247 $value //= defined $user_synonyms{$_} ? env
($user_synonyms{$_}) : undef
1250 if (defined $value) {
1251 if (ref $user{$_} eq 'ARRAY') {
1252 if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') {
1253 $user{$_} = [ split /$list_separator_re/, $value ];
1255 $user{$_} = [ $value ];
1257 } elsif (!defined $user{$_}) {
1263 if (grep { /-rpath\b/ } ($user{LDFLAGS
} ? @
{$user{LDFLAGS
}} : ())
1264 && !$disabled{shared
}
1265 && !($disabled{asan
} && $disabled{msan
} && $disabled{ubsan
})) {
1266 die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
1267 "***** any of asan, msan or ubsan\n";
1270 # If no target was given, try guessing.
1272 my %system_config = OpenSSL
::config
::get_platform
(%guess_opts, %user);
1274 # The $system_config{disable} is used to populate %disabled with
1275 # entries that aren't already there.
1276 foreach ( @
{$system_config{disable
} // []} ) {
1277 $disabled{$_} = 'system' unless defined $disabled{$_};
1279 delete $system_config{disable
};
1281 # Override config entries with stuff from the guesser.
1282 # It's assumed that this really is nothing new.
1283 %config = ( %config, %system_config );
1284 $target = $system_config{target
};
1288 my $disable_type = shift;
1291 $disabled{$_} = $disable_type;
1294 my @tocheckfor = (@_ ?
@_ : keys %disabled);
1295 while (@tocheckfor) {
1296 my %new_tocheckfor = ();
1297 my @cascade_copy = (@disable_cascades);
1298 while (@cascade_copy) {
1299 my ($test, $descendents) =
1300 (shift @cascade_copy, shift @cascade_copy);
1301 if (ref($test) eq "CODE" ?
$test->() : defined($disabled{$test})) {
1302 foreach (grep { !defined($disabled{$_}) } @
$descendents) {
1303 $new_tocheckfor{$_} = 1; $disabled{$_} = "cascade";
1307 @tocheckfor = (keys %new_tocheckfor);
1310 disable
(); # First cascade run
1312 our $die = sub { die @_; };
1313 if ($target eq "TABLE") {
1314 local $die = sub { warn @_; };
1315 foreach (sort keys %table) {
1316 print_table_entry
($_, "TABLE");
1321 if ($target eq "LIST") {
1322 foreach (sort keys %table) {
1323 print $_,"\n" unless $table{$_}->{template
};
1328 if ($target eq "HASH") {
1329 local $die = sub { warn @_; };
1330 print "%table = (\n";
1331 foreach (sort keys %table) {
1332 print_table_entry
($_, "HASH");
1337 print "Configuring OpenSSL version $config{full_version} ";
1338 print "for target $target\n";
1340 if (scalar(@seed_sources) == 0) {
1341 print "Using os-specific seed configuration\n";
1342 push @seed_sources, 'os';
1344 if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) {
1345 delete $disabled{'egd'};
1347 if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
1348 die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
1349 warn <<_____
if scalar(@seed_sources) == 1;
1351 ============================== WARNING
===============================
1352 You have selected the
--with
-rand-seed
=none option
, which effectively
1353 disables automatic reseeding of the OpenSSL SEED
-SRC random generator
.
1354 All operations depending on the random generator such as creating
keys
1355 will
not work
unless the random generator is seeded manually by the
1358 Instead of manually seeding
, a different random generator can be set
1359 at runtime
in openssl
.cnf
or configured at build
time with
1360 -DOPENSSL_DEFAULT_SEED_SRC
.
1362 Please
read the
'Note on random number generation' section
in the
1363 INSTALL
.md instructions
and the RAND_DRBG
(7) manual page
for more
1365 ============================== WARNING
===============================
1369 push @
{$config{openssl_feature_defines
}},
1370 map { (my $x = $_) =~ tr
|[\
-a
-z
]|[_A
-Z
]|; "OPENSSL_RAND_SEED_$x" }
1373 my $provider_string = $disabled{"fips-post"} ?
"non-compliant FIPS Provider" : "FIPS Provider";
1375 $config{FIPS_VENDOR
} =
1376 (defined $version{FIPS_VENDOR
} ?
"$version{FIPS_VENDOR} $provider_string for OpenSSL" : "OpenSSL $provider_string");
1378 # Backward compatibility?
1379 if ($target =~ m/^CygWin32(-.*)$/) {
1380 $target = "Cygwin".$1;
1383 # Support for legacy targets having a name starting with 'debug-'
1384 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
1386 $config{build_type
} = "debug";
1388 # If we do not find debug-foo in the table, the target is set to foo.
1389 if (!$table{$target}) {
1395 # It's possible that we have different config targets for specific
1396 # toolchains, so we try to detect them, and go for the plain config
1399 foreach ( ( "$target-$user{CC}", "$target", undef ) ) {
1400 $found=$_ if $table{$_} && !$table{$_}->{template
};
1405 # If we don't have a config target now, we try the C compiler as we
1407 my $cc = $user{CC
} // 'cc';
1408 $target = $cc if $table{$cc} && !$table{$cc}->{template
};
1411 &usage
unless $target;
1413 exit 0 if $dryrun; # From older 'config'
1415 $config{target
} = $target;
1416 my %target = resolve_config
($target);
1418 foreach (keys %target_attr_translate) {
1419 $target{$target_attr_translate{$_}} = $target{$_}
1424 %target = ( %{$table{DEFAULTS
}}, %target );
1426 my %conf_files = map { $_ => 1 } (@
{$target{_conf_fname_int
}});
1427 $config{conf_files
} = [ sort keys %conf_files ];
1429 # Using sub disable within these loops may prove fragile, so we run
1430 # a cascade afterwards
1431 foreach my $feature (@
{$target{disable
}}) {
1432 if (exists $deprecated_disablables{$feature}) {
1433 warn "***** config $target disables deprecated feature $feature\n";
1434 } elsif (!grep { $feature eq $_ } @disablables) {
1435 die "***** config $target disables unknown feature $feature\n";
1437 $disabled{$feature} = 'config';
1439 foreach my $feature (@
{$target{enable
}}) {
1440 if ("default" eq ($disabled{$feature} // "")) {
1441 if (exists $deprecated_disablables{$feature}) {
1442 warn "***** config $target enables deprecated feature $feature\n";
1443 } elsif (!grep { $feature eq $_ } @disablables) {
1444 die "***** config $target enables unknown feature $feature\n";
1446 delete $disabled{$feature};
1450 # If uplink_arch isn't defined, disable uplink
1451 $disabled{uplink
} = 'no uplink_arch' unless (defined $target{uplink_arch
});
1452 # If asm_arch isn't defined, disable asm
1453 $disabled{asm
} = 'no asm_arch' unless (defined $target{asm_arch
});
1455 disable
(); # Run a cascade now
1457 $target{CXXFLAGS
}//=$target{CFLAGS
} if $target{CXX
};
1458 $target{cxxflags
}//=$target{cflags
} if $target{CXX
};
1459 $target{exe_extension
}=".exe" if ($config{target
} eq "DJGPP");
1460 $target{exe_extension
}=".pm" if ($config{target
} =~ /vos/);
1462 # Fill %config with values from %user, and in case those are undefined or
1463 # empty, use values from %target (acting as a default).
1464 foreach (keys %user) {
1465 my $ref_type = ref $user{$_};
1467 # Temporary function. Takes an intended ref type (empty string or "ARRAY")
1468 # and a value that's to be coerced into that type.
1472 my $undef_p = shift;
1474 die "Too many arguments for \$mkvalue" if @_;
1476 while (ref $value eq 'CODE') {
1477 $value = $value->();
1480 if ($type eq 'ARRAY') {
1481 return undef unless defined $value;
1482 return undef if ref $value ne 'ARRAY' && !$value;
1483 return undef if ref $value eq 'ARRAY' && !@
$value;
1484 return [ $value ] unless ref $value eq 'ARRAY';
1486 return undef unless $value;
1491 $mkvalue->($ref_type, $user{$_})
1492 || $mkvalue->($ref_type, $target{$_});
1493 delete $config{$_} unless defined $config{$_};
1496 # Finish up %config by appending things the user gave us on the command line
1497 # apart from "make variables"
1498 foreach (keys %useradd) {
1499 # The must all be lists, so we assert that here
1500 die "internal error: \$useradd{$_} isn't an ARRAY\n"
1501 unless ref $useradd{$_} eq 'ARRAY';
1503 if (defined $config{$_}) {
1504 push @
{$config{$_}}, @
{$useradd{$_}};
1506 $config{$_} = [ @
{$useradd{$_}} ];
1509 # At this point, we can forget everything about %user and %useradd,
1510 # because it's now all been merged into the corresponding $config entry
1512 if ($config{prefix
} && !$config{CROSS_COMPILE
}) {
1513 die "Directory given with --prefix MUST be absolute\n"
1514 unless file_name_is_absolute
($config{prefix
});
1517 if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @
{$config{LDFLAGS
}}) {
1518 disable
('static', 'pic', 'threads');
1521 # Allow overriding the build file name
1522 $config{build_file
} = env
('BUILDFILE') || $target{build_file
} || "Makefile";
1524 # Make sure build_scheme is consistent.
1525 $target{build_scheme
} = [ $target{build_scheme
} ]
1526 if ref($target{build_scheme
}) ne "ARRAY";
1528 my ($builder, $builder_platform, @builder_opts) =
1529 @
{$target{build_scheme
}};
1531 foreach my $checker (($builder_platform."-".$config{build_file
}."-checker.pm",
1532 $builder_platform."-checker.pm")) {
1533 my $checker_path = catfile
($srcdir, "Configurations", $checker);
1534 if (-f
$checker_path) {
1535 my $fn = $ENV{CONFIGURE_CHECKER_WARN
}
1536 ?
sub { warn $@
; } : sub { die $@
; };
1537 if (! do $checker_path) {
1543 $fn->("The detected tools didn't match the platform\n");
1550 push @
{$config{defines
}}, "NDEBUG" if $config{build_type
} eq "release";
1552 if ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m)
1554 push @
{$config{cflags
}}, "-mno-cygwin";
1555 push @
{$config{cxxflags
}}, "-mno-cygwin" if $config{CXX
};
1556 push @
{$config{shared_ldflag
}}, "-mno-cygwin";
1559 if ($target =~ /linux.*-mips/ && !$disabled{asm
}
1560 && !grep { $_ =~ /-m(ips|arch=)/ } (@
{$config{CFLAGS
}})) {
1561 # minimally required architecture flags for assembly modules
1563 $value = '-mips2' if ($target =~ /mips32/);
1564 $value = '-mips3' if ($target =~ /mips64/);
1565 unshift @
{$config{cflags
}}, $value;
1566 unshift @
{$config{cxxflags
}}, $value if $config{CXX
};
1569 # If threads aren't disabled, check how possible they are
1570 unless ($disabled{threads
}) {
1571 if ($auto_threads) {
1572 # Enabled by default, disable it forcibly if unavailable
1573 if ($target{thread_scheme
} eq "(unknown)") {
1574 disable
("unavailable", 'threads');
1577 # The user chose to enable threads explicitly, let's see
1578 # if there's a chance that's possible
1579 if ($target{thread_scheme
} eq "(unknown)") {
1580 # If the user asked for "threads" and we don't have internal
1581 # knowledge how to do it, [s]he is expected to provide any
1582 # system-dependent compiler options that are necessary. We
1583 # can't truly check that the given options are correct, but
1584 # we expect the user to know what [s]He is doing.
1585 if (!@
{$config{CFLAGS
}} && !@
{$config{CPPDEFINES
}}) {
1586 die "You asked for multi-threading support, but didn't\n"
1587 ,"provide any system-specific compiler options\n";
1593 # Find out if clang's sanitizers have been enabled with -fsanitize
1594 # flags and ensure that the corresponding %disabled elements area
1595 # removed to reflect that the sanitizers are indeed enabled.
1596 my %detected_sanitizers = ();
1597 foreach (grep /^-fsanitize=/, @
{$config{CFLAGS
} || []}) {
1598 (my $checks = $_) =~ s/^-fsanitize=//;
1599 foreach (split /,/, $checks) {
1600 my $d = { address
=> 'asan',
1601 undefined
=> 'ubsan',
1602 memory
=> 'msan' } -> {$_};
1603 next unless defined $d;
1605 $detected_sanitizers{$d} = 1;
1606 if (defined $disabled{$d}) {
1607 die "***** Conflict between disabling $d and enabling $_ sanitizer"
1608 if $disabled{$d} ne "default";
1609 delete $disabled{$d};
1614 # If threads still aren't disabled, add a C macro to ensure the source
1615 # code knows about it. Any other flag is taken care of by the configs.
1616 unless($disabled{threads
}) {
1617 push @
{$config{openssl_feature_defines
}}, "OPENSSL_THREADS";
1620 if ($disabled{"unstable-qlog"}) {
1621 $disabled{"qlog"} = 1;
1624 my $no_shared_warn=0;
1625 if (($target{shared_target
} // '') eq "")
1628 if (!$disabled{shared
} || !$disabled{"dynamic-engine"});
1629 disable
('no-shared-target', 'pic');
1632 if ($disabled{"dynamic-engine"}) {
1633 $config{dynamic_engines
} = 0;
1635 $config{dynamic_engines
} = 1;
1638 unless ($disabled{asan
} || defined $detected_sanitizers{asan
}) {
1639 push @
{$config{cflags
}}, "-fsanitize=address";
1642 unless ($disabled{ubsan
} || defined $detected_sanitizers{ubsan
}) {
1643 push @
{$config{cflags
}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC";
1646 unless ($disabled{msan
} || defined $detected_sanitizers{msan
}) {
1647 push @
{$config{cflags
}}, "-fsanitize=memory";
1650 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1651 && $disabled{asan
} && $disabled{ubsan
} && $disabled{msan
}) {
1652 push @
{$config{cflags
}}, "-fno-omit-frame-pointer", "-g";
1653 push @
{$config{cxxflags
}}, "-fno-omit-frame-pointer", "-g" if $config{CXX
};
1659 # This saves the build files from having to check
1662 foreach (qw(shared_cflag shared_cxxflag shared_cppflag
1663 shared_defines shared_includes shared_ldflag
1664 module_cflags module_cxxflags module_cppflags
1665 module_defines module_includes module_lflags))
1673 push @
{$config{lib_defines
}}, "OPENSSL_PIC";
1676 if ($target{sys_id
} ne "")
1678 push @
{$config{openssl_sys_defines
}}, "OPENSSL_SYS_$target{sys_id}";
1681 my %predefined_C = compiler_predefined
($config{CROSS_COMPILE
}.$config{CC
});
1682 my %predefined_CXX = $config{CXX
}
1683 ? compiler_predefined
($config{CROSS_COMPILE
}.$config{CXX
})
1686 unless ($disabled{asm
}) {
1687 # big endian systems can use ELFv2 ABI
1688 if ($target eq "linux-ppc64" || $target eq "BSD-ppc64") {
1689 $target{perlasm_scheme
} = "linux64v2" if ($predefined_C{_CALL_ELF
} == 2);
1693 # Check for makedepend capabilities.
1694 if (!$disabled{makedepend
}) {
1695 # If the attribute makedep_scheme is defined, then we assume that the
1696 # config target and its associated build file are programmed to deal
1698 # If makedep_scheme is undefined, we go looking for GCC compatible
1699 # dependency making, and if that's not available, we try to fall back
1701 if ($target{makedep_scheme
}) {
1702 $config{makedep_scheme
} = $target{makedep_scheme
};
1703 # If the makedepcmd attribute is defined, copy it. If not, the
1704 # build files will have to fend for themselves.
1705 $config{makedepcmd
} = $target{makedepcmd
} if $target{makedepcmd
};
1706 } elsif (($predefined_C{__GNUC__
} // -1) >= 3
1707 && !($predefined_C{__APPLE_CC__
} && !$predefined_C{__clang__
})) {
1708 # We know that GNU C version 3 and up as well as all clang
1709 # versions support dependency generation, but Xcode did not
1710 # handle $cc -M before clang support (but claims __GNUC__ = 3)
1711 $config{makedep_scheme
} = 'gcc';
1713 # In all other cases, we look for 'makedepend', and set the
1714 # makedep_scheme value if we found it.
1715 $config{makedepcmd
} = which
('makedepend');
1716 $config{makedep_scheme
} = 'makedepend' if $config{makedepcmd
};
1719 # If no depend scheme is set, we disable makedepend
1720 disable
('unavailable', 'makedepend') unless $config{makedep_scheme
};
1723 if (!$disabled{asm
} && !$predefined_C{__MACH__
} && $^O
ne 'VMS' && !$predefined_C{_AIX
}) {
1724 # probe for -Wa,--noexecstack option...
1725 if ($predefined_C{__clang__
}) {
1726 # clang has builtin assembler, which doesn't recognize --help,
1727 # but it apparently recognizes the option in question on all
1728 # supported platforms even when it's meaningless. In other words
1729 # probe would fail, but probed option always accepted...
1730 push @
{$config{cflags
}}, "-Wa,--noexecstack", "-Qunused-arguments";
1732 my $cc = $config{CROSS_COMPILE
}.$config{CC
};
1733 open(PIPE
, "$cc -Wa,--help -c -o null.$$.o -x assembler /dev/null 2>&1 |");
1735 if (m/--noexecstack/) {
1736 push @
{$config{cflags
}}, "-Wa,--noexecstack";
1741 unlink("null.$$.o");
1745 # Deal with bn_ops ###################################################
1748 my $def_int="unsigned int";
1749 $config{rc4_int
} =$def_int;
1750 ($config{b64l
},$config{b64
},$config{b32
})=(0,0,1);
1753 foreach (sort split(/\s+/,$target{bn_ops
})) {
1754 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1755 $config{bn_ll
}=1 if $_ eq 'BN_LLONG';
1756 $config{rc4_int
}="unsigned char" if $_ eq 'RC4_CHAR';
1757 ($config{b64l
},$config{b64
},$config{b32
})
1758 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
1759 ($config{b64l
},$config{b64
},$config{b32
})
1760 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
1761 ($config{b64l
},$config{b64
},$config{b32
})
1762 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
1764 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1767 $config{api
} = $config{major
} * 10000 + $config{minor
} * 100
1768 unless $config{api
};
1769 foreach (keys %$apitable) {
1770 $disabled{"deprecated-$_"} = "deprecation"
1771 if $disabled{deprecated
} && $config{api
} >= $apitable->{$_};
1774 disable
(); # Run a cascade now
1776 # Hack cflags for better warnings (dev option) #######################
1778 # "Stringify" the C and C++ flags string. This permits it to be made part of
1779 # a string and works as well on command lines.
1780 $config{cflags
} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1781 @
{$config{cflags
}} ];
1782 $config{cxxflags
} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1783 @
{$config{cxxflags
}} ] if $config{CXX
};
1785 $config{openssl_api_defines
} = [
1786 "OPENSSL_CONFIGURED_API=".$config{api
},
1789 my @strict_warnings_collection=();
1790 if ($strict_warnings)
1793 my $gccver = $predefined_C{__GNUC__
} // -1;
1797 push @strict_warnings_collection, @gcc_devteam_warn;
1798 push @strict_warnings_collection, @clang_devteam_warn
1799 if (defined($predefined_C{__clang__
}));
1801 elsif ($config{target
} =~ /^VC-/)
1803 push @strict_warnings_collection, @cl_devteam_warn;
1807 warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC"
1811 $config{CFLAGS
} = [ map { $_ eq '--ossl-strict-warnings'
1812 ?
@strict_warnings_collection
1814 @
{$config{CFLAGS
}} ];
1816 unless ($disabled{afalgeng
}) {
1817 $config{afalgeng
}="";
1818 if (grep { $_ eq 'afalgeng' } @
{$target{enable
}}) {
1819 push @
{$config{engdirs
}}, "afalg";
1821 disable
('not-linux', 'afalgeng');
1825 unless ($disabled{devcryptoeng
}) {
1826 if ($target =~ m/^BSD/) {
1827 my $maxver = 5*100 + 7;
1828 my $sysstr = `uname -s`;
1829 my $verstr = `uname -r`;
1832 my ($ma, $mi, @rest) = split m
|\
.|, $verstr;
1833 my $ver = $ma*100 + $mi;
1834 if ($sysstr eq 'OpenBSD' && $ver >= $maxver) {
1835 disable
('too-new-kernel', 'devcryptoeng');
1840 unless ($disabled{ktls
}) {
1842 my $cc = $config{CROSS_COMPILE
}.$config{CC
};
1843 if ($target =~ m/^linux/) {
1844 system("printf '#include <sys/types.h>\n#include <linux/tls.h>' | $cc -E - >/dev/null 2>&1");
1846 disable
('too-old-kernel', 'ktls');
1848 } elsif ($target =~ m/^BSD/) {
1849 system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1");
1851 disable
('too-old-freebsd', 'ktls');
1854 disable
('not-linux-or-freebsd', 'ktls');
1858 unless ($disabled{winstore
}) {
1859 unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) {
1860 disable
('not-windows', 'winstore');
1864 push @
{$config{openssl_other_defines
}}, "OPENSSL_NO_KTLS" if ($disabled{ktls
});
1866 # Get the extra flags used when building shared libraries and modules. We
1867 # do this late because some of them depend on %disabled.
1869 # Make the flags to build DSOs the same as for shared libraries unless they
1870 # are already defined
1871 $target{module_cflags
} = $target{shared_cflag
} unless defined $target{module_cflags
};
1872 $target{module_cxxflags
} = $target{shared_cxxflag
} unless defined $target{module_cxxflags
};
1873 $target{module_ldflags
} = $target{shared_ldflag
} unless defined $target{module_ldflags
};
1875 my $shared_info_pl =
1876 catfile
(dirname
($0), "Configurations", "shared-info.pl");
1877 my %shared_info = read_eval_file
($shared_info_pl);
1878 push @
{$target{_conf_fname_int
}}, $shared_info_pl;
1879 my $si = $target{shared_target
};
1880 while (ref $si ne "HASH") {
1881 last if ! defined $si;
1882 if (ref $si eq "CODE") {
1885 $si = $shared_info{$si};
1889 # Some of the 'shared_target' values don't have any entries in
1890 # %shared_info. That's perfectly fine, AS LONG AS the build file
1891 # template knows how to handle this. That is currently the case for
1894 # Just as above, copy certain shared_* attributes to the corresponding
1895 # module_ attribute unless the latter is already defined
1896 $si->{module_cflags
} = $si->{shared_cflag
} unless defined $si->{module_cflags
};
1897 $si->{module_cxxflags
} = $si->{shared_cxxflag
} unless defined $si->{module_cxxflags
};
1898 $si->{module_ldflags
} = $si->{shared_ldflag
} unless defined $si->{module_ldflags
};
1899 foreach (sort keys %$si) {
1900 $target{$_} = defined $target{$_}
1901 ? add
($si->{$_})->($target{$_})
1907 # ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON
1909 ######################################################################
1910 # Build up information for skipping certain directories depending on disabled
1911 # features, as well as setting up macros for disabled features.
1913 # This is a tentative database of directories to skip. Some entries may not
1914 # correspond to anything real, but that's ok, they will simply be ignored.
1915 # The actual processing of these entries is done in the build.info lookup
1916 # loop further down.
1918 # The key is a Unix formatted path in the source tree, the value is an index
1919 # into %disabled_info, so any existing path gets added to a corresponding
1920 # 'skipped' entry in there with the list of skipped directories.
1922 my %disabled_info = (); # For configdata.pm
1923 foreach my $what (sort keys %disabled) {
1924 # There are deprecated disablables that translate to themselves.
1925 # They cause disabling cascades, but should otherwise not register.
1926 next if $deprecated_disablables{$what};
1927 # The generated $disabled{"deprecated-x.y"} entries are special
1928 # and treated properly elsewhere
1929 next if $what =~ m
|^deprecated
-|;
1931 $config{options
} .= " no-$what";
1933 if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
1934 'module', 'pic', 'dynamic-engine', 'makedepend',
1935 'sse2', 'legacy' )) {
1936 (my $WHAT = uc $what) =~ s
|-|_
|g
;
1937 my $skipdir = $what;
1939 # fix-up crypto/directory name(s)
1940 $skipdir = "ripemd" if $what eq "rmd160";
1941 $skipdir = "whrlpool" if $what eq "whirlpool";
1943 my $macro = $disabled_info{$what}->{macro
} = "OPENSSL_NO_$WHAT";
1944 push @
{$config{openssl_feature_defines
}}, $macro;
1946 $skipdir{engines
} = $what if $what eq 'engine';
1947 $skipdir{"crypto/$skipdir"} = $what
1948 unless $what eq 'async' || $what eq 'err' || $what eq 'dso' || $what eq 'http';
1952 if ($disabled{"dynamic-engine"}) {
1953 push @
{$config{openssl_feature_defines
}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1955 push @
{$config{openssl_feature_defines
}}, "OPENSSL_NO_STATIC_ENGINE";
1958 # If we use the unified build, collect information from build.info files
1959 my %unified_info = ();
1961 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO
});
1962 if ($builder eq "unified") {
1963 use Text
::Template
1.46;
1968 my $relativeto = shift || ".";
1969 my $no_mkpath = shift // 0;
1971 $dir = catdir
($base,$dir) unless isabsolute
($dir);
1973 # Make sure the directories we're building in exists
1974 mkpath
($dir) unless $no_mkpath;
1976 my $res = abs2rel
(absolutedir
($dir), rel2abs
($relativeto));
1977 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1984 my $relativeto = shift || ".";
1985 my $no_mkpath = shift // 0;
1987 $file = catfile
($base,$file) unless isabsolute
($file);
1989 my $d = dirname
($file);
1990 my $f = basename
($file);
1992 # Make sure the directories we're building in exists
1993 mkpath
($d) unless $no_mkpath;
1995 my $res = abs2rel
(catfile
(absolutedir
($d), $f), rel2abs
($relativeto));
1996 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
2000 # Store the name of the template file we will build the build file from
2001 # in %config. This may be useful for the build file itself.
2002 my @build_file_template_names =
2003 ( $builder_platform."-".$config{build_file
}.".tmpl",
2004 $config{build_file
}.".tmpl" );
2005 my @build_file_templates = ();
2007 # First, look in the user provided directory, if given
2008 if (defined env
($local_config_envname)) {
2009 @build_file_templates =
2012 # VMS environment variables are logical names,
2013 # which can be used as is
2014 $local_config_envname . ':' . $_;
2016 catfile
(env
($local_config_envname), $_);
2019 @build_file_template_names;
2021 # Then, look in our standard directory
2022 push @build_file_templates,
2023 ( map { cleanfile
($srcdir, catfile
("Configurations", $_), $blddir, 1) }
2024 @build_file_template_names );
2026 my $build_file_template;
2027 for $_ (@build_file_templates) {
2028 $build_file_template = $_;
2029 last if -f
$build_file_template;
2031 $build_file_template = undef;
2033 if (!defined $build_file_template) {
2034 die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
2036 $config{build_file_templates
}
2037 = [ cleanfile
($srcdir, catfile
("Configurations", "common0.tmpl"),
2039 $build_file_template ];
2041 my @build_dirs = ( [ ] ); # current directory
2043 $config{build_infos
} = [ ];
2045 # We want to detect configdata.pm in the source tree, so we
2046 # don't use it if the build tree is different.
2047 my $src_configdata = cleanfile
($srcdir, "configdata.pm", $blddir, 1);
2049 # Any source file that we recognise is placed in this hash table, with
2050 # the list of its intended destinations as value. When everything has
2051 # been collected, there's a routine that checks that these source files
2052 # exist, or if they are generated, that the generator exists.
2053 my %check_exist = ();
2054 my %check_generate = ();
2057 while (@build_dirs) {
2058 my @curd = @
{shift @build_dirs};
2059 my $sourced = catdir
($srcdir, @curd);
2060 my $buildd = catdir
($blddir, @curd);
2062 my $unixdir = join('/', @curd);
2063 if (exists $skipdir{$unixdir}) {
2064 my $what = $skipdir{$unixdir};
2065 push @
{$disabled_info{$what}->{skipped
}}, catdir
(@curd);
2071 my $f = 'build.info';
2072 # The basic things we're trying to build
2079 my %shared_sources = ();
2088 # Support for $variablename in build.info files.
2089 # Embedded perl code is the ultimate master, still. If its output
2090 # contains a dollar sign, it had better be escaped, or it will be
2091 # taken for a variable name prefix.
2093 # Variable name syntax
2094 my $variable_name_re = qr/(?P<VARIABLE>[[:alpha:]][[:alnum:]_]*)/;
2095 # Value modifier syntaxes
2096 my $variable_subst_re = qr/\/(?P
<RE
>(?
:\\\
/|.)*?)\/(?P
<SUBST
>.*?
)/;
2097 # Variable reference
2098 my $variable_simple_re = qr/(?<!\\)\$${variable_name_re}/;
2099 my $variable_w_mod_re =
2100 qr/(?<!\\)\$\{${variable_name_re}(?P<MOD>(?:\\\/|.)*?
)\
}/;
2101 # Tie it all together
2102 my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/;
2104 my $expand_variables = sub {
2106 my $value_rest = shift;
2108 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND
}) {
2110 "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n"
2113 while ($value_rest =~ /${variable_re}/) {
2114 # We must save important regexp values, because the next
2115 # regexp clears them
2117 my $variable_value = $variables{$+{VARIABLE
}};
2122 # Process modifier expressions, if present
2124 if ($mod =~ /^${variable_subst_re}$/) {
2126 my $subst = $+{SUBST};
2128 $variable_value =~ s/\Q$re\E/$subst/g;
2130 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2132 "DEBUG[\$expand_variables] ... and substituted ",
2133 "'$re' with '$subst'\n";
2138 $value .= $variable_value;
2140 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2142 "DEBUG[\$expand_variables] ... into: '$value$value_rest'\n";
2144 return $value . $value_rest;
2147 # Support for attributes in build.info files
2148 my %attributes = ();
2149 my $handle_attributes = sub {
2150 my $attr_str = shift;
2154 return unless defined $attr_str;
2156 my @a = tokenize($attr_str, qr|\s*,\s*|);
2157 foreach my $a (@a) {
2161 if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) {
2166 foreach my $g (@goals) {
2168 $$ref->{$g}->{$ak} = $av;
2170 delete $$ref->{$g}->{$ak};
2176 # Support for pushing values on multiple indexes of a given hash
2179 my $valueref = shift;
2180 my $index_str = shift; # May be undef or empty
2181 my $attrref = shift; # May be undef
2182 my $attr_str = shift;
2185 if (defined $index_str) {
2186 my @indexes = ( '' );
2187 if ($index_str !~ m|^\s*$|) {
2188 @indexes = tokenize($index_str);
2190 foreach (@indexes) {
2191 push @{$valueref->{$_}}, @values;
2192 if (defined $attrref) {
2193 $handle_attributes->($attr_str, \$$attrref->{$_},
2198 push @$valueref, @values;
2199 $handle_attributes->($attr_str, $attrref, @values)
2200 if defined $attrref;
2204 if ($buildinfo_debug) {
2205 print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n";
2207 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
2209 Text::Template->new(TYPE => 'FILE
',
2210 SOURCE => catfile($sourced, $f),
2211 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
2212 die "Something went wrong with $sourced/$f: $!\n" unless $template;
2215 $template->fill_in(HASH => { config => \%config,
2217 disabled => \%disabled,
2218 withargs => \%withargs,
2219 builddir => abs2rel($buildd, $blddir),
2220 sourcedir => abs2rel($sourced, $blddir),
2221 buildtop => abs2rel($blddir, $blddir),
2222 sourcetop => abs2rel($srcdir, $blddir) },
2223 DELIMITERS => [ "{-", "-}" ]);
2225 # The top item of this stack has the following values
2226 # -2 positive already run and we found ELSE (following ELSIF should fail)
2227 # -1 positive already run (skip until ENDIF)
2228 # 0 negatives so far (if we're at a condition
, check it
)
2229 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
2230 # 2 positive ELSE (following ELSIF should fail)
2233 # A few useful generic regexps
2234 my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/;
2235 my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/;
2236 my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/;
2237 my $value_re = qr/(?P<VALUE>.*?)/;
2238 collect_information
(
2239 collect_from_array
([ @text ],
2240 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
2241 $l1 =~ s/\\$//; $l1.$l2 }),
2242 # Info we're looking for
2243 qr/^\s* IF ${cond_re} \s*$/x
2245 if (! @skip || $skip[$#skip] > 0) {
2246 push @skip, !! $expand_variables->($+{COND
});
2251 qr/^\s* ELSIF ${cond_re} \s*$/x
2252 => sub { die "ELSIF out of scope" if ! @skip;
2253 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
2254 $skip[$#skip] = -1 if $skip[$#skip] != 0;
2255 $skip[$#skip] = !! $expand_variables->($+{COND
})
2256 if $skip[$#skip] == 0; },
2258 => sub { die "ELSE out of scope" if ! @skip;
2259 $skip[$#skip] = -2 if $skip[$#skip] != 0;
2260 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
2261 qr/^\s* ENDIF \s*$/x
2262 => sub { die "ENDIF out of scope" if ! @skip;
2264 qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x
2266 if (!@skip || $skip[$#skip] > 0) {
2267 $variables{$+{VARIABLE
}} = $expand_variables->($+{VALUE
});
2270 qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x
2272 if (!@skip || $skip[$#skip] > 0) {
2273 foreach (tokenize
($expand_variables->($+{VALUE
}))) {
2274 push @build_dirs, [ @curd, splitdir
($_, 1) ];
2278 qr/^\s* PROGRAMS ${attribs_re} \s* = \s* ${value_re} \s* $/x
2279 => sub { $push_to->(\
@programs, undef,
2280 \
$attributes{programs
}, $+{ATTRIBS
},
2281 tokenize
($expand_variables->($+{VALUE
})))
2282 if !@skip || $skip[$#skip] > 0; },
2283 qr/^\s* LIBS ${attribs_re} \s* = \s* ${value_re} \s* $/x
2284 => sub { $push_to->(\
@libraries, undef,
2285 \
$attributes{libraries
}, $+{ATTRIBS
},
2286 tokenize
($expand_variables->($+{VALUE
})))
2287 if !@skip || $skip[$#skip] > 0; },
2288 qr/^\s* MODULES ${attribs_re} \s* = \s* ${value_re} \s* $/x
2289 => sub { $push_to->(\
@modules, undef,
2290 \
$attributes{modules
}, $+{ATTRIBS
},
2291 tokenize
($expand_variables->($+{VALUE
})))
2292 if !@skip || $skip[$#skip] > 0; },
2293 qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x
2294 => sub { $push_to->(\
@scripts, undef,
2295 \
$attributes{scripts
}, $+{ATTRIBS
},
2296 tokenize
($expand_variables->($+{VALUE
})))
2297 if !@skip || $skip[$#skip] > 0; },
2298 qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2299 => sub { $push_to->(\
%imagedocs, $expand_variables->($+{INDEX
}),
2301 tokenize
($expand_variables->($+{VALUE
})))
2302 if !@skip || $skip[$#skip] > 0; },
2303 qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2304 => sub { $push_to->(\
%htmldocs, $expand_variables->($+{INDEX
}),
2306 tokenize
($expand_variables->($+{VALUE
})))
2307 if !@skip || $skip[$#skip] > 0; },
2308 qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2309 => sub { $push_to->(\
%mandocs, $expand_variables->($+{INDEX
}),
2311 tokenize
($expand_variables->($+{VALUE
})))
2312 if !@skip || $skip[$#skip] > 0; },
2313 qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2314 => sub { $push_to->(\
%sources, $expand_variables->($+{INDEX
}),
2315 \
$attributes{sources
}, $+{ATTRIBS
},
2316 tokenize
($expand_variables->($+{VALUE
})))
2317 if !@skip || $skip[$#skip] > 0; },
2318 qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2319 => sub { $push_to->(\
%shared_sources, $expand_variables->($+{INDEX
}),
2320 \
$attributes{sources
}, $+{ATTRIBS
},
2321 tokenize
($expand_variables->($+{VALUE
})))
2322 if !@skip || $skip[$#skip] > 0; },
2323 qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x
2324 => sub { $push_to->(\
%includes, $expand_variables->($+{INDEX
}),
2326 tokenize
($expand_variables->($+{VALUE
})))
2327 if !@skip || $skip[$#skip] > 0; },
2328 qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x
2329 => sub { $push_to->(\
%defines, $expand_variables->($+{INDEX
}),
2331 tokenize
($expand_variables->($+{VALUE
})))
2332 if !@skip || $skip[$#skip] > 0; },
2333 qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2334 => sub { $push_to->(\
%depends, $expand_variables->($+{INDEX
}),
2335 \
$attributes{depends
}, $+{ATTRIBS
},
2336 tokenize
($expand_variables->($+{VALUE
})))
2337 if !@skip || $skip[$#skip] > 0; },
2338 qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2339 => sub { $push_to->(\
%generate, $expand_variables->($+{INDEX
}),
2340 \
$attributes{generate
}, $+{ATTRIBS
},
2341 $expand_variables->($+{VALUE
}))
2342 if !@skip || $skip[$#skip] > 0; },
2343 qr/^\s* (?:\#.*)? $/x => sub { },
2344 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
2346 if ($buildinfo_debug) {
2347 print STDERR
"DEBUG: Parsing ",join(" ", @_),"\n";
2348 print STDERR
"DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2352 if ($buildinfo_debug) {
2353 print STDERR
"DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2357 die "runaway IF?" if (@skip);
2359 if (grep { defined $attributes{modules
}->{$_}->{engine
} } keys %attributes
2360 and !$config{dynamic_engines
}) {
2362 ENGINES can only be used if configured with 'dynamic-engine'.
2363 This is usually a fault in a build.info file.
2368 my %infos = ( programs
=> [ @programs ],
2369 libraries
=> [ @libraries ],
2370 modules
=> [ @modules ],
2371 scripts
=> [ @scripts ] );
2372 foreach my $k (keys %infos) {
2373 foreach (@
{$infos{$k}}) {
2374 my $item = cleanfile
($buildd, $_, $blddir);
2375 $unified_info{$k}->{$item} = 1;
2377 # Fix up associated attributes
2378 $unified_info{attributes
}->{$k}->{$item} =
2379 $attributes{$k}->{$_}
2380 if defined $attributes{$k}->{$_};
2385 # Check that we haven't defined any library as both shared and
2386 # explicitly static. That is forbidden.
2388 foreach (grep /\.a$/, keys %{$unified_info{libraries
}}) {
2389 (my $l = $_) =~ s/\.a$//;
2390 push @doubles, $l if defined $unified_info{libraries
}->{$l};
2392 die "these libraries are both explicitly static and shared:\n ",
2393 join(" ", @doubles), "\n"
2396 foreach (keys %sources) {
2398 my $ddest = cleanfile
($buildd, $_, $blddir);
2399 foreach (@
{$sources{$dest}}) {
2400 my $s = cleanfile
($sourced, $_, $blddir, 1);
2402 # If it's generated or we simply don't find it in the source
2403 # tree, we assume it's in the build tree.
2404 if ($s eq $src_configdata || $generate{$_} || ! -f
$s) {
2405 $s = cleanfile
($buildd, $_, $blddir);
2408 # We recognise C++, C and asm files
2409 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
2410 push @
{$check_exist{$s}}, $ddest;
2411 $o =~ s/\.[csS]$/.o/; # C and assembler
2412 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2413 $o = cleanfile
($buildd, $o, $blddir);
2414 $unified_info{sources
}->{$ddest}->{$o} = -1;
2415 $unified_info{sources
}->{$o}->{$s} = -1;
2416 } elsif ($s =~ /\.rc$/) {
2417 # We also recognise resource files
2418 push @
{$check_exist{$s}}, $ddest;
2419 $o =~ s/\.rc$/.res/; # Resource configuration
2420 $o = cleanfile
($buildd, $o, $blddir);
2421 $unified_info{sources
}->{$ddest}->{$o} = -1;
2422 $unified_info{sources
}->{$o}->{$s} = -1;
2424 push @
{$check_exist{$s}}, $ddest;
2425 $unified_info{sources
}->{$ddest}->{$s} = 1;
2427 # Fix up associated attributes
2429 $unified_info{attributes
}->{sources
}->{$ddest}->{$o} =
2430 $unified_info{attributes
}->{sources
}->{$o}->{$s} =
2431 $attributes{sources
}->{$dest}->{$_}
2432 if defined $attributes{sources
}->{$dest}->{$_};
2434 $unified_info{attributes
}->{sources
}->{$ddest}->{$s} =
2435 $attributes{sources
}->{$dest}->{$_}
2436 if defined $attributes{sources
}->{$dest}->{$_};
2441 foreach (keys %shared_sources) {
2443 my $ddest = cleanfile
($buildd, $_, $blddir);
2444 foreach (@
{$shared_sources{$dest}}) {
2445 my $s = cleanfile
($sourced, $_, $blddir, 1);
2447 # If it's generated or we simply don't find it in the source
2448 # tree, we assume it's in the build tree.
2449 if ($s eq $src_configdata || $generate{$_} || ! -f
$s) {
2450 $s = cleanfile
($buildd, $_, $blddir);
2454 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
2455 # We recognise C++, C and asm files
2456 push @
{$check_exist{$s}}, $ddest;
2457 $o =~ s/\.[csS]$/.o/; # C and assembler
2458 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2459 $o = cleanfile
($buildd, $o, $blddir);
2460 $unified_info{shared_sources
}->{$ddest}->{$o} = -1;
2461 $unified_info{sources
}->{$o}->{$s} = -1;
2462 } elsif ($s =~ /\.rc$/) {
2463 # We also recognise resource files
2464 push @
{$check_exist{$s}}, $ddest;
2465 $o =~ s/\.rc$/.res/; # Resource configuration
2466 $o = cleanfile
($buildd, $o, $blddir);
2467 $unified_info{shared_sources
}->{$ddest}->{$o} = -1;
2468 $unified_info{sources
}->{$o}->{$s} = -1;
2469 } elsif ($s =~ /\.ld$/) {
2470 # We also recognise linker scripts (or corresponding)
2471 # We know they are generated files
2472 push @
{$check_exist{$s}}, $ddest;
2473 $o = cleanfile
($buildd, $_, $blddir);
2474 $unified_info{shared_sources
}->{$ddest}->{$o} = 1;
2476 die "unrecognised source file type for shared library: $s\n";
2478 # Fix up associated attributes
2480 $unified_info{attributes
}->{shared_sources
}->{$ddest}->{$o} =
2481 $unified_info{attributes
}->{sources
}->{$o}->{$s} =
2482 $attributes{sources
}->{$dest}->{$_}
2483 if defined $attributes{sources
}->{$dest}->{$_};
2485 $unified_info{attributes
}->{shared_sources
}->{$ddest}->{$o} =
2486 $attributes{sources
}->{$dest}->{$_}
2487 if defined $attributes{sources
}->{$dest}->{$_};
2492 foreach (keys %generate) {
2494 my $ddest = cleanfile
($buildd, $_, $blddir);
2495 die "more than one generator for $dest: "
2496 ,join(" ", @
{$generate{$_}}),"\n"
2497 if scalar @
{$generate{$_}} > 1;
2498 my @generator = split /\s+/, $generate{$dest}->[0];
2499 my $gen = $generator[0];
2500 $generator[0] = cleanfile
($sourced, $gen, $blddir, 1);
2502 # If the generator is itself generated, it's in the build tree
2503 if ($generate{$gen} || ! -f
$generator[0]) {
2504 $generator[0] = cleanfile
($buildd, $gen, $blddir);
2506 $check_generate{$ddest}->{$generator[0]}++;
2508 $unified_info{generate
}->{$ddest} = [ @generator ];
2509 # Fix up associated attributes
2510 $unified_info{attributes
}->{generate
}->{$ddest} =
2511 $attributes{generate
}->{$dest}->{$gen}
2512 if defined $attributes{generate
}->{$dest}->{$gen};
2515 foreach (keys %depends) {
2519 if ($dest =~ /^\|(.*)\|$/) {
2520 # Collect the raw target
2521 $unified_info{targets
}->{$1} = 1;
2523 } elsif ($dest eq '') {
2526 $ddest = cleanfile
($sourced, $dest, $blddir, 1);
2528 # If the destination doesn't exist in source, it can only be
2529 # a generated file in the build tree.
2530 if ($ddest eq $src_configdata || ! -f
$ddest) {
2531 $ddest = cleanfile
($buildd, $dest, $blddir);
2534 foreach my $f (@
{$depends{$dest}}) {
2535 # If the dependency destination is generated, dependencies
2536 # may have an extra syntax to separate the intended inclusion
2537 # directory from the module to be loaded: a | instead of a
2538 # / as directory separator.
2539 # Do note that this has to be handled in the build file
2541 # $i = inclusion path in source directory
2542 # $i2 = inclusion path in build directory
2543 # $m = module path (within the inclusion path)
2544 # $i = full module path in source directory
2545 # $i2 = full module path in build directory
2546 my $i; my $i2; my $m; my $d; my $d2;
2547 if ($unified_info{generate
}->{$ddest}
2548 && $f =~ m/^(.*?)\|(.*)$/) {
2551 # We must be very careful to modify $i last
2552 $d = cleanfile
($sourced, "$i/$m", $blddir, 1);
2553 $d2 = cleanfile
($buildd, "$i/$m", $blddir);
2554 $i2 = cleandir
($buildd, $i, $blddir);
2555 $i = cleandir
($sourced, $i, $blddir, 1);
2557 $d = cleanfile
($sourced, $f, $blddir, 1);
2558 $d2 = cleanfile
($buildd, $f, $blddir);
2561 # If we know it's generated, or assume it is because we can't
2562 # find it in the source tree, we set file we depend on to be
2563 # in the build tree rather than the source tree.
2564 if ($d eq $src_configdata
2565 || (grep { $d2 eq $_ }
2566 keys %{$unified_info{generate
}})
2572 # Put together the computed inclusion dir with the
2573 # original module name. Do note that we conserve the
2574 # Unixly path syntax for the module path.
2577 $unified_info{depends
}->{$ddest}->{$d} = 1;
2579 # Fix up associated attributes
2580 $unified_info{attributes
}->{depends
}->{$ddest}->{$d} =
2581 $attributes{depends
}->{$dest}->{$f}
2582 if defined $attributes{depends
}->{$dest}->{$f};
2586 foreach (keys %includes) {
2588 my $ddest = cleanfile
($sourced, $_, $blddir, 1);
2590 # If the destination doesn't exist in source, it can only be
2591 # a generated file in the build tree.
2592 if ($ddest eq $src_configdata || ! -f
$ddest) {
2593 $ddest = cleanfile
($buildd, $_, $blddir);
2595 foreach (@
{$includes{$dest}}) {
2596 my $is = cleandir
($sourced, $_, $blddir, 1);
2597 my $ib = cleandir
($buildd, $_, $blddir);
2598 push @
{$unified_info{includes
}->{$ddest}->{source
}}, $is
2599 unless grep { $_ eq $is } @
{$unified_info{includes
}->{$ddest}->{source
}};
2600 push @
{$unified_info{includes
}->{$ddest}->{build
}}, $ib
2601 unless grep { $_ eq $ib } @
{$unified_info{includes
}->{$ddest}->{build
}};
2605 foreach my $dest (keys %defines) {
2609 $ddest = cleanfile
($sourced, $dest, $blddir, 1);
2611 # If the destination doesn't exist in source, it can only
2612 # be a generated file in the build tree.
2614 $ddest = cleanfile
($buildd, $dest, $blddir);
2617 foreach my $v (@
{$defines{$dest}}) {
2618 $v =~ m
|^([^=]*)(=.*)?
$|;
2619 die "0 length macro name not permitted\n" if $1 eq "";
2621 die "$1 defined more than once\n"
2622 if defined $unified_info{defines
}->{$ddest}->{$1};
2623 $unified_info{defines
}->{$ddest}->{$1} = $2;
2625 die "$1 defined more than once\n"
2626 if grep { $v eq $_ } @
{$config{defines
}};
2627 push @
{$config{defines
}}, $v;
2632 foreach my $section (keys %imagedocs) {
2633 foreach (@
{$imagedocs{$section}}) {
2634 my $imagedocs = cleanfile
($buildd, $_, $blddir);
2635 $unified_info{imagedocs
}->{$section}->{$imagedocs} = 1;
2639 foreach my $section (keys %htmldocs) {
2640 foreach (@
{$htmldocs{$section}}) {
2641 my $htmldocs = cleanfile
($buildd, $_, $blddir);
2642 $unified_info{htmldocs
}->{$section}->{$htmldocs} = 1;
2646 foreach my $section (keys %mandocs) {
2647 foreach (@
{$mandocs{$section}}) {
2648 my $mandocs = cleanfile
($buildd, $_, $blddir);
2649 $unified_info{mandocs
}->{$section}->{$mandocs} = 1;
2654 my $ordinals_text = join(', ', sort keys %ordinals);
2655 warn <<"EOF" if $ordinals_text;
2657 WARNING: ORDINALS were specified for $ordinals_text
2658 They are ignored and should be replaced with a combination of GENERATE,
2659 DEPEND and SHARED_SOURCE.
2662 # Check that each generated file is only generated once
2663 my $ambiguous_generation = 0;
2664 foreach (sort keys %check_generate) {
2665 my @generators = sort keys %{$check_generate{$_}};
2666 my $generators_txt = join(', ', @generators);
2667 if (scalar @generators > 1) {
2668 warn "$_ is GENERATEd by more than one generator ($generators_txt)\n";
2669 $ambiguous_generation++;
2671 if ($check_generate{$_}->{$generators[0]} > 1) {
2672 warn "INFO: $_ has more than one GENERATE declaration (same generator)\n"
2675 die "There are ambiguous source file generations\n"
2676 if $ambiguous_generation > 0;
2678 # All given source files should exist, or if generated, their
2679 # generator should exist. This loop ensures this is true.
2681 foreach my $orig (sort keys %check_exist) {
2682 foreach my $dest (@
{$check_exist{$orig}}) {
2683 if ($orig ne $src_configdata) {
2684 if ($orig =~ /\.a$/) {
2685 # Static library names may be used as sources, so we
2686 # need to detect those and give them special treatment.
2687 unless (grep { $_ eq $orig }
2688 keys %{$unified_info{libraries
}}) {
2689 warn "$orig is given as source for $dest, but no such library is built\n";
2693 # A source may be generated, and its generator may be
2694 # generated as well. We therefore loop to dig out the
2698 while (my @next = keys %{$check_generate{$gen}}) {
2703 if ($gen ne $orig) {
2705 warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n";
2708 warn "$orig is given as source for $dest, but is missing\n";
2715 die "There are files missing\n" if $missing > 0;
2717 # Go through the sources of all libraries and check that the same basename
2718 # doesn't appear more than once. Some static library archivers depend on
2719 # them being unique.
2722 foreach my $prod (keys %{$unified_info{libraries
}}) {
2724 map { keys %{$unified_info{sources
}->{$_}} }
2725 keys %{$unified_info{sources
}->{$prod}};
2728 # Count how many times a given each source basename
2729 # appears for each product.
2730 foreach my $src (@prod_sources) {
2731 $srccnt{basename
$src}++;
2734 foreach my $src (keys %srccnt) {
2735 if ((my $cnt = $srccnt{$src}) > 1) {
2736 print STDERR
"$src appears $cnt times for the product $prod\n";
2744 # Massage the result
2746 # If we depend on a header file or a perl module, add an inclusion of
2747 # its directory to allow smoothe inclusion
2748 foreach my $dest (keys %{$unified_info{depends
}}) {
2749 next if $dest eq "";
2750 foreach my $d (keys %{$unified_info{depends
}->{$dest}}) {
2751 next unless $d =~ /\.(h|pm)$/;
2752 # Take into account when a dependency uses the inclusion|module
2754 my $i = $d =~ m/\|/ ?
$` : dirname($d);
2756 $d eq "configdata.pm" || defined($unified_info{generate}->{$d})
2757 ? 'build' : 'source';
2758 push @{$unified_info{includes}->{$dest}->{$spot}}, $i
2759 unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{$spot}};
2763 # Go through all intermediary files and change their names to something that
2764 # reflects what they will be built for. Note that for some source files,
2765 # this leads to duplicate object files because they are used multiple times.
2766 # the goal is to rename all object files according to this scheme:
2767 # {productname}-{midfix}-{origobjname}.[o|res]
2768 # the {midfix} is a keyword indicating the type of product, which is mostly
2769 # valuable for libraries since they come in two forms.
2771 # This also reorganises the {sources} and {shared_sources} so that the
2772 # former only contains ALL object files that are supposed to end up in
2773 # static libraries and programs, while the latter contains ALL object files
2774 # that are supposed to end up in shared libraries and DSOs.
2775 # The main reason for having two different source structures is to allow
2776 # the same name to be used for the static and the shared variants of a
2779 # Take copies so we don't get interference from added stuff
2780 my %unified_copy = ();
2781 foreach (('sources', 'shared_sources')) {
2782 $unified_copy{$_} = { %{$unified_info{$_}} }
2783 if defined($unified_info{$_});
2784 delete $unified_info{$_};
2786 foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) {
2787 # $intent serves multi purposes:
2788 # - give a prefix for the new object files names
2789 # - in the case of libraries, rearrange the object files so static
2790 # libraries use the 'sources' structure exclusively, while shared
2791 # libraries use the 'shared_sources' structure exclusively.
2793 programs => { bin => { src => [ 'sources' ],
2794 dst => 'sources' } },
2795 libraries => { lib => { src => [ 'sources' ],
2797 shlib => { prodselect =>
2798 sub { grep !/\.a$/, @_ },
2801 dst => 'shared_sources' } },
2802 modules => { dso => { src => [ 'sources' ],
2803 dst => 'sources' } },
2804 scripts => { script => { src => [ 'sources' ],
2805 dst => 'sources' } }
2807 foreach my $kind (keys %$intent) {
2808 next if ($intent->{$kind}->{dst} eq 'shared_sources'
2809 && $disabled{shared});
2811 my @src = @{$intent->{$kind}->{src}};
2812 my $dst = $intent->{$kind}->{dst};
2813 my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ };
2814 foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) {
2815 # %prod_sources has all applicable objects as keys, and
2816 # their corresponding sources as values
2818 map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] }
2819 map { keys %{$unified_copy{$_}->{$prod}} }
2821 foreach (keys %prod_sources) {
2822 # Only affect object files and resource files,
2823 # the others simply get a new value
2824 # (+1 instead of -1)
2825 if ($_ =~ /\.(o|res)$/) {
2826 (my $prodname = $prod) =~ s|\.a$||;
2828 catfile(dirname($_),
2831 . '-' . basename($_));
2832 $unified_info{$dst}->{$prod}->{$newobj} = 1;
2833 foreach my $src (@{$prod_sources{$_}}) {
2834 $unified_info{sources}->{$newobj}->{$src} = 1;
2835 # Adjust source attributes
2836 my $attrs = $unified_info{attributes}->{sources};
2837 if (defined $attrs->{$prod}
2838 && defined $attrs->{$prod}->{$_}) {
2839 $attrs->{$prod}->{$newobj} =
2840 $attrs->{$prod}->{$_};
2841 delete $attrs->{$prod}->{$_};
2843 foreach my $objsrc (keys %{$attrs->{$_} // {}}) {
2844 $attrs->{$newobj}->{$objsrc} =
2845 $attrs->{$_}->{$objsrc};
2846 delete $attrs->{$_}->{$objsrc};
2849 # Adjust dependencies
2850 foreach my $deps (keys %{$unified_info{depends}->{$_}}) {
2851 $unified_info{depends}->{$_}->{$deps} = -1;
2852 $unified_info{depends}->{$newobj}->{$deps} = 1;
2855 foreach my $k (('source', 'build')) {
2857 defined($unified_info{includes}->{$_}->{$k});
2858 my @incs = @{$unified_info{includes}->{$_}->{$k}};
2859 $unified_info{includes}->{$newobj}->{$k} = [ @incs ];
2862 $unified_info{$dst}->{$prod}->{$_} = 1;
2870 # At this point, we have a number of sources with the value -1. They
2871 # aren't part of the local build and are probably meant for a different
2872 # platform, and can therefore be cleaned away. That happens when making
2873 # %unified_info more efficient below.
2875 ### Make unified_info a bit more efficient
2876 # One level structures
2877 foreach (("programs", "libraries", "modules", "scripts", "targets")) {
2878 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
2880 # Two level structures
2881 foreach my $l1 (("sources", "shared_sources", "ldadd", "depends",
2882 "imagedocs", "htmldocs", "mandocs")) {
2883 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
2886 grep { $unified_info{$l1}->{$l2}->{$_} > 0 }
2887 keys %{$unified_info{$l1}->{$l2}};
2889 $unified_info{$l1}->{$l2} = [ @items ];
2891 delete $unified_info{$l1}->{$l2};
2896 foreach my $dest (sort keys %{$unified_info{defines}}) {
2897 $unified_info{defines}->{$dest}
2898 = [ map { $_.$unified_info{defines}->{$dest}->{$_} }
2899 sort keys %{$unified_info{defines}->{$dest}} ];
2902 foreach my $dest (sort keys %{$unified_info{includes}}) {
2903 if (defined($unified_info{includes}->{$dest}->{build})) {
2904 my @source_includes = ();
2905 @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} )
2906 if defined($unified_info{includes}->{$dest}->{source});
2907 $unified_info{includes}->{$dest} =
2908 [ @{$unified_info{includes}->{$dest}->{build}} ];
2909 foreach my $inc (@source_includes) {
2910 push @{$unified_info{includes}->{$dest}}, $inc
2911 unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
2913 } elsif (defined($unified_info{includes}->{$dest}->{source})) {
2914 $unified_info{includes}->{$dest} =
2915 [ @{$unified_info{includes}->{$dest}->{source}} ];
2917 delete $unified_info{includes}->{$dest};
2921 # For convenience collect information regarding directories where
2922 # files are generated, those generated files and the end product
2923 # they end up in where applicable. Then, add build rules for those
2925 my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ],
2926 "dso" => [ @{$unified_info{modules}} ],
2927 "bin" => [ @{$unified_info{programs}} ],
2928 "script" => [ @{$unified_info{scripts}} ],
2929 "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} }
2930 keys %{$unified_info{imagedocs} // {}}),
2931 (map { @{$unified_info{htmldocs}->{$_} // []} }
2932 keys %{$unified_info{htmldocs} // {}}),
2933 (map { @{$unified_info{mandocs}->{$_} // []} }
2934 keys %{$unified_info{mandocs} // {}}) ] );
2935 foreach my $type (sort keys %loopinfo) {
2936 foreach my $product (@{$loopinfo{$type}}) {
2938 my $pd = dirname($product);
2940 foreach (@{$unified_info{sources}->{$product} // []},
2941 @{$unified_info{shared_sources}->{$product} // []}) {
2942 my $d = dirname($_);
2944 # We don't want to create targets for source directories
2945 # when building out of source
2946 next if ($config{sourcedir} ne $config{builddir}
2947 && $d =~ m|^\Q$config{sourcedir}\E|);
2948 # We already have a "test" target, and the current directory
2949 # is just silly to make a target for
2950 next if $d eq "test" || $d eq ".";
2953 push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
2956 foreach (sort keys %dirs) {
2957 push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
2964 # For the schemes that need it, we provide the old *_obj configs
2965 # from the *_asm_obj ones
2966 foreach (grep /_(asm|aux)_src$/, keys %target) {
2968 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
2969 $target{$obj} = $target{$src};
2970 $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
2971 $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
2974 # Write down our configuration where it fits #########################
2976 my %template_vars = (
2979 disablables => \@disablables,
2980 disablables_int => \@disablables_int,
2981 disabled => \%disabled,
2982 withargs => \%withargs,
2983 unified_info => \%unified_info,
2986 makevars => [ sort keys %user ],
2987 disabled_info => \%disabled_info,
2988 user_crossable => \@user_crossable,
2990 my $configdata_outname = 'configdata.pm';
2991 open CONFIGDATA, ">$configdata_outname.new"
2992 or die "Trying to create $configdata_outname.new: $!";
2993 my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir, 1);
2994 my $configdata_tmpl =
2995 OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname);
2996 $configdata_tmpl->fill_in(
2997 FILENAME => $configdata_tmplname,
2998 OUTPUT => \*CONFIGDATA,
2999 HASH => { %template_vars,
3001 'WARNING: do not edit!',
3002 "Generated by Configure from $configdata_tmplname",
3004 ) or die $Text::Template::ERROR;
3007 rename "$configdata_outname.new", $configdata_outname;
3008 if ($builder_platform eq 'unix') {
3009 my $mode = (0755 & ~umask);
3010 chmod $mode, 'configdata.pm'
3011 or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!);
3013 print "Created $configdata_outname\n";
3015 print "Running $configdata_outname\n";
3016 my $perlcmd = (quotify("maybeshell", $config{PERL}))[0];
3017 my $cmd = "$perlcmd $configdata_outname";
3018 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
3022 $SIG{__DIE__} = $orig_death_handler;
3024 print <<"EOF" if ($disabled{threads} eq "unavailable");
3026 The library could not be configured for supporting multi-threaded
3027 applications as the compiler options required on this system are not known.
3028 See file INSTALL.md for details if you need multi-threading.
3031 print <<"EOF" if ($no_shared_warn);
3033 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
3034 platform, so we will pretend you gave the option 'no-pic', which also disables
3035 'shared' and 'dynamic-engine'. If you know how to implement shared libraries
3036 or position independent code, please let us know (but please first make sure
3037 you have tried with a current version of OpenSSL).
3044 ######################################################################
3046 # Helpers and utility functions
3049 # Death handler, to print a helpful message in case of failure #######
3052 die @_ if $^S
; # To prevent the added message in eval blocks
3053 my $build_file = $config{build_file
} // "build file";
3054 my @message = ( <<"_____", @_ );
3056 Failure
! $build_file wasn
't produced.
3057 Please read INSTALL.md and associated NOTES-* files. You may also have to
3058 look over your available compiler tool chain or change your configuration.
3062 # Dying is terminal, so it's ok to
reset the signal handler here
.
3063 $SIG{__DIE__
} = $orig_death_handler;
3067 # Configuration file reading #########################################
3069 # Note: All of the helper functions are for lazy evaluation. They all
3070 # return a CODE ref, which will return the intended value when evaluated.
3071 # Thus, whenever there's mention of a returned value, it's about that
3074 # Helper function to implement conditional value variants, with a default
3075 # plus additional values based on the value of $config{build_type}.
3076 # Arguments are given in hash table form:
3078 # picker(default => "Basic string: ",
3080 # release => "release")
3082 # When configuring with --debug, the resulting string will be
3083 # "Basic string: debug", and when not, it will be "Basic string: release"
3085 # This can be used to create variants of sets of flags according to the
3088 # cflags => picker(default => "-Wall",
3089 # debug => "-g -O0",
3094 return sub { add
($opts{default} || (),
3095 $opts{$config{build_type
}} || ())->(); }
3098 # Helper function to combine several values of different types into one.
3099 # This is useful if you want to combine a string with the result of a
3100 # lazy function, such as:
3102 # cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
3106 return sub { add
(@stuff)->(); }
3109 # Helper function to implement conditional values depending on the value
3110 # of $disabled{threads}. Can be used as follows:
3112 # cflags => combine("-Wall", threads("-pthread"))
3116 return sub { add
($disabled{threads
} ?
() : @flags)->(); }
3121 return sub { add
($disabled{shared
} ?
() : @flags)->(); }
3124 our $add_called = 0;
3125 # Helper function to implement adding values to already existing configuration
3126 # values. It handles elements that are ARRAYs, CODEs and scalars
3128 my $separator = shift;
3130 # If there's any ARRAY in the collection of values OR the separator
3131 # is undef, we will return an ARRAY of combined values, otherwise a
3132 # string of joined values with $separator as the separator.
3133 my $found_array = !defined($separator);
3138 while (ref($res) eq "CODE") {
3141 if (defined($res)) {
3142 if (ref($res) eq "ARRAY") {
3158 join($separator, grep { defined($_) && $_ ne "" } @values);
3162 my $separator = " ";
3163 if (ref($_[$#_]) eq "HASH") {
3165 $separator = $opts->{separator
};
3168 sub { _add
($separator, @x, @_) };
3171 my $separator = " ";
3172 if (ref($_[$#_]) eq "HASH") {
3174 $separator = $opts->{separator
};
3177 sub { _add
($separator, @_, @x) };
3180 sub read_eval_file
{
3185 open F
, "< $fname" or die "Can't open '$fname': $!\n";
3194 @result = ( eval $content );
3197 return wantarray ?
@result : $result[0];
3200 # configuration reader, evaluates the input file as a perl script and expects
3201 # it to fill %targets with target configurations. Those are then added to
3208 # Protect certain tables from tampering
3211 %targets = read_eval_file
($fname);
3213 my %preexisting = ();
3214 foreach (sort keys %targets) {
3215 $preexisting{$_} = 1 if $table{$_};
3218 The following config targets from $fname
3219 shadow pre-existing config targets with the same name:
3221 map { " $_\n" } sort keys %preexisting
3225 # For each target, check that it's configured with a hash table.
3226 foreach (keys %targets) {
3227 if (ref($targets{$_}) ne "HASH") {
3228 if (ref($targets{$_}) eq "") {
3229 warn "Deprecated target configuration for $_, ignoring...\n";
3231 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
3233 delete $targets{$_};
3235 $targets{$_}->{_conf_fname_int
} = add
([ $fname ]);
3239 %table = (%table, %targets);
3243 # configuration resolver. Will only resolve all the lazy evaluation
3244 # codeblocks for the chosen target and all those it inherits from,
3246 sub resolve_config
{
3248 my @breadcrumbs = @_;
3250 # my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
3252 if (grep { $_ eq $target } @breadcrumbs) {
3253 die "inherit_from loop! target backtrace:\n "
3254 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
3257 if (!defined($table{$target})) {
3258 warn "Warning! target $target doesn't exist!\n";
3261 # Recurse through all inheritances. They will be resolved on the
3262 # fly, so when this operation is done, they will all just be a
3263 # bunch of attributes with string values.
3264 # What we get here, though, are keys with references to lists of
3265 # the combined values of them all. We will deal with lists after
3266 # this stage is done.
3267 my %combined_inheritance = ();
3268 if ($table{$target}->{inherit_from
}) {
3270 map { ref($_) eq "CODE" ?
$_->() : $_ } @
{$table{$target}->{inherit_from
}};
3271 foreach (@inherit_from) {
3272 my %inherited_config = resolve_config
($_, $target, @breadcrumbs);
3274 # 'template' is a marker that's considered private to
3275 # the config that had it.
3276 delete $inherited_config{template
};
3278 foreach (keys %inherited_config) {
3279 if (!$combined_inheritance{$_}) {
3280 $combined_inheritance{$_} = [];
3282 push @
{$combined_inheritance{$_}}, $inherited_config{$_};
3287 # We won't need inherit_from in this target any more, since we've
3288 # resolved all the inheritances that lead to this
3289 delete $table{$target}->{inherit_from
};
3291 # Now is the time to deal with those lists. Here's the place to
3292 # decide what shall be done with those lists, all based on the
3293 # values of the target we're currently dealing with.
3294 # - If a value is a coderef, it will be executed with the list of
3295 # inherited values as arguments.
3296 # - If the corresponding key doesn't have a value at all or is the
3297 # empty string, the inherited value list will be run through the
3298 # default combiner (below), and the result becomes this target's
3300 # - Otherwise, this target's value is assumed to be a string that
3301 # will simply override the inherited list of values.
3302 my $default_combiner = add
();
3305 map { $_ => 1 } (keys %combined_inheritance,
3306 keys %{$table{$target}});
3308 sub process_values
{
3310 my $inherited = shift; # Always a [ list ]
3316 while(ref($object) eq "CODE") {
3317 $object = $object->(@
$inherited);
3319 if (!defined($object)) {
3322 elsif (ref($object) eq "ARRAY") {
3323 local $add_called; # To make sure recursive calls don't affect it
3324 return [ map { process_values
($_, $inherited, $target, $entry) }
3326 } elsif (ref($object) eq "") {
3329 die "cannot handle reference type ",ref($object)
3330 ," found in target ",$target," -> ",$entry,"\n";
3334 foreach my $key (sort keys %all_keys) {
3335 my $previous = $combined_inheritance{$key};
3337 # Current target doesn't have a value for the current key?
3338 # Assign it the default combiner, the rest of this loop body
3339 # will handle it just like any other coderef.
3340 if (!exists $table{$target}->{$key}) {
3341 $table{$target}->{$key} = $default_combiner;
3344 $table{$target}->{$key} = process_values
($table{$target}->{$key},
3345 $combined_inheritance{$key},
3347 unless(defined($table{$target}->{$key})) {
3348 delete $table{$target}->{$key};
3350 # if ($extra_checks &&
3351 # $previous && !($add_called || $previous ~~ $table{$target}->{$key})) {
3352 # warn "$key got replaced in $target\n";
3356 # Finally done, return the result.
3357 return %{$table{$target}};
3362 print STDERR
$usage;
3363 print STDERR
"\npick os/compiler from:\n";
3367 foreach $i (sort keys %table)
3369 next if $table{$i}->{template
};
3370 next if $i =~ /^debug/;
3371 $k += length($i) + 1;
3377 print STDERR
$i . " ";
3379 foreach $i (sort keys %table)
3381 next if $table{$i}->{template
};
3382 next if $i !~ /^debug/;
3383 $k += length($i) + 1;
3389 print STDERR
$i . " ";
3394 sub compiler_predefined
{
3398 return () if $^O
eq 'VMS';
3400 die 'compiler_predefined called without a compiler command'
3403 if (! $predefined{$cc}) {
3405 $predefined{$cc} = {};
3407 # collect compiler pre-defines from gcc or gcc-alike...
3408 open(PIPE
, "$cc -dM -E -x c /dev/null 2>&1 |");
3409 while (my $l = <PIPE
>) {
3410 $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
3411 $predefined{$cc}->{$1} = $2 // '';
3416 return %{$predefined{$cc}};
3423 if (eval { require IPC
::Cmd
; 1; }) {
3425 return scalar IPC
::Cmd
::can_run
($name);
3427 # if there is $directories component in splitpath,
3428 # then it's not something to test with $PATH...
3429 return $name if (File
::Spec
->splitpath($name))[1];
3431 foreach (File
::Spec
->path()) {
3432 my $fullpath = catfile
($_, "$name$target{exe_extension}");
3433 if (-f
$fullpath and -x
$fullpath) {
3445 unless ($opts{cacheonly
}) {
3446 # Note that if $ENV{$name} doesn't exist or is undefined,
3447 # $config{perlenv}->{$name} will be created with the value
3448 # undef. This is intentional.
3450 $config{perlenv
}->{$name} = $ENV{$name}
3451 if ! exists $config{perlenv
}->{$name};
3453 return $config{perlenv
}->{$name};
3456 # Configuration printer ##############################################
3458 sub print_table_entry
3460 local $now_printing = shift;
3461 my %target = resolve_config
($now_printing);
3464 # Don't print the templates
3465 return if $target{template
};
3510 if ($type eq "TABLE") {
3512 print "*** $now_printing\n";
3513 foreach (@sequence) {
3514 if (ref($target{$_}) eq "ARRAY") {
3515 printf "\$%-12s = %s\n", $_, join(" ", @
{$target{$_}});
3517 printf "\$%-12s = %s\n", $_, $target{$_};
3520 } elsif ($type eq "HASH") {
3522 length((sort { length($a) <=> length($b) } @sequence)[-1]);
3523 print " '$now_printing' => {\n";
3524 foreach (@sequence) {
3526 if (ref($target{$_}) eq "ARRAY") {
3527 print " '",$_,"'"," " x
($largest - length($_))," => [ ",join(", ", map { "'$_'" } @
{$target{$_}})," ],\n";
3529 print " '",$_,"'"," " x
($largest - length($_))," => '",$target{$_},"',\n";
3537 # Utility routines ###################################################
3539 # On VMS, if the given file is a logical name, File::Spec::Functions
3540 # will consider it an absolute path. There are cases when we want a
3541 # purely syntactic check without checking the environment.
3545 # On non-platforms, we just use file_name_is_absolute().
3546 return file_name_is_absolute
($file) unless $^O
eq "VMS";
3548 # If the file spec includes a device or a directory spec,
3549 # file_name_is_absolute() is perfectly safe.
3550 return file_name_is_absolute
($file) if $file =~ m
|[:\
[]|;
3552 # Here, we know the given file spec isn't absolute
3556 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
3557 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
3558 # realpath() requires that at least all path components except the last is an
3559 # existing directory. On VMS, the last component of the directory spec must
3564 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
3565 # will return the volume name for the device, no matter what. Also,
3566 # it will return an incorrect directory spec if the argument is a
3567 # directory that doesn't exist.
3569 return rel2abs
($dir);
3572 # realpath() on Windows seems to check if the directory actually exists,
3573 # which isn't what is wanted here. All we want to know is if a directory
3574 # spec is absolute, not if it exists.
3575 if ($^O
eq "MSWin32") {
3576 return rel2abs
($dir);
3579 # We use realpath() on Unix, since no other will properly clean out
3581 use Cwd qw
/realpath/;
3583 return realpath
($dir);
3586 # Check if all paths are one and the same, using stat. They must both exist
3587 # We need this for the cases when File::Spec doesn't detect case insensitivity
3588 # (File::Spec::Unix assumes case sensitivity)
3590 die "samedir expects two arguments\n" unless scalar @_ == 2;
3592 my @stat0 = stat($_[0]); # First argument
3593 my @stat1 = stat($_[1]); # Second argument
3595 die "Couldn't stat $_[0]" unless @stat0;
3596 die "Couldn't stat $_[1]" unless @stat1;
3598 # Compare device number
3599 return 0 unless ($stat0[0] == $stat1[0]);
3600 # Compare "inode". The perl manual recommends comparing as
3601 # string rather than as number.
3602 return 0 unless ($stat0[1] eq $stat1[1]);
3604 return 1; # All the same
3609 perl
=> sub { my $x = shift;
3610 $x =~ s/([\\\$\@"])/\\$1/g;
3611 return '"'.$x.'"'; },
3612 maybeshell
=> sub { my $x = shift;
3613 (my $y = $x) =~ s/([\\\"])/\\$1/g;
3614 if ($x ne $y || $x =~ m
|\s
|) {
3623 defined($processors{$for}) ?
$processors{$for} : sub { shift; };
3625 return map { $processor->($_); } @_;
3628 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
3629 # $filename is a file name to read from
3630 # $line_concat_cond_re is a regexp detecting a line continuation ending
3631 # $line_concat is a CODEref that takes care of concatenating two lines
3632 sub collect_from_file
{
3633 my $filename = shift;
3634 my $line_concat_cond_re = shift;
3635 my $line_concat = shift;
3637 open my $fh, $filename || die "unable to read $filename: $!\n";
3639 my $saved_line = "";
3643 if (defined $line_concat) {
3644 $_ = $line_concat->($saved_line, $_);
3647 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3653 die "$filename ending with continuation line\n" if $_;
3659 # collect_from_array($array, $line_concat_cond_re, $line_concat)
3660 # $array is an ARRAYref of lines
3661 # $line_concat_cond_re is a regexp detecting a line continuation ending
3662 # $line_concat is a CODEref that takes care of concatenating two lines
3663 sub collect_from_array
{
3665 my $line_concat_cond_re = shift;
3666 my $line_concat = shift;
3667 my @array = (@
$array);
3670 my $saved_line = "";
3672 while (defined($_ = shift @array)) {
3674 if (defined $line_concat) {
3675 $_ = $line_concat->($saved_line, $_);
3678 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3684 die "input text ending with continuation line\n" if $_;
3689 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
3690 # $lineiterator is a CODEref that delivers one line at a time.
3691 # All following arguments are regex/CODEref pairs, where the regexp detects a
3692 # line and the CODEref does something with the result of the regexp.
3693 sub collect_information
{
3694 my $lineiterator = shift;
3695 my %collectors = @_;
3697 while(defined($_ = $lineiterator->())) {
3700 if ($collectors{"BEFORE"}) {
3701 $collectors{"BEFORE"}->($_);
3703 foreach my $re (keys %collectors) {
3704 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
3705 $collectors{$re}->($lineiterator);
3709 if ($collectors{"OTHERWISE"}) {
3710 $collectors{"OTHERWISE"}->($lineiterator, $_)
3711 unless $found || !defined $collectors{"OTHERWISE"};
3713 if ($collectors{"AFTER"}) {
3714 $collectors{"AFTER"}->($_);
3720 # tokenize($line,$separator)
3721 # $line is a line of text to split up into tokens
3722 # $separator [optional] is a regular expression that separates the tokens,
3723 # the default being spaces. Do not use quotes of any kind as separators,
3724 # that will give undefined results.
3725 # Returns a list of tokens.
3727 # Tokens are divided by separator (spaces by default). If the tokens include
3728 # the separators, they have to be quoted with single or double quotes.
3729 # Double quotes inside a double quoted token must be escaped. Escaping is done
3731 # Basically, the same quoting rules apply for " and ' as in any
3734 my $line = my $debug_line = shift;
3735 my $separator = shift // qr
|\s
+|;
3738 if ($ENV{CONFIGURE_DEBUG_TOKENIZE
}) {
3739 print STDERR
"DEBUG[tokenize]: \$separator = $separator\n";
3742 while ($line =~ s
|^${separator
}||, $line ne "") {
3745 $line =~ m/^(.*?)(${separator}|"|'|$)/;
3749 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
3753 } elsif ($line =~ m/^'([^']*)'/) {
3758 push @result, $token;
3761 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3762 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
3763 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";