3 # Copyright 2016-2022 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.
80 # no-hw do not compile support for any crypto hardware.
81 # [no-]threads [don't] try to create a library that is suitable for
82 # multithreaded applications (default is "threads" if we
85 # [don't] allow thread pool functionality
86 # [no-]default-thread-pool
87 # [don't] allow default thread pool functionality
88 # [no-]shared [don't] try to create shared libraries when supported.
89 # [no-]pic [don't] try to build position independent code when supported.
90 # If disabled, it also disables shared and dynamic-engine.
91 # no-asm do not use assembler
92 # no-egd do not compile support for the entropy-gathering daemon APIs
93 # [no-]zlib [don't] compile support for zlib compression.
94 # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
95 # library and will be loaded at run-time by the OpenSSL library.
96 # sctp include SCTP support
97 # enable-quic include QUIC support (currently just for developers as the
98 # implementation is by no means complete and usable)
99 # no-uplink Don't build support for UPLINK interface.
100 # enable-weak-ssl-ciphers
101 # Enable weak ciphers that are disabled by default.
102 # 386 generate 80386 code in assembly modules
103 # no-sse2 disables IA-32 SSE2 code in assembly modules, the above
104 # mentioned '386' option implies this one
105 # no-<cipher> build without specified algorithm (dsa, idea, rc5, ...)
106 # -<xxx> +<xxx> All options which are unknown to the 'Configure' script are
107 # /<xxx> passed through to the compiler. Unix-style options beginning
108 # with a '-' or '+' are recognized, as well as Windows-style
109 # options beginning with a '/'. If the option contains arguments
110 # separated by spaces, then the URL-style notation %20 can be
111 # used for the space character in order to avoid having to quote
112 # the option. For example, -opt%20arg gets expanded to -opt arg.
113 # In fact, any ASCII character can be encoded as %xx using its
114 # hexadecimal encoding.
115 # -static while -static is also a pass-through compiler option (and
116 # as such is limited to environments where it's actually
117 # meaningful), it triggers a number configuration options,
118 # namely no-pic, no-shared and no-threads. It is
119 # argued that the only reason to produce statically linked
120 # binaries (and in context it means executables linked with
121 # -static flag, and not just executables linked with static
122 # libcrypto.a) is to eliminate dependency on specific run-time,
123 # a.k.a. libc version. The mentioned config options are meant
124 # to achieve just that. Unfortunately on Linux it's impossible
125 # to eliminate the dependency completely for openssl executable
126 # because of getaddrinfo and gethostbyname calls, which can
127 # invoke dynamically loadable library facility anyway to meet
128 # the lookup requests. For this reason on Linux statically
129 # linked openssl executable has rather debugging value than
130 # production quality.
132 # BN_LLONG use the type 'long long' in crypto/bn/bn.h
133 # RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
134 # Following are set automatically by this script
136 # MD5_ASM use some extra md5 assembler,
137 # SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86
138 # RMD160_ASM use some extra ripemd160 assembler,
139 # SHA256_ASM sha256_block is implemented in assembler
140 # SHA512_ASM sha512_block is implemented in assembler
141 # AES_ASM AES_[en|de]crypt is implemented in assembler
143 # Minimum warning options... any contributions to OpenSSL should at least
144 # get past these. Note that we only use these with C compilers, not with
147 # -DPEDANTIC complements -pedantic and is meant to mask code that
148 # is not strictly standard-compliant and/or implementation-specific,
149 # e.g. inline assembly, disregards to alignment requirements, such
150 # that -pedantic would complain about. Incidentally -DPEDANTIC has
151 # to be used even in sanitized builds, because sanitizer too is
152 # supposed to and does take notice of non-standard behaviour. Then
153 # -pedantic with pre-C9x compiler would also complain about 'long
154 # long' not being supported. As 64-bit algorithms are common now,
155 # it grew impossible to resolve this without sizeable additional
156 # code, so we just tell compiler to be pedantic about everything
157 # but 'long long' type.
159 my @gcc_devteam_warn = qw(
160 -DPEDANTIC -pedantic -Wno-long-long -DUNUSEDRESULT_DEBUG
162 -Wmissing-declarations
164 -Wno-unused-parameter
165 -Wno-missing-field-initializers
177 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
178 # TODO(openssl-team): fix problems and investigate if (at least) the
179 # following warnings can also be enabled:
181 # -Wunreachable-code -- no, too ugly/compiler-specific
182 # -Wlanguage-extension-token -- no, we use asm()
183 # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
184 # -Wextended-offsetof -- no, needed in CMS ASN1 code
185 my @clang_devteam_warn = qw(
186 -Wno-unknown-warning-option
188 -Wno-parentheses-equality
189 -Wno-language-extension-token
190 -Wno-extended-offsetof
191 -Wconditional-uninitialized
192 -Wincompatible-pointer-types-discards-qualifiers
193 -Wmissing-variable-declarations
196 my @cl_devteam_warn = qw(
200 my $strict_warnings = 0;
202 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
203 # which would cover all BSD flavors. -pthread applies to them all,
204 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
205 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
206 # which has to be accompanied by explicit -D_THREAD_SAFE and
207 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
208 # seems to be sufficient?
209 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
212 # API compatibility name to version number mapping.
215 # This table expresses when API additions or changes can occur.
216 # The numbering used changes from 3.0 and on because we updated
217 # (solidified) our version numbering scheme at that point.
219 # From 3.0 and on, we internalise the given version number in decimal
220 # as MAJOR * 10000 + MINOR * 100 + 0
224 # Note that before 3.0, we didn't have the same version number scheme.
225 # Still, the numbering we use here covers what we need.
234 # For OpenSSL::config::get_platform
242 our $now_printing; # set to current entry's name in print_table_entry
243 # (todo: right thing would be to encapsulate name
244 # into %target [class] and make print_table_entry
247 # Forward declarations ###############################################
249 # read_config(filename)
251 # Reads a configuration file and populates %table with the contents
252 # (which the configuration file places in %targets).
255 # resolve_config(target)
257 # Resolves all the late evaluations, inheritances and so on for the
258 # chosen target and any target it inherits from.
262 # Information collection #############################################
264 # Unified build supports separate build dir
265 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
266 my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
268 # File::Spec::Unix doesn't detect case insensitivity, so we make sure to
269 # check if the source and build directory are really the same, and make
270 # them so. This avoids all kinds of confusion later on.
271 # We must check @File::Spec::ISA rather than using File::Spec->isa() to
272 # know if File::Spec ended up loading File::Spec::Unix.
274 if (grep(/::Unix$/, @File::Spec::ISA)
275 && samedir($srcdir, $blddir));
277 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
279 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
281 $config{sourcedir} = abs2rel($srcdir, $blddir);
282 $config{builddir} = abs2rel($blddir, $blddir);
283 # echo -n 'holy hand grenade of antioch' | openssl sha256
285 'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
287 # Collect reconfiguration information if needed
290 if (grep /^reconf(igure)?$/, @argvcopy) {
291 die "reconfiguring with other arguments present isn't supported"
292 if scalar @argvcopy > 1;
293 if (-f "./configdata.pm") {
294 my $file = "./configdata.pm";
295 unless (my $return = do $file) {
296 die "couldn't parse $file: $@" if $@;
297 die "couldn't do $file: $!" unless defined $return;
298 die "couldn't run $file" unless $return;
301 @argvcopy = defined($configdata::config{perlargv}) ?
302 @{$configdata::config{perlargv}} : ();
303 die "Incorrect data to reconfigure, please do a normal configuration\n"
304 if (grep(/^reconf/,@argvcopy));
305 $config{perlenv} = $configdata::config{perlenv} // {};
307 die "Insufficient data to reconfigure, please do a normal configuration\n";
311 $config{perlargv} = [ @argvcopy ];
313 # Historical: if known directories in crypto/ have been removed, it means
314 # that those sub-systems are disabled.
315 # (the other option would be to removed them from the SUBDIRS statement in
317 # We reverse the input list for cosmetic purely reasons, to compensate that
318 # 'unshift' adds at the front of the list (i.e. in reverse input order).
319 foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh',
320 'dsa', 'ec', 'hmac', 'idea', 'md2', 'md5', 'mdc2',
321 'rc2', 'rc4', 'rc5', 'ripemd', 'seed', 'sha',
322 'sm2', 'sm3', 'sm4') ) {
323 unshift @argvcopy, "no-$_" if ! -d catdir($srcdir, 'crypto', $_);
326 # Collect version numbers
330 collect_from_file(catfile($srcdir,'VERSION.dat')),
331 qr/\s*(\w+)\s*=\s*(.*?)\s*$/ =>
333 # Only define it if there is a value at all
337 # Some values are quoted. Trim the quotes
338 $v = $1 if $v =~ /^"(.*)"$/;
339 $version{uc $k} = $v;
343 sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" },
346 $config{major} = $version{MAJOR} // 'unknown';
347 $config{minor} = $version{MINOR} // 'unknown';
348 $config{patch} = $version{PATCH} // 'unknown';
349 $config{prerelease} =
350 defined $version{PRE_RELEASE_TAG} ? "-$version{PRE_RELEASE_TAG}" : '';
351 $config{build_metadata} =
352 defined $version{BUILD_METADATA} ? "+$version{BUILD_METADATA}" : '';
353 $config{shlib_version} = $version{SHLIB_VERSION} // 'unknown';
354 $config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx';
356 $config{version} = "$config{major}.$config{minor}.$config{patch}";
357 $config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
359 die "erroneous version information in VERSION.dat: ",
360 "$config{version}, $config{shlib_version}\n"
361 unless (defined $version{MAJOR}
362 && defined $version{MINOR}
363 && defined $version{PATCH}
364 && defined $version{SHLIB_VERSION});
366 # Collect target configurations
368 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
369 foreach (sort glob($pattern)) {
373 if (defined env($local_config_envname)) {
375 # VMS environment variables are logical names,
376 # which can be used as is
377 $pattern = $local_config_envname . ':' . '*.conf';
379 $pattern = catfile(env($local_config_envname), '*.conf');
382 foreach (sort glob($pattern)) {
387 # Save away perl command information
388 $config{perl_cmd} = $^X;
389 $config{perl_version} = $Config{version};
390 $config{perl_archname} = $Config{archname};
393 $config{openssldir}="";
394 $config{processor}="";
396 my $auto_threads=1; # enable threads automatically? true by default
399 # Known TLS and DTLS protocols
400 my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
401 my @dtls = qw(dtls1 dtls1_2);
403 # Explicitly known options that are possible to disable. They can
404 # be regexps, and will be used like this: /^no-${option}$/
405 # For developers: keep it sorted alphabetically
435 "default-thread-pool",
447 "ec_nistp_64_gcc_128",
456 "fips-securitychecks",
521 foreach my $proto ((@tls, @dtls))
523 push(@disablables, $proto);
524 push(@disablables, "$proto-method") unless $proto eq "tls1_3";
527 # Internal disablables, for aliasing purposes. They serve no special
528 # purpose here, but allow scripts to get to know them through configdata.pm,
529 # where these are merged with @disablables.
530 # The actual aliasing mechanism is done via %disable_cascades
531 my @disablables_int = qw(
535 my %deprecated_disablables = (
537 "buf-freelists" => undef,
538 "crypto-mdebug-backtrace" => undef,
539 "hw" => "hw", # causes cascade, but no macro
540 "hw-padlock" => "padlockeng",
541 "ripemd" => "rmd160",
542 "ui" => "ui-console",
543 "heartbeats" => undef,
546 # All of the following are disabled by default:
548 our %disabled = ( # "what" => "comment"
551 "brotli" => "default",
552 "brotli-dynamic" => "default",
553 "buildtest-c++" => "default",
554 "crypto-mdebug" => "default",
555 "crypto-mdebug-backtrace" => "default",
556 "devcryptoeng" => "default",
557 "ec_nistp_64_gcc_128" => "default",
559 "external-tests" => "default",
560 "fuzz-afl" => "default",
561 "fuzz-libfuzzer" => "default",
569 "ssl3-method" => "default",
571 "trace" => "default",
572 "ubsan" => "default",
573 "unit-test" => "default",
574 "weak-ssl-ciphers" => "default",
576 "zlib-dynamic" => "default",
579 # Note: => pair form used for aesthetics, not to truly make a hash table
580 my @disable_cascades = (
581 # "what" => [ "cascade", ... ]
582 "bulk" => [ "shared", "dso",
583 "aria", "async", "autoload-config",
584 "blake2", "bf", "camellia", "cast", "chacha",
585 "cmac", "cms", "cmp", "comp", "ct",
586 "des", "dgram", "dh", "dsa",
590 "md4", "multiblock", "nextprotoneg",
591 "ocsp", "ocb", "poly1305", "psk",
592 "rc2", "rc4", "rmd160",
593 "seed", "siphash", "siv",
595 "srtp", "ssl3-method", "ssl-trace",
597 "ts", "ui-console", "whirlpool",
598 "fips-securitychecks" ],
599 sub { $config{processor} eq "386" }
602 "ssl3-method" => [ "ssl3" ],
603 "zlib" => [ "zlib-dynamic" ],
604 "brotli" => [ "brotli-dynamic" ],
606 "ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ],
607 "dgram" => [ "dtls", "quic", "sctp" ],
608 "sock" => [ "dgram", "tfo" ],
610 sub { 0 == scalar grep { !$disabled{$_} } @dtls }
614 sub { 0 == scalar grep { !$disabled{$_} } @tls }
617 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
619 # If no modules, then no dynamic engines either
620 "module" => [ "dynamic-engine" ],
622 # Without shared libraries, dynamic engines aren't possible.
623 # This is due to them having to link with libcrypto and register features
624 # using the ENGINE functionality, and since that relies on global tables,
625 # those *have* to be exactly the same as the ones accessed from the app,
626 # which cannot be guaranteed if shared libraries aren't present.
627 # (note that even with shared libraries, both the app and dynamic engines
628 # must be linked with the same library)
629 "shared" => [ "dynamic-engine", "uplink" ],
630 "dso" => [ "dynamic-engine", "module" ],
631 # Other modules don't necessarily have to link with libcrypto, so shared
632 # libraries do not have to be a condition to produce those.
634 # Without position independent code, there can be no shared libraries
636 "pic" => [ "shared", "module" ],
638 "module" => [ "fips", "dso" ],
640 "engine" => [ "dynamic-engine", grep(/eng$/, @disablables) ],
641 "dynamic-engine" => [ "loadereng" ],
642 "hw" => [ "padlockeng" ],
644 # no-autoalginit is only useful when building non-shared
645 "autoalginit" => [ "shared", "apps", "fips" ],
647 "stdio" => [ "apps", "capieng", "egd" ],
648 "apps" => [ "tests" ],
649 "tests" => [ "external-tests" ],
650 "comp" => [ "zlib", "brotli" ],
652 sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
654 sub { !$disabled{"msan"} } => [ "asm" ],
657 "legacy" => [ "md2" ],
661 "fips" => [ "fips-securitychecks", "acvp-tests" ],
663 "threads" => [ "thread-pool" ],
664 "thread-pool" => [ "default-thread-pool" ],
666 "deprecated-3.0" => [ "engine", "srp" ]
669 # Avoid protocol support holes. Also disable all versions below N, if version
670 # N is disabled while N+1 is enabled.
672 my @list = (reverse @tls);
673 while ((my $first, my $second) = (shift @list, shift @list)) {
675 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
677 unshift @list, $second;
679 my @list = (reverse @dtls);
680 while ((my $first, my $second) = (shift @list, shift @list)) {
682 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
684 unshift @list, $second;
687 # Explicit "no-..." options will be collected in %disabled along with the defaults.
688 # To remove something from %disabled, use "enable-foo".
689 # For symmetry, "disable-foo" is a synonym for "no-foo".
691 # For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with
692 # platform specific list separators. Users from those platforms should
693 # recognise those separators from how you set up the PATH to find executables.
694 # The default is the Unix like separator, :, but as an exception, we also
695 # support the space as separator.
696 my $list_separator_re =
697 { VMS => qr/(?<!\^),/,
698 MSWin32 => qr/(?<!\\);/ } -> {$^O} // qr/(?<!\\)[:\s]/;
699 # All the "make variables" we support
700 # Some get pre-populated for the sake of backward compatibility
701 # (we supported those before the change to "make variable" support.
708 CFLAGS => [ env('CFLAGS') || () ],
710 CXXFLAGS => [ env('CXXFLAGS') || () ],
712 CPPFLAGS => [ env('CPPFLAGS') || () ], # -D, -I, -Wp,
713 CPPDEFINES => [], # Alternative for -D
714 CPPINCLUDES => [], # Alternative for -I
715 CROSS_COMPILE => env('CROSS_COMPILE'),
716 HASHBANGPERL=> env('HASHBANGPERL') || env('PERL'),
718 LDFLAGS => [ env('LDFLAGS') || () ], # -L, -Wl,
719 LDLIBS => [ env('LDLIBS') || () ], # -l
722 PERL => env('PERL') || ($^O ne "VMS" ? $^X : "perl"),
723 RANLIB => env('RANLIB'),
724 RC => env('RC') || env('WINDRES'),
725 RCFLAGS => [ env('RCFLAGS') || () ],
728 # Info about what "make variables" may be prefixed with the cross compiler
729 # prefix. This should NEVER mention any such variable with a list for value.
730 my @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC );
731 # The same but for flags given as Configure options. These are *additional*
732 # input, as opposed to the VAR=string option that override the corresponding
733 # config target attributes
745 my %user_synonyms = (
746 HASHBANGPERL=> 'PERL',
750 # Some target attributes have been renamed, this is the translation table
751 my %target_attr_translate =(
757 hashbangperl => 'HASHBANGPERL',
765 # Initialisers coming from 'config' scripts
766 $config{defines} = [ split(/$list_separator_re/, env('__CNF_CPPDEFINES')) ];
767 $config{includes} = [ split(/$list_separator_re/, env('__CNF_CPPINCLUDES')) ];
768 $config{cppflags} = [ env('__CNF_CPPFLAGS') || () ];
769 $config{cflags} = [ env('__CNF_CFLAGS') || () ];
770 $config{cxxflags} = [ env('__CNF_CXXFLAGS') || () ];
771 $config{lflags} = [ env('__CNF_LDFLAGS') || () ];
772 $config{ex_libs} = [ env('__CNF_LDLIBS') || () ];
774 $config{openssl_api_defines}=[];
775 $config{openssl_sys_defines}=[];
776 $config{openssl_feature_defines}=[];
778 $config{build_type} = "release";
781 my %cmdvars = (); # Stores FOO='blah' type arguments
782 my %unsupported_options = ();
783 my %deprecated_options = ();
784 # If you change this, update apps/version.c
785 my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
786 my @seed_sources = ();
789 $_ = shift @argvcopy;
791 # Support env variable assignments among the options
792 if (m|^(\w+)=(.+)?$|)
795 # Every time a variable is given as a configuration argument,
796 # it acts as a reset if the variable.
797 if (exists $user{$1})
799 $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef;
801 #if (exists $useradd{$1})
808 # VMS is a case insensitive environment, and depending on settings
809 # out of our control, we may receive options uppercased. Let's
810 # downcase at least the part before any equal sign.
816 # some people just can't read the instructions, clang people have to...
817 s/^-no-(?!integrated-as)/no-/;
819 # rewrite some options in "enable-..." form
820 s /^-?-?shared$/enable-shared/;
821 s /^sctp$/enable-sctp/;
822 s /^threads$/enable-threads/;
823 s /^zlib$/enable-zlib/;
824 s /^zlib-dynamic$/enable-zlib-dynamic/;
825 s /^fips$/enable-fips/;
827 if (/^(no|disable|enable)-(.+)$/)
830 if ($word !~ m|hw(?:-.+)| # special treatment for hw regexp opt
831 && !exists $deprecated_disablables{$word}
832 && !grep { $word eq $_ } @disablables)
834 $unsupported_options{$_} = 1;
838 if (/^no-(.+)$/ || /^disable-(.+)$/)
840 foreach my $proto ((@tls, @dtls))
842 if ($1 eq "$proto-method")
844 $disabled{"$proto"} = "option($proto-method)";
850 foreach my $proto (@dtls)
852 $disabled{$proto} = "option(dtls)";
854 $disabled{"dtls"} = "option(dtls)";
858 # Last one of its kind
859 $disabled{"ssl3"} = "option(ssl)";
863 # XXX: Tests will fail if all SSL/TLS
864 # protocols are disabled.
865 foreach my $proto (@tls)
867 $disabled{$proto} = "option(tls)";
870 elsif ($1 eq "static-engine")
872 delete $disabled{"dynamic-engine"};
874 elsif ($1 eq "dynamic-engine")
876 $disabled{"dynamic-engine"} = "option";
878 elsif (exists $deprecated_disablables{$1})
880 $deprecated_options{$_} = 1;
881 if (defined $deprecated_disablables{$1})
883 $disabled{$deprecated_disablables{$1}} = "option";
886 elsif ($1 =~ m|hw(?:-.+)|) # deprecate hw options in regexp form
888 $deprecated_options{$_} = 1;
892 $disabled{$1} = "option";
894 # No longer an automatic choice
895 $auto_threads = 0 if ($1 eq "threads");
897 elsif (/^enable-(.+)$/)
899 if ($1 eq "static-engine")
901 $disabled{"dynamic-engine"} = "option";
903 elsif ($1 eq "dynamic-engine")
905 delete $disabled{"dynamic-engine"};
907 elsif ($1 eq "zlib-dynamic")
909 delete $disabled{"zlib"};
911 elsif ($1 eq "brotli-dynamic")
913 delete $disabled{"brotli"};
916 delete $disabled{$algo};
918 # No longer an automatic choice
919 $auto_threads = 0 if ($1 eq "threads");
921 elsif (/^-d$/) # From older 'config'
923 $config{build_type} = "debug";
925 elsif (/^-v$/) # From older 'config'
927 $guess_opts{verbose} = 1;
931 $guess_opts{nowait} = 1;
933 elsif (/^-t$/) # From older 'config'
937 elsif (/^--strict-warnings$/)
939 # Pretend that our strict flags is a C flag, and replace it
940 # with the proper flags later on
941 push @{$useradd{CFLAGS}}, '--ossl-strict-warnings';
946 $config{build_type} = "debug";
948 elsif (/^--release$/)
950 $config{build_type} = "release";
953 { $config{processor}=386; }
956 # No RSAref support any more since it's not needed.
957 # The check for the option is there so scripts aren't
962 if (/^--prefix=(.*)$/)
965 die "Directory given with --prefix MUST be absolute\n"
966 unless file_name_is_absolute($config{prefix});
968 elsif (/^--api=(.*)$/)
971 die "Unknown API compatibility level $api"
972 unless defined $apitable->{$api};
973 $config{api}=$apitable->{$api};
975 elsif (/^--libdir=(.*)$/)
979 elsif (/^--openssldir=(.*)$/)
981 $config{openssldir}=$1;
983 elsif (/^--with-zlib-lib=(.*)$/)
985 $withargs{zlib_lib}=$1;
987 elsif (/^--with-zlib-include=(.*)$/)
989 $withargs{zlib_include}=$1;
991 elsif (/^--with-brotli-lib=(.*)$/)
993 $withargs{brotli_lib}=$1;
995 elsif (/^--with-brotli-include=(.*)$/)
997 $withargs{brotli_include}=$1;
999 elsif (/^--with-fuzzer-lib=(.*)$/)
1001 $withargs{fuzzer_lib}=$1;
1003 elsif (/^--with-fuzzer-include=(.*)$/)
1005 $withargs{fuzzer_include}=$1;
1007 elsif (/^--with-rand-seed=(.*)$/)
1009 foreach my $x (split(m|,|, $1))
1011 die "Unknown --with-rand-seed choice $x\n"
1012 if ! grep { $x eq $_ } @known_seed_sources;
1013 push @seed_sources, $x;
1016 elsif (/^--fips-key=(.*)$/)
1018 $user{FIPSKEY}=lc($1);
1019 die "Non-hex character in FIPS key\n"
1020 if $user{FIPSKEY} =~ /[^a-f0-9]/;
1021 die "FIPS key must have even number of characters\n"
1023 die "FIPS key too long (64 bytes max)\n"
1026 elsif (/^--banner=(.*)$/)
1028 $banner = $1 . "\n";
1030 elsif (/^--cross-compile-prefix=(.*)$/)
1032 $user{CROSS_COMPILE}=$1;
1034 elsif (/^--config=(.*)$/)
1040 push @{$useradd{LDLIBS}}, $_;
1042 elsif (/^-framework$/)
1044 push @{$useradd{LDLIBS}}, $_, shift(@argvcopy);
1046 elsif (/^-L(.*)$/ or /^-Wl,/)
1048 push @{$useradd{LDFLAGS}}, $_;
1050 elsif (/^-rpath$/ or /^-R$/)
1051 # -rpath is the OSF1 rpath flag
1052 # -R is the old Solaris rpath flag
1054 my $rpath = shift(@argvcopy) || "";
1055 $rpath .= " " if $rpath ne "";
1056 push @{$useradd{LDFLAGS}}, $_, $rpath;
1060 push @{$useradd{LDFLAGS}}, $_;
1062 elsif (m|^[-/]D(.*)$|)
1064 push @{$useradd{CPPDEFINES}}, $1;
1066 elsif (m|^[-/]I(.*)$|)
1068 push @{$useradd{CPPINCLUDES}}, $1;
1072 push @{$useradd{CPPFLAGS}}, $1;
1074 else # common if (/^[-+]/), just pass down...
1076 # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1077 # This provides a simple way to pass options with arguments separated
1078 # by spaces without quoting (e.g. -opt%20arg translates to -opt arg).
1079 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1080 push @{$useradd{CFLAGS}}, $_;
1081 push @{$useradd{CXXFLAGS}}, $_;
1086 # Treat %xx as an ASCII code (e.g. replace %20 by a space character).
1087 # This provides a simple way to pass options with arguments separated
1088 # by spaces without quoting (e.g. /opt%20arg translates to /opt arg).
1089 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
1090 push @{$useradd{CFLAGS}}, $_;
1091 push @{$useradd{CXXFLAGS}}, $_;
1095 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
1098 unless ($_ eq $target || /^no-/ || /^disable-/)
1100 # "no-..." follows later after implied deactivations
1101 # have been derived. (Don't take this too seriously,
1102 # we really only write OPTIONS to the Makefile out of
1105 if ($config{options} eq "")
1106 { $config{options} = $_; }
1108 { $config{options} .= " ".$_; }
1112 if (keys %deprecated_options)
1114 warn "***** Deprecated options: ",
1115 join(", ", keys %deprecated_options), "\n";
1117 if (keys %unsupported_options)
1119 die "***** Unsupported options: ",
1120 join(", ", keys %unsupported_options), "\n";
1123 # If any %useradd entry has been set, we must check that the "make
1124 # variables" haven't been set. We start by checking of any %useradd entry
1126 if (grep { scalar @$_ > 0 } values %useradd) {
1127 # Hash of env / make variables names. The possible values are:
1129 # 2 - %useradd entry set
1133 $v += 1 if $cmdvars{$_};
1134 $v += 2 if @{$useradd{$_}};
1138 # If any of the corresponding "make variables" is set, we error
1139 if (grep { $_ & 1 } values %detected_vars) {
1140 my $names = join(', ', grep { $detected_vars{$_} > 0 }
1141 sort keys %detected_vars);
1143 ***** Mixing make variables and additional compiler/linker flags as
1144 ***** configure command line option is not permitted.
1145 ***** Affected make variables: $names
1150 # Check through all supported command line variables to see if any of them
1151 # were set, and canonicalise the values we got. If no compiler or linker
1152 # flag or anything else that affects %useradd was set, we also check the
1153 # environment for values.
1155 grep { defined $_ && (ref $_ ne 'ARRAY' || @$_) } values %useradd;
1156 foreach (keys %user) {
1157 my $value = $cmdvars{$_};
1158 $value //= env($_) unless $anyuseradd;
1160 defined $user_synonyms{$_} ? $cmdvars{$user_synonyms{$_}} : undef;
1161 $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef
1164 if (defined $value) {
1165 if (ref $user{$_} eq 'ARRAY') {
1166 if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') {
1167 $user{$_} = [ split /$list_separator_re/, $value ];
1169 $user{$_} = [ $value ];
1171 } elsif (!defined $user{$_}) {
1177 if (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ())
1178 && !$disabled{shared}
1179 && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
1180 die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
1181 "***** any of asan, msan or ubsan\n";
1184 # If no target was given, try guessing.
1186 my %system_config = OpenSSL::config::get_platform(%guess_opts, %user);
1188 # The $system_config{disable} is used to populate %disabled with
1189 # entries that aren't already there.
1190 foreach ( @{$system_config{disable} // []} ) {
1191 $disabled{$_} = 'system' unless defined $disabled{$_};
1193 delete $system_config{disable};
1195 # Override config entries with stuff from the guesser.
1196 # It's assumed that this really is nothing new.
1197 %config = ( %config, %system_config );
1198 $target = $system_config{target};
1202 my $disable_type = shift;
1205 $disabled{$_} = $disable_type;
1208 my @tocheckfor = (@_ ? @_ : keys %disabled);
1209 while (@tocheckfor) {
1210 my %new_tocheckfor = ();
1211 my @cascade_copy = (@disable_cascades);
1212 while (@cascade_copy) {
1213 my ($test, $descendents) =
1214 (shift @cascade_copy, shift @cascade_copy);
1215 if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
1216 foreach (grep { !defined($disabled{$_}) } @$descendents) {
1217 $new_tocheckfor{$_} = 1; $disabled{$_} = "cascade";
1221 @tocheckfor = (keys %new_tocheckfor);
1224 disable(); # First cascade run
1226 our $die = sub { die @_; };
1227 if ($target eq "TABLE") {
1228 local $die = sub { warn @_; };
1229 foreach (sort keys %table) {
1230 print_table_entry($_, "TABLE");
1235 if ($target eq "LIST") {
1236 foreach (sort keys %table) {
1237 print $_,"\n" unless $table{$_}->{template};
1242 if ($target eq "HASH") {
1243 local $die = sub { warn @_; };
1244 print "%table = (\n";
1245 foreach (sort keys %table) {
1246 print_table_entry($_, "HASH");
1251 print "Configuring OpenSSL version $config{full_version} ";
1252 print "for target $target\n";
1254 if (scalar(@seed_sources) == 0) {
1255 print "Using os-specific seed configuration\n";
1256 push @seed_sources, 'os';
1258 if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) {
1259 delete $disabled{'egd'};
1261 if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
1262 die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
1263 warn <<_____ if scalar(@seed_sources) == 1;
1265 ============================== WARNING ===============================
1266 You have selected the --with-rand-seed=none option, which effectively
1267 disables automatic reseeding of the OpenSSL random generator.
1268 All operations depending on the random generator such as creating keys
1269 will not work unless the random generator is seeded manually by the
1272 Please read the 'Note on random number generation' section in the
1273 INSTALL.md instructions and the RAND_DRBG(7) manual page for more
1275 ============================== WARNING ===============================
1279 push @{$config{openssl_feature_defines}},
1280 map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
1283 # Backward compatibility?
1284 if ($target =~ m/^CygWin32(-.*)$/) {
1285 $target = "Cygwin".$1;
1288 # Support for legacy targets having a name starting with 'debug-'
1289 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
1291 $config{build_type} = "debug";
1293 # If we do not find debug-foo in the table, the target is set to foo.
1294 if (!$table{$target}) {
1300 # It's possible that we have different config targets for specific
1301 # toolchains, so we try to detect them, and go for the plain config
1304 foreach ( ( "$target-$user{CC}", "$target", undef ) ) {
1305 $found=$_ if $table{$_} && !$table{$_}->{template};
1310 # If we don't have a config target now, we try the C compiler as we
1312 my $cc = $user{CC} // 'cc';
1313 $target = $cc if $table{$cc} && !$table{$cc}->{template};
1316 &usage unless $target;
1318 exit 0 if $dryrun; # From older 'config'
1320 $config{target} = $target;
1321 my %target = resolve_config($target);
1323 foreach (keys %target_attr_translate) {
1324 $target{$target_attr_translate{$_}} = $target{$_}
1329 %target = ( %{$table{DEFAULTS}}, %target );
1331 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
1332 $config{conf_files} = [ sort keys %conf_files ];
1334 # Using sub disable within these loops may prove fragile, so we run
1335 # a cascade afterwards
1336 foreach my $feature (@{$target{disable}}) {
1337 if (exists $deprecated_disablables{$feature}) {
1338 warn "***** config $target disables deprecated feature $feature\n";
1339 } elsif (!grep { $feature eq $_ } @disablables) {
1340 die "***** config $target disables unknown feature $feature\n";
1342 $disabled{$feature} = 'config';
1344 foreach my $feature (@{$target{enable}}) {
1345 if ("default" eq ($disabled{$feature} // "")) {
1346 if (exists $deprecated_disablables{$feature}) {
1347 warn "***** config $target enables deprecated feature $feature\n";
1348 } elsif (!grep { $feature eq $_ } @disablables) {
1349 die "***** config $target enables unknown feature $feature\n";
1351 delete $disabled{$feature};
1355 # If uplink_arch isn't defined, disable uplink
1356 $disabled{uplink} = 'no uplink_arch' unless (defined $target{uplink_arch});
1357 # If asm_arch isn't defined, disable asm
1358 $disabled{asm} = 'no asm_arch' unless (defined $target{asm_arch});
1360 disable(); # Run a cascade now
1362 $target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX};
1363 $target{cxxflags}//=$target{cflags} if $target{CXX};
1364 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP");
1365 $target{exe_extension}=".pm" if ($config{target} =~ /vos/);
1367 # Fill %config with values from %user, and in case those are undefined or
1368 # empty, use values from %target (acting as a default).
1369 foreach (keys %user) {
1370 my $ref_type = ref $user{$_};
1372 # Temporary function. Takes an intended ref type (empty string or "ARRAY")
1373 # and a value that's to be coerced into that type.
1377 my $undef_p = shift;
1379 die "Too many arguments for \$mkvalue" if @_;
1381 while (ref $value eq 'CODE') {
1382 $value = $value->();
1385 if ($type eq 'ARRAY') {
1386 return undef unless defined $value;
1387 return undef if ref $value ne 'ARRAY' && !$value;
1388 return undef if ref $value eq 'ARRAY' && !@$value;
1389 return [ $value ] unless ref $value eq 'ARRAY';
1391 return undef unless $value;
1396 $mkvalue->($ref_type, $user{$_})
1397 || $mkvalue->($ref_type, $target{$_});
1398 delete $config{$_} unless defined $config{$_};
1401 # Finish up %config by appending things the user gave us on the command line
1402 # apart from "make variables"
1403 foreach (keys %useradd) {
1404 # The must all be lists, so we assert that here
1405 die "internal error: \$useradd{$_} isn't an ARRAY\n"
1406 unless ref $useradd{$_} eq 'ARRAY';
1408 if (defined $config{$_}) {
1409 push @{$config{$_}}, @{$useradd{$_}};
1411 $config{$_} = [ @{$useradd{$_}} ];
1414 # At this point, we can forget everything about %user and %useradd,
1415 # because it's now all been merged into the corresponding $config entry
1417 if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) {
1418 disable('static', 'pic', 'threads');
1421 # Allow overriding the build file name
1422 $config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
1424 # Make sure build_scheme is consistent.
1425 $target{build_scheme} = [ $target{build_scheme} ]
1426 if ref($target{build_scheme}) ne "ARRAY";
1428 my ($builder, $builder_platform, @builder_opts) =
1429 @{$target{build_scheme}};
1431 foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm",
1432 $builder_platform."-checker.pm")) {
1433 my $checker_path = catfile($srcdir, "Configurations", $checker);
1434 if (-f $checker_path) {
1435 my $fn = $ENV{CONFIGURE_CHECKER_WARN}
1436 ? sub { warn $@; } : sub { die $@; };
1437 if (! do $checker_path) {
1443 $fn->("The detected tools didn't match the platform\n");
1450 push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
1452 if ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m)
1454 push @{$config{cflags}}, "-mno-cygwin";
1455 push @{$config{cxxflags}}, "-mno-cygwin" if $config{CXX};
1456 push @{$config{shared_ldflag}}, "-mno-cygwin";
1459 if ($target =~ /linux.*-mips/ && !$disabled{asm}
1460 && !grep { $_ !~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) {
1461 # minimally required architecture flags for assembly modules
1463 $value = '-mips2' if ($target =~ /mips32/);
1464 $value = '-mips3' if ($target =~ /mips64/);
1465 unshift @{$config{cflags}}, $value;
1466 unshift @{$config{cxxflags}}, $value if $config{CXX};
1469 # If threads aren't disabled, check how possible they are
1470 unless ($disabled{threads}) {
1471 if ($auto_threads) {
1472 # Enabled by default, disable it forcibly if unavailable
1473 if ($target{thread_scheme} eq "(unknown)") {
1474 disable("unavailable", 'threads');
1477 # The user chose to enable threads explicitly, let's see
1478 # if there's a chance that's possible
1479 if ($target{thread_scheme} eq "(unknown)") {
1480 # If the user asked for "threads" and we don't have internal
1481 # knowledge how to do it, [s]he is expected to provide any
1482 # system-dependent compiler options that are necessary. We
1483 # can't truly check that the given options are correct, but
1484 # we expect the user to know what [s]He is doing.
1485 if (!@{$config{CFLAGS}} && !@{$config{CPPDEFINES}}) {
1486 die "You asked for multi-threading support, but didn't\n"
1487 ,"provide any system-specific compiler options\n";
1493 # Find out if clang's sanitizers have been enabled with -fsanitize
1494 # flags and ensure that the corresponding %disabled elements area
1495 # removed to reflect that the sanitizers are indeed enabled.
1496 my %detected_sanitizers = ();
1497 foreach (grep /^-fsanitize=/, @{$config{CFLAGS} || []}) {
1498 (my $checks = $_) =~ s/^-fsanitize=//;
1499 foreach (split /,/, $checks) {
1500 my $d = { address => 'asan',
1501 undefined => 'ubsan',
1502 memory => 'msan' } -> {$_};
1503 next unless defined $d;
1505 $detected_sanitizers{$d} = 1;
1506 if (defined $disabled{$d}) {
1507 die "***** Conflict between disabling $d and enabling $_ sanitizer"
1508 if $disabled{$d} ne "default";
1509 delete $disabled{$d};
1514 # If threads still aren't disabled, add a C macro to ensure the source
1515 # code knows about it. Any other flag is taken care of by the configs.
1516 unless($disabled{threads}) {
1517 push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
1520 my $no_shared_warn=0;
1521 if (($target{shared_target} // '') eq "")
1524 if (!$disabled{shared} || !$disabled{"dynamic-engine"});
1525 disable('no-shared-target', 'pic');
1528 if ($disabled{"dynamic-engine"}) {
1529 $config{dynamic_engines} = 0;
1531 $config{dynamic_engines} = 1;
1534 unless ($disabled{asan} || defined $detected_sanitizers{asan}) {
1535 push @{$config{cflags}}, "-fsanitize=address";
1538 unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) {
1539 push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC";
1542 unless ($disabled{msan} || defined $detected_sanitizers{msan}) {
1543 push @{$config{cflags}}, "-fsanitize=memory";
1546 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1547 && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1548 push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g";
1549 push @{$config{cxxflags}}, "-fno-omit-frame-pointer", "-g" if $config{CXX};
1555 # This saves the build files from having to check
1558 foreach (qw(shared_cflag shared_cxxflag shared_cppflag
1559 shared_defines shared_includes shared_ldflag
1560 module_cflags module_cxxflags module_cppflags
1561 module_defines module_includes module_lflags))
1569 push @{$config{lib_defines}}, "OPENSSL_PIC";
1572 if ($target{sys_id} ne "")
1574 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1577 my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC});
1578 my %predefined_CXX = $config{CXX}
1579 ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX})
1582 unless ($disabled{asm}) {
1583 # big endian systems can use ELFv2 ABI
1584 if ($target eq "linux-ppc64" || $target eq "BSD-ppc64") {
1585 $target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2);
1589 # Check for makedepend capabilities.
1590 if (!$disabled{makedepend}) {
1591 # If the attribute makedep_scheme is defined, then we assume that the
1592 # config target and its associated build file are programmed to deal
1594 # If makedep_scheme is undefined, we go looking for GCC compatible
1595 # dependency making, and if that's not available, we try to fall back
1597 if ($target{makedep_scheme}) {
1598 $config{makedep_scheme} = $target{makedep_scheme};
1599 # If the makedepcmd attribute is defined, copy it. If not, the
1600 # build files will have to fend for themselves.
1601 $config{makedepcmd} = $target{makedepcmd} if $target{makedepcmd};
1602 } elsif (($predefined_C{__GNUC__} // -1) >= 3
1603 && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) {
1604 # We know that GNU C version 3 and up as well as all clang
1605 # versions support dependency generation, but Xcode did not
1606 # handle $cc -M before clang support (but claims __GNUC__ = 3)
1607 $config{makedep_scheme} = 'gcc';
1609 # In all other cases, we look for 'makedepend', and set the
1610 # makedep_scheme value if we found it.
1611 $config{makedepcmd} = which('makedepend');
1612 $config{makedep_scheme} = 'makedepend' if $config{makedepcmd};
1615 # If no depend scheme is set, we disable makedepend
1616 disable('unavailable', 'makedepend') unless $config{makedep_scheme};
1619 if (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') {
1620 # probe for -Wa,--noexecstack option...
1621 if ($predefined_C{__clang__}) {
1622 # clang has builtin assembler, which doesn't recognize --help,
1623 # but it apparently recognizes the option in question on all
1624 # supported platforms even when it's meaningless. In other words
1625 # probe would fail, but probed option always accepted...
1626 push @{$config{cflags}}, "-Wa,--noexecstack", "-Qunused-arguments";
1628 my $cc = $config{CROSS_COMPILE}.$config{CC};
1629 open(PIPE, "$cc -Wa,--help -c -o null.$$.o -x assembler /dev/null 2>&1 |");
1631 if (m/--noexecstack/) {
1632 push @{$config{cflags}}, "-Wa,--noexecstack";
1637 unlink("null.$$.o");
1641 # Deal with bn_ops ###################################################
1644 my $def_int="unsigned int";
1645 $config{rc4_int} =$def_int;
1646 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1649 foreach (sort split(/\s+/,$target{bn_ops})) {
1650 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1651 $config{bn_ll}=1 if $_ eq 'BN_LLONG';
1652 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
1653 ($config{b64l},$config{b64},$config{b32})
1654 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
1655 ($config{b64l},$config{b64},$config{b32})
1656 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
1657 ($config{b64l},$config{b64},$config{b32})
1658 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
1660 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1663 $config{api} = $config{major} * 10000 + $config{minor} * 100
1664 unless $config{api};
1665 foreach (keys %$apitable) {
1666 $disabled{"deprecated-$_"} = "deprecation"
1667 if $disabled{deprecated} && $config{api} >= $apitable->{$_};
1670 disable(); # Run a cascade now
1672 # Hack cflags for better warnings (dev option) #######################
1674 # "Stringify" the C and C++ flags string. This permits it to be made part of
1675 # a string and works as well on command lines.
1676 $config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1677 @{$config{cflags}} ];
1678 $config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1679 @{$config{cxxflags}} ] if $config{CXX};
1681 $config{openssl_api_defines} = [
1682 "OPENSSL_CONFIGURED_API=".$config{api},
1685 my @strict_warnings_collection=();
1686 if ($strict_warnings)
1689 my $gccver = $predefined_C{__GNUC__} // -1;
1693 push @strict_warnings_collection, @gcc_devteam_warn;
1694 push @strict_warnings_collection, @clang_devteam_warn
1695 if (defined($predefined_C{__clang__}));
1697 elsif ($config{target} =~ /^VC-/)
1699 push @strict_warnings_collection, @cl_devteam_warn;
1703 warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC"
1707 $config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings'
1708 ? @strict_warnings_collection
1710 @{$config{CFLAGS}} ];
1712 unless ($disabled{afalgeng}) {
1713 $config{afalgeng}="";
1714 if (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
1715 push @{$config{engdirs}}, "afalg";
1717 disable('not-linux', 'afalgeng');
1721 unless ($disabled{devcryptoeng}) {
1722 if ($target =~ m/^BSD/) {
1723 my $maxver = 5*100 + 7;
1724 my $sysstr = `uname -s`;
1725 my $verstr = `uname -r`;
1728 my ($ma, $mi, @rest) = split m|\.|, $verstr;
1729 my $ver = $ma*100 + $mi;
1730 if ($sysstr eq 'OpenBSD' && $ver >= $maxver) {
1731 disable('too-new-kernel', 'devcryptoeng');
1736 unless ($disabled{ktls}) {
1738 my $cc = $config{CROSS_COMPILE}.$config{CC};
1739 if ($target =~ m/^linux/) {
1740 system("printf '#include <sys/types.h>\n#include <linux/tls.h>' | $cc -E - >/dev/null 2>&1");
1742 disable('too-old-kernel', 'ktls');
1744 } elsif ($target =~ m/^BSD/) {
1745 system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1");
1747 disable('too-old-freebsd', 'ktls');
1750 disable('not-linux-or-freebsd', 'ktls');
1754 unless ($disabled{winstore}) {
1755 unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) {
1756 disable('not-windows', 'winstore');
1760 push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
1762 # Get the extra flags used when building shared libraries and modules. We
1763 # do this late because some of them depend on %disabled.
1765 # Make the flags to build DSOs the same as for shared libraries unless they
1766 # are already defined
1767 $target{module_cflags} = $target{shared_cflag} unless defined $target{module_cflags};
1768 $target{module_cxxflags} = $target{shared_cxxflag} unless defined $target{module_cxxflags};
1769 $target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_ldflags};
1771 my $shared_info_pl =
1772 catfile(dirname($0), "Configurations", "shared-info.pl");
1773 my %shared_info = read_eval_file($shared_info_pl);
1774 push @{$target{_conf_fname_int}}, $shared_info_pl;
1775 my $si = $target{shared_target};
1776 while (ref $si ne "HASH") {
1777 last if ! defined $si;
1778 if (ref $si eq "CODE") {
1781 $si = $shared_info{$si};
1785 # Some of the 'shared_target' values don't have any entries in
1786 # %shared_info. That's perfectly fine, AS LONG AS the build file
1787 # template knows how to handle this. That is currently the case for
1790 # Just as above, copy certain shared_* attributes to the corresponding
1791 # module_ attribute unless the latter is already defined
1792 $si->{module_cflags} = $si->{shared_cflag} unless defined $si->{module_cflags};
1793 $si->{module_cxxflags} = $si->{shared_cxxflag} unless defined $si->{module_cxxflags};
1794 $si->{module_ldflags} = $si->{shared_ldflag} unless defined $si->{module_ldflags};
1795 foreach (sort keys %$si) {
1796 $target{$_} = defined $target{$_}
1797 ? add($si->{$_})->($target{$_})
1803 # ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON
1805 ######################################################################
1806 # Build up information for skipping certain directories depending on disabled
1807 # features, as well as setting up macros for disabled features.
1809 # This is a tentative database of directories to skip. Some entries may not
1810 # correspond to anything real, but that's ok, they will simply be ignored.
1811 # The actual processing of these entries is done in the build.info lookup
1812 # loop further down.
1814 # The key is a Unix formatted path in the source tree, the value is an index
1815 # into %disabled_info, so any existing path gets added to a corresponding
1816 # 'skipped' entry in there with the list of skipped directories.
1818 my %disabled_info = (); # For configdata.pm
1819 foreach my $what (sort keys %disabled) {
1820 # There are deprecated disablables that translate to themselves.
1821 # They cause disabling cascades, but should otherwise not register.
1822 next if $deprecated_disablables{$what};
1823 # The generated $disabled{"deprecated-x.y"} entries are special
1824 # and treated properly elsewhere
1825 next if $what =~ m|^deprecated-|;
1827 $config{options} .= " no-$what";
1829 if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
1830 'module', 'pic', 'dynamic-engine', 'makedepend',
1831 'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) {
1832 (my $WHAT = uc $what) =~ s|-|_|g;
1833 my $skipdir = $what;
1835 # fix-up crypto/directory name(s)
1836 $skipdir = "ripemd" if $what eq "rmd160";
1837 $skipdir = "whrlpool" if $what eq "whirlpool";
1839 my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT";
1840 push @{$config{openssl_feature_defines}}, $macro;
1842 $skipdir{engines} = $what if $what eq 'engine';
1843 $skipdir{"crypto/$skipdir"} = $what
1844 unless $what eq 'async' || $what eq 'err' || $what eq 'dso';
1848 if ($disabled{"dynamic-engine"}) {
1849 push @{$config{openssl_feature_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1851 push @{$config{openssl_feature_defines}}, "OPENSSL_NO_STATIC_ENGINE";
1854 # If we use the unified build, collect information from build.info files
1855 my %unified_info = ();
1857 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1858 if ($builder eq "unified") {
1859 use Text::Template 1.46;
1864 my $relativeto = shift || ".";
1866 $dir = catdir($base,$dir) unless isabsolute($dir);
1868 # Make sure the directories we're building in exists
1871 my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1872 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1879 my $relativeto = shift || ".";
1881 $file = catfile($base,$file) unless isabsolute($file);
1883 my $d = dirname($file);
1884 my $f = basename($file);
1886 # Make sure the directories we're building in exists
1889 my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1890 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1894 # Store the name of the template file we will build the build file from
1895 # in %config. This may be useful for the build file itself.
1896 my @build_file_template_names =
1897 ( $builder_platform."-".$target{build_file}.".tmpl",
1898 $target{build_file}.".tmpl" );
1899 my @build_file_templates = ();
1901 # First, look in the user provided directory, if given
1902 if (defined env($local_config_envname)) {
1903 @build_file_templates =
1906 # VMS environment variables are logical names,
1907 # which can be used as is
1908 $local_config_envname . ':' . $_;
1910 catfile(env($local_config_envname), $_);
1913 @build_file_template_names;
1915 # Then, look in our standard directory
1916 push @build_file_templates,
1917 ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1918 @build_file_template_names );
1920 my $build_file_template;
1921 for $_ (@build_file_templates) {
1922 $build_file_template = $_;
1923 last if -f $build_file_template;
1925 $build_file_template = undef;
1927 if (!defined $build_file_template) {
1928 die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1930 $config{build_file_templates}
1931 = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"),
1933 $build_file_template ];
1935 my @build_dirs = ( [ ] ); # current directory
1937 $config{build_infos} = [ ];
1939 # We want to detect configdata.pm in the source tree, so we
1940 # don't use it if the build tree is different.
1941 my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir);
1943 # Any source file that we recognise is placed in this hash table, with
1944 # the list of its intended destinations as value. When everything has
1945 # been collected, there's a routine that checks that these source files
1946 # exist, or if they are generated, that the generator exists.
1947 my %check_exist = ();
1948 my %check_generate = ();
1951 while (@build_dirs) {
1952 my @curd = @{shift @build_dirs};
1953 my $sourced = catdir($srcdir, @curd);
1954 my $buildd = catdir($blddir, @curd);
1956 my $unixdir = join('/', @curd);
1957 if (exists $skipdir{$unixdir}) {
1958 my $what = $skipdir{$unixdir};
1959 push @{$disabled_info{$what}->{skipped}}, catdir(@curd);
1965 my $f = 'build.info';
1966 # The basic things we're trying to build
1973 my %shared_sources = ();
1982 # Support for $variablename in build.info files.
1983 # Embedded perl code is the ultimate master, still. If its output
1984 # contains a dollar sign, it had better be escaped, or it will be
1985 # taken for a variable name prefix.
1987 # Variable name syntax
1988 my $variable_name_re = qr/(?P<VARIABLE>[[:alpha:]][[:alnum:]_]*)/;
1989 # Value modifier syntaxes
1990 my $variable_subst_re = qr/\/(?P<RE>(?:\\\/|.)*?)\/(?P<SUBST>.*?)/;
1991 # Variable reference
1992 my $variable_simple_re = qr/(?<!\\)\$${variable_name_re}/;
1993 my $variable_w_mod_re =
1994 qr/(?<!\\)\$\{${variable_name_re}(?P<MOD>(?:\\\/|.)*?)\}/;
1995 # Tie it all together
1996 my $variable_re = qr/${variable_simple_re}|${variable_w_mod_re}/;
1998 my $expand_variables = sub {
2000 my $value_rest = shift;
2002 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2004 "DEBUG[\$expand_variables] Parsed '$value_rest' ...\n"
2007 while ($value_rest =~ /${variable_re}/) {
2008 # We must save important regexp values, because the next
2009 # regexp clears them
2011 my $variable_value = $variables{$+{VARIABLE}};
2016 # Process modifier expressions, if present
2018 if ($mod =~ /^${variable_subst_re}$/) {
2020 my $subst = $+{SUBST};
2022 $variable_value =~ s/\Q$re\E/$subst/g;
2024 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2026 "DEBUG[\$expand_variables] ... and substituted ",
2027 "'$re' with '$subst'\n";
2032 $value .= $variable_value;
2034 if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
2036 "DEBUG[\$expand_variables] ... into: '$value$value_rest'\n";
2038 return $value . $value_rest;
2041 # Support for attributes in build.info files
2042 my %attributes = ();
2043 my $handle_attributes = sub {
2044 my $attr_str = shift;
2048 return unless defined $attr_str;
2050 my @a = tokenize($attr_str, qr|\s*,\s*|);
2051 foreach my $a (@a) {
2055 if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) {
2060 foreach my $g (@goals) {
2062 $$ref->{$g}->{$ak} = $av;
2064 delete $$ref->{$g}->{$ak};
2070 # Support for pushing values on multiple indexes of a given hash
2073 my $valueref = shift;
2074 my $index_str = shift; # May be undef or empty
2075 my $attrref = shift; # May be undef
2076 my $attr_str = shift;
2079 if (defined $index_str) {
2080 my @indexes = ( '' );
2081 if ($index_str !~ m|^\s*$|) {
2082 @indexes = tokenize($index_str);
2084 foreach (@indexes) {
2085 push @{$valueref->{$_}}, @values;
2086 if (defined $attrref) {
2087 $handle_attributes->($attr_str, \$$attrref->{$_},
2092 push @$valueref, @values;
2093 $handle_attributes->($attr_str, $attrref, @values)
2094 if defined $attrref;
2098 if ($buildinfo_debug) {
2099 print STDERR "DEBUG: Reading ",catfile($sourced, $f),"\n";
2101 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
2103 Text::Template->new(TYPE => 'FILE',
2104 SOURCE => catfile($sourced, $f),
2105 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
2106 die "Something went wrong with $sourced/$f: $!\n" unless $template;
2109 $template->fill_in(HASH => { config => \%config,
2111 disabled => \%disabled,
2112 withargs => \%withargs,
2113 builddir => abs2rel($buildd, $blddir),
2114 sourcedir => abs2rel($sourced, $blddir),
2115 buildtop => abs2rel($blddir, $blddir),
2116 sourcetop => abs2rel($srcdir, $blddir) },
2117 DELIMITERS => [ "{-", "-}" ]);
2119 # The top item of this stack has the following values
2120 # -2 positive already run and we found ELSE (following ELSIF should fail)
2121 # -1 positive already run (skip until ENDIF)
2122 # 0 negatives so far (if we're at a condition, check it)
2123 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
2124 # 2 positive ELSE (following ELSIF should fail)
2127 # A few useful generic regexps
2128 my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/;
2129 my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/;
2130 my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/;
2131 my $value_re = qr/(?P<VALUE>.*?)/;
2132 collect_information(
2133 collect_from_array([ @text ],
2134 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
2135 $l1 =~ s/\\$//; $l1.$l2 }),
2136 # Info we're looking for
2137 qr/^\s* IF ${cond_re} \s*$/x
2139 if (! @skip || $skip[$#skip] > 0) {
2140 push @skip, !! $expand_variables->($+{COND});
2145 qr/^\s* ELSIF ${cond_re} \s*$/x
2146 => sub { die "ELSIF out of scope" if ! @skip;
2147 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
2148 $skip[$#skip] = -1 if $skip[$#skip] != 0;
2149 $skip[$#skip] = !! $expand_variables->($+{COND})
2150 if $skip[$#skip] == 0; },
2152 => sub { die "ELSE out of scope" if ! @skip;
2153 $skip[$#skip] = -2 if $skip[$#skip] != 0;
2154 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
2155 qr/^\s* ENDIF \s*$/x
2156 => sub { die "ENDIF out of scope" if ! @skip;
2158 qr/^\s* ${variable_re} \s* = \s* ${value_re} \s* $/x
2160 if (!@skip || $skip[$#skip] > 0) {
2161 $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE});
2164 qr/^\s* SUBDIRS \s* = \s* ${value_re} \s* $/x
2166 if (!@skip || $skip[$#skip] > 0) {
2167 foreach (tokenize($expand_variables->($+{VALUE}))) {
2168 push @build_dirs, [ @curd, splitdir($_, 1) ];
2172 qr/^\s* PROGRAMS ${attribs_re} \s* = \s* ${value_re} \s* $/x
2173 => sub { $push_to->(\@programs, undef,
2174 \$attributes{programs}, $+{ATTRIBS},
2175 tokenize($expand_variables->($+{VALUE})))
2176 if !@skip || $skip[$#skip] > 0; },
2177 qr/^\s* LIBS ${attribs_re} \s* = \s* ${value_re} \s* $/x
2178 => sub { $push_to->(\@libraries, undef,
2179 \$attributes{libraries}, $+{ATTRIBS},
2180 tokenize($expand_variables->($+{VALUE})))
2181 if !@skip || $skip[$#skip] > 0; },
2182 qr/^\s* MODULES ${attribs_re} \s* = \s* ${value_re} \s* $/x
2183 => sub { $push_to->(\@modules, undef,
2184 \$attributes{modules}, $+{ATTRIBS},
2185 tokenize($expand_variables->($+{VALUE})))
2186 if !@skip || $skip[$#skip] > 0; },
2187 qr/^\s* SCRIPTS ${attribs_re} \s* = \s* ${value_re} \s* $/x
2188 => sub { $push_to->(\@scripts, undef,
2189 \$attributes{scripts}, $+{ATTRIBS},
2190 tokenize($expand_variables->($+{VALUE})))
2191 if !@skip || $skip[$#skip] > 0; },
2192 qr/^\s* IMAGEDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2193 => sub { $push_to->(\%imagedocs, $expand_variables->($+{INDEX}),
2195 tokenize($expand_variables->($+{VALUE})))
2196 if !@skip || $skip[$#skip] > 0; },
2197 qr/^\s* HTMLDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2198 => sub { $push_to->(\%htmldocs, $expand_variables->($+{INDEX}),
2200 tokenize($expand_variables->($+{VALUE})))
2201 if !@skip || $skip[$#skip] > 0; },
2202 qr/^\s* MANDOCS ${index_re} \s* = \s* ${value_re} \s* $/x
2203 => sub { $push_to->(\%mandocs, $expand_variables->($+{INDEX}),
2205 tokenize($expand_variables->($+{VALUE})))
2206 if !@skip || $skip[$#skip] > 0; },
2207 qr/^\s* SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2208 => sub { $push_to->(\%sources, $expand_variables->($+{INDEX}),
2209 \$attributes{sources}, $+{ATTRIBS},
2210 tokenize($expand_variables->($+{VALUE})))
2211 if !@skip || $skip[$#skip] > 0; },
2212 qr/^\s* SHARED_SOURCE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2213 => sub { $push_to->(\%shared_sources, $expand_variables->($+{INDEX}),
2214 \$attributes{sources}, $+{ATTRIBS},
2215 tokenize($expand_variables->($+{VALUE})))
2216 if !@skip || $skip[$#skip] > 0; },
2217 qr/^\s* INCLUDE ${index_re} \s* = \s* ${value_re} \s* $/x
2218 => sub { $push_to->(\%includes, $expand_variables->($+{INDEX}),
2220 tokenize($expand_variables->($+{VALUE})))
2221 if !@skip || $skip[$#skip] > 0; },
2222 qr/^\s* DEFINE ${index_re} \s* = \s* ${value_re} \s* $/x
2223 => sub { $push_to->(\%defines, $expand_variables->($+{INDEX}),
2225 tokenize($expand_variables->($+{VALUE})))
2226 if !@skip || $skip[$#skip] > 0; },
2227 qr/^\s* DEPEND ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2228 => sub { $push_to->(\%depends, $expand_variables->($+{INDEX}),
2229 \$attributes{depends}, $+{ATTRIBS},
2230 tokenize($expand_variables->($+{VALUE})))
2231 if !@skip || $skip[$#skip] > 0; },
2232 qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
2233 => sub { $push_to->(\%generate, $expand_variables->($+{INDEX}),
2234 \$attributes{generate}, $+{ATTRIBS},
2235 $expand_variables->($+{VALUE}))
2236 if !@skip || $skip[$#skip] > 0; },
2237 qr/^\s* (?:\#.*)? $/x => sub { },
2238 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
2240 if ($buildinfo_debug) {
2241 print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
2242 print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2246 if ($buildinfo_debug) {
2247 print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
2251 die "runaway IF?" if (@skip);
2253 if (grep { defined $attributes{modules}->{$_}->{engine} } keys %attributes
2254 and !$config{dynamic_engines}) {
2256 ENGINES can only be used if configured with 'dynamic-engine'.
2257 This is usually a fault in a build.info file.
2262 my %infos = ( programs => [ @programs ],
2263 libraries => [ @libraries ],
2264 modules => [ @modules ],
2265 scripts => [ @scripts ] );
2266 foreach my $k (keys %infos) {
2267 foreach (@{$infos{$k}}) {
2268 my $item = cleanfile($buildd, $_, $blddir);
2269 $unified_info{$k}->{$item} = 1;
2271 # Fix up associated attributes
2272 $unified_info{attributes}->{$k}->{$item} =
2273 $attributes{$k}->{$_}
2274 if defined $attributes{$k}->{$_};
2279 # Check that we haven't defined any library as both shared and
2280 # explicitly static. That is forbidden.
2282 foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
2283 (my $l = $_) =~ s/\.a$//;
2284 push @doubles, $l if defined $unified_info{libraries}->{$l};
2286 die "these libraries are both explicitly static and shared:\n ",
2287 join(" ", @doubles), "\n"
2290 foreach (keys %sources) {
2292 my $ddest = cleanfile($buildd, $_, $blddir);
2293 foreach (@{$sources{$dest}}) {
2294 my $s = cleanfile($sourced, $_, $blddir);
2296 # If it's generated or we simply don't find it in the source
2297 # tree, we assume it's in the build tree.
2298 if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
2299 $s = cleanfile($buildd, $_, $blddir);
2302 # We recognise C++, C and asm files
2303 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
2304 push @{$check_exist{$s}}, $ddest;
2305 $o =~ s/\.[csS]$/.o/; # C and assembler
2306 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2307 $o = cleanfile($buildd, $o, $blddir);
2308 $unified_info{sources}->{$ddest}->{$o} = -1;
2309 $unified_info{sources}->{$o}->{$s} = -1;
2310 } elsif ($s =~ /\.rc$/) {
2311 # We also recognise resource files
2312 push @{$check_exist{$s}}, $ddest;
2313 $o =~ s/\.rc$/.res/; # Resource configuration
2314 $o = cleanfile($buildd, $o, $blddir);
2315 $unified_info{sources}->{$ddest}->{$o} = -1;
2316 $unified_info{sources}->{$o}->{$s} = -1;
2318 push @{$check_exist{$s}}, $ddest;
2319 $unified_info{sources}->{$ddest}->{$s} = 1;
2321 # Fix up associated attributes
2323 $unified_info{attributes}->{sources}->{$ddest}->{$o} =
2324 $unified_info{attributes}->{sources}->{$o}->{$s} =
2325 $attributes{sources}->{$dest}->{$_}
2326 if defined $attributes{sources}->{$dest}->{$_};
2328 $unified_info{attributes}->{sources}->{$ddest}->{$s} =
2329 $attributes{sources}->{$dest}->{$_}
2330 if defined $attributes{sources}->{$dest}->{$_};
2335 foreach (keys %shared_sources) {
2337 my $ddest = cleanfile($buildd, $_, $blddir);
2338 foreach (@{$shared_sources{$dest}}) {
2339 my $s = cleanfile($sourced, $_, $blddir);
2341 # If it's generated or we simply don't find it in the source
2342 # tree, we assume it's in the build tree.
2343 if ($s eq $src_configdata || $generate{$_} || ! -f $s) {
2344 $s = cleanfile($buildd, $_, $blddir);
2348 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
2349 # We recognise C++, C and asm files
2350 push @{$check_exist{$s}}, $ddest;
2351 $o =~ s/\.[csS]$/.o/; # C and assembler
2352 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
2353 $o = cleanfile($buildd, $o, $blddir);
2354 $unified_info{shared_sources}->{$ddest}->{$o} = -1;
2355 $unified_info{sources}->{$o}->{$s} = -1;
2356 } elsif ($s =~ /\.rc$/) {
2357 # We also recognise resource files
2358 push @{$check_exist{$s}}, $ddest;
2359 $o =~ s/\.rc$/.res/; # Resource configuration
2360 $o = cleanfile($buildd, $o, $blddir);
2361 $unified_info{shared_sources}->{$ddest}->{$o} = -1;
2362 $unified_info{sources}->{$o}->{$s} = -1;
2363 } elsif ($s =~ /\.ld$/) {
2364 # We also recognise linker scripts (or corresponding)
2365 # We know they are generated files
2366 push @{$check_exist{$s}}, $ddest;
2367 $o = cleanfile($buildd, $_, $blddir);
2368 $unified_info{shared_sources}->{$ddest}->{$o} = 1;
2370 die "unrecognised source file type for shared library: $s\n";
2372 # Fix up associated attributes
2374 $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
2375 $unified_info{attributes}->{sources}->{$o}->{$s} =
2376 $attributes{sources}->{$dest}->{$_}
2377 if defined $attributes{sources}->{$dest}->{$_};
2379 $unified_info{attributes}->{shared_sources}->{$ddest}->{$o} =
2380 $attributes{sources}->{$dest}->{$_}
2381 if defined $attributes{sources}->{$dest}->{$_};
2386 foreach (keys %generate) {
2388 my $ddest = cleanfile($buildd, $_, $blddir);
2389 die "more than one generator for $dest: "
2390 ,join(" ", @{$generate{$_}}),"\n"
2391 if scalar @{$generate{$_}} > 1;
2392 my @generator = split /\s+/, $generate{$dest}->[0];
2393 my $gen = $generator[0];
2394 $generator[0] = cleanfile($sourced, $gen, $blddir);
2396 # If the generator is itself generated, it's in the build tree
2397 if ($generate{$gen} || ! -f $generator[0]) {
2398 $generator[0] = cleanfile($buildd, $gen, $blddir);
2400 $check_generate{$ddest}->{$generator[0]}++;
2402 $unified_info{generate}->{$ddest} = [ @generator ];
2403 # Fix up associated attributes
2404 $unified_info{attributes}->{generate}->{$ddest} =
2405 $attributes{generate}->{$dest}->{$gen}
2406 if defined $attributes{generate}->{$dest}->{$gen};
2409 foreach (keys %depends) {
2413 if ($dest =~ /^\|(.*)\|$/) {
2414 # Collect the raw target
2415 $unified_info{targets}->{$1} = 1;
2417 } elsif ($dest eq '') {
2420 $ddest = cleanfile($sourced, $_, $blddir);
2422 # If the destination doesn't exist in source, it can only be
2423 # a generated file in the build tree.
2424 if ($ddest eq $src_configdata || ! -f $ddest) {
2425 $ddest = cleanfile($buildd, $_, $blddir);
2428 foreach (@{$depends{$dest}}) {
2429 my $d = cleanfile($sourced, $_, $blddir);
2430 my $d2 = cleanfile($buildd, $_, $blddir);
2432 # If we know it's generated, or assume it is because we can't
2433 # find it in the source tree, we set file we depend on to be
2434 # in the build tree rather than the source tree.
2435 if ($d eq $src_configdata
2436 || (grep { $d2 eq $_ }
2437 keys %{$unified_info{generate}})
2441 $unified_info{depends}->{$ddest}->{$d} = 1;
2443 # Fix up associated attributes
2444 $unified_info{attributes}->{depends}->{$ddest}->{$d} =
2445 $attributes{depends}->{$dest}->{$_}
2446 if defined $attributes{depends}->{$dest}->{$_};
2450 foreach (keys %includes) {
2452 my $ddest = cleanfile($sourced, $_, $blddir);
2454 # If the destination doesn't exist in source, it can only be
2455 # a generated file in the build tree.
2456 if ($ddest eq $src_configdata || ! -f $ddest) {
2457 $ddest = cleanfile($buildd, $_, $blddir);
2459 foreach (@{$includes{$dest}}) {
2460 my $is = cleandir($sourced, $_, $blddir);
2461 my $ib = cleandir($buildd, $_, $blddir);
2462 push @{$unified_info{includes}->{$ddest}->{source}}, $is
2463 unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
2464 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
2465 unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
2469 foreach my $dest (keys %defines) {
2473 $ddest = cleanfile($sourced, $dest, $blddir);
2475 # If the destination doesn't exist in source, it can only
2476 # be a generated file in the build tree.
2478 $ddest = cleanfile($buildd, $dest, $blddir);
2481 foreach my $v (@{$defines{$dest}}) {
2482 $v =~ m|^([^=]*)(=.*)?$|;
2483 die "0 length macro name not permitted\n" if $1 eq "";
2485 die "$1 defined more than once\n"
2486 if defined $unified_info{defines}->{$ddest}->{$1};
2487 $unified_info{defines}->{$ddest}->{$1} = $2;
2489 die "$1 defined more than once\n"
2490 if grep { $v eq $_ } @{$config{defines}};
2491 push @{$config{defines}}, $v;
2496 foreach my $section (keys %imagedocs) {
2497 foreach (@{$imagedocs{$section}}) {
2498 my $imagedocs = cleanfile($buildd, $_, $blddir);
2499 $unified_info{imagedocs}->{$section}->{$imagedocs} = 1;
2503 foreach my $section (keys %htmldocs) {
2504 foreach (@{$htmldocs{$section}}) {
2505 my $htmldocs = cleanfile($buildd, $_, $blddir);
2506 $unified_info{htmldocs}->{$section}->{$htmldocs} = 1;
2510 foreach my $section (keys %mandocs) {
2511 foreach (@{$mandocs{$section}}) {
2512 my $mandocs = cleanfile($buildd, $_, $blddir);
2513 $unified_info{mandocs}->{$section}->{$mandocs} = 1;
2518 my $ordinals_text = join(', ', sort keys %ordinals);
2519 warn <<"EOF" if $ordinals_text;
2521 WARNING: ORDINALS were specified for $ordinals_text
2522 They are ignored and should be replaced with a combination of GENERATE,
2523 DEPEND and SHARED_SOURCE.
2526 # Check that each generated file is only generated once
2527 my $ambiguous_generation = 0;
2528 foreach (sort keys %check_generate) {
2529 my @generators = sort keys %{$check_generate{$_}};
2530 my $generators_txt = join(', ', @generators);
2531 if (scalar @generators > 1) {
2532 warn "$_ is GENERATEd by more than one generator ($generators_txt)\n";
2533 $ambiguous_generation++;
2535 if ($check_generate{$_}->{$generators[0]} > 1) {
2536 warn "INFO: $_ has more than one GENERATE declaration (same generator)\n"
2539 die "There are ambiguous source file generations\n"
2540 if $ambiguous_generation > 0;
2542 # All given source files should exist, or if generated, their
2543 # generator should exist. This loop ensures this is true.
2545 foreach my $orig (sort keys %check_exist) {
2546 foreach my $dest (@{$check_exist{$orig}}) {
2547 if ($orig ne $src_configdata) {
2548 if ($orig =~ /\.a$/) {
2549 # Static library names may be used as sources, so we
2550 # need to detect those and give them special treatment.
2551 unless (grep { $_ eq $orig }
2552 keys %{$unified_info{libraries}}) {
2553 warn "$orig is given as source for $dest, but no such library is built\n";
2557 # A source may be generated, and its generator may be
2558 # generated as well. We therefore loop to dig out the
2562 while (my @next = keys %{$check_generate{$gen}}) {
2567 if ($gen ne $orig) {
2569 warn "$orig is given as source for $dest, but its generator (leading to $gen) is missing\n";
2572 warn "$orig is given as source for $dest, but is missing\n";
2579 die "There are files missing\n" if $missing > 0;
2581 # Go through the sources of all libraries and check that the same basename
2582 # doesn't appear more than once. Some static library archivers depend on
2583 # them being unique.
2586 foreach my $prod (keys %{$unified_info{libraries}}) {
2588 map { keys %{$unified_info{sources}->{$_}} }
2589 keys %{$unified_info{sources}->{$prod}};
2592 # Count how many times a given each source basename
2593 # appears for each product.
2594 foreach my $src (@prod_sources) {
2595 $srccnt{basename $src}++;
2598 foreach my $src (keys %srccnt) {
2599 if ((my $cnt = $srccnt{$src}) > 1) {
2600 print STDERR "$src appears $cnt times for the product $prod\n";
2608 # Massage the result
2610 # If we depend on a header file or a perl module, add an inclusion of
2611 # its directory to allow smoothe inclusion
2612 foreach my $dest (keys %{$unified_info{depends}}) {
2613 next if $dest eq "";
2614 foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
2615 next unless $d =~ /\.(h|pm)$/;
2616 my $i = dirname($d);
2618 $d eq "configdata.pm" || defined($unified_info{generate}->{$d})
2619 ? 'build' : 'source';
2620 push @{$unified_info{includes}->{$dest}->{$spot}}, $i
2621 unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{$spot}};
2625 # Go through all intermediary files and change their names to something that
2626 # reflects what they will be built for. Note that for some source files,
2627 # this leads to duplicate object files because they are used multiple times.
2628 # the goal is to rename all object files according to this scheme:
2629 # {productname}-{midfix}-{origobjname}.[o|res]
2630 # the {midfix} is a keyword indicating the type of product, which is mostly
2631 # valuable for libraries since they come in two forms.
2633 # This also reorganises the {sources} and {shared_sources} so that the
2634 # former only contains ALL object files that are supposed to end up in
2635 # static libraries and programs, while the latter contains ALL object files
2636 # that are supposed to end up in shared libraries and DSOs.
2637 # The main reason for having two different source structures is to allow
2638 # the same name to be used for the static and the shared variants of a
2641 # Take copies so we don't get interference from added stuff
2642 my %unified_copy = ();
2643 foreach (('sources', 'shared_sources')) {
2644 $unified_copy{$_} = { %{$unified_info{$_}} }
2645 if defined($unified_info{$_});
2646 delete $unified_info{$_};
2648 foreach my $prodtype (('programs', 'libraries', 'modules', 'scripts')) {
2649 # $intent serves multi purposes:
2650 # - give a prefix for the new object files names
2651 # - in the case of libraries, rearrange the object files so static
2652 # libraries use the 'sources' structure exclusively, while shared
2653 # libraries use the 'shared_sources' structure exclusively.
2655 programs => { bin => { src => [ 'sources' ],
2656 dst => 'sources' } },
2657 libraries => { lib => { src => [ 'sources' ],
2659 shlib => { prodselect =>
2660 sub { grep !/\.a$/, @_ },
2663 dst => 'shared_sources' } },
2664 modules => { dso => { src => [ 'sources' ],
2665 dst => 'sources' } },
2666 scripts => { script => { src => [ 'sources' ],
2667 dst => 'sources' } }
2669 foreach my $kind (keys %$intent) {
2670 next if ($intent->{$kind}->{dst} eq 'shared_sources'
2671 && $disabled{shared});
2673 my @src = @{$intent->{$kind}->{src}};
2674 my $dst = $intent->{$kind}->{dst};
2675 my $prodselect = $intent->{$kind}->{prodselect} // sub { @_ };
2676 foreach my $prod ($prodselect->(keys %{$unified_info{$prodtype}})) {
2677 # %prod_sources has all applicable objects as keys, and
2678 # their corresponding sources as values
2680 map { $_ => [ keys %{$unified_copy{sources}->{$_}} ] }
2681 map { keys %{$unified_copy{$_}->{$prod}} }
2683 foreach (keys %prod_sources) {
2684 # Only affect object files and resource files,
2685 # the others simply get a new value
2686 # (+1 instead of -1)
2687 if ($_ =~ /\.(o|res)$/) {
2688 (my $prodname = $prod) =~ s|\.a$||;
2690 catfile(dirname($_),
2693 . '-' . basename($_));
2694 $unified_info{$dst}->{$prod}->{$newobj} = 1;
2695 foreach my $src (@{$prod_sources{$_}}) {
2696 $unified_info{sources}->{$newobj}->{$src} = 1;
2697 # Adjust source attributes
2698 my $attrs = $unified_info{attributes}->{sources};
2699 if (defined $attrs->{$prod}
2700 && defined $attrs->{$prod}->{$_}) {
2701 $attrs->{$prod}->{$newobj} =
2702 $attrs->{$prod}->{$_};
2703 delete $attrs->{$prod}->{$_};
2705 foreach my $objsrc (keys %{$attrs->{$_} // {}}) {
2706 $attrs->{$newobj}->{$objsrc} =
2707 $attrs->{$_}->{$objsrc};
2708 delete $attrs->{$_}->{$objsrc};
2711 # Adjust dependencies
2712 foreach my $deps (keys %{$unified_info{depends}->{$_}}) {
2713 $unified_info{depends}->{$_}->{$deps} = -1;
2714 $unified_info{depends}->{$newobj}->{$deps} = 1;
2717 foreach my $k (('source', 'build')) {
2719 defined($unified_info{includes}->{$_}->{$k});
2720 my @incs = @{$unified_info{includes}->{$_}->{$k}};
2721 $unified_info{includes}->{$newobj}->{$k} = [ @incs ];
2724 $unified_info{$dst}->{$prod}->{$_} = 1;
2732 # At this point, we have a number of sources with the value -1. They
2733 # aren't part of the local build and are probably meant for a different
2734 # platform, and can therefore be cleaned away. That happens when making
2735 # %unified_info more efficient below.
2737 ### Make unified_info a bit more efficient
2738 # One level structures
2739 foreach (("programs", "libraries", "modules", "scripts", "targets")) {
2740 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
2742 # Two level structures
2743 foreach my $l1 (("sources", "shared_sources", "ldadd", "depends",
2744 "imagedocs", "htmldocs", "mandocs")) {
2745 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
2748 grep { $unified_info{$l1}->{$l2}->{$_} > 0 }
2749 keys %{$unified_info{$l1}->{$l2}};
2751 $unified_info{$l1}->{$l2} = [ @items ];
2753 delete $unified_info{$l1}->{$l2};
2758 foreach my $dest (sort keys %{$unified_info{defines}}) {
2759 $unified_info{defines}->{$dest}
2760 = [ map { $_.$unified_info{defines}->{$dest}->{$_} }
2761 sort keys %{$unified_info{defines}->{$dest}} ];
2764 foreach my $dest (sort keys %{$unified_info{includes}}) {
2765 if (defined($unified_info{includes}->{$dest}->{build})) {
2766 my @source_includes = ();
2767 @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} )
2768 if defined($unified_info{includes}->{$dest}->{source});
2769 $unified_info{includes}->{$dest} =
2770 [ @{$unified_info{includes}->{$dest}->{build}} ];
2771 foreach my $inc (@source_includes) {
2772 push @{$unified_info{includes}->{$dest}}, $inc
2773 unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
2775 } elsif (defined($unified_info{includes}->{$dest}->{source})) {
2776 $unified_info{includes}->{$dest} =
2777 [ @{$unified_info{includes}->{$dest}->{source}} ];
2779 delete $unified_info{includes}->{$dest};
2783 # For convenience collect information regarding directories where
2784 # files are generated, those generated files and the end product
2785 # they end up in where applicable. Then, add build rules for those
2787 my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ],
2788 "dso" => [ @{$unified_info{modules}} ],
2789 "bin" => [ @{$unified_info{programs}} ],
2790 "script" => [ @{$unified_info{scripts}} ],
2791 "docs" => [ (map { @{$unified_info{imagedocs}->{$_} // []} }
2792 keys %{$unified_info{imagedocs} // {}}),
2793 (map { @{$unified_info{htmldocs}->{$_} // []} }
2794 keys %{$unified_info{htmldocs} // {}}),
2795 (map { @{$unified_info{mandocs}->{$_} // []} }
2796 keys %{$unified_info{mandocs} // {}}) ] );
2797 foreach my $type (sort keys %loopinfo) {
2798 foreach my $product (@{$loopinfo{$type}}) {
2800 my $pd = dirname($product);
2802 foreach (@{$unified_info{sources}->{$product} // []},
2803 @{$unified_info{shared_sources}->{$product} // []}) {
2804 my $d = dirname($_);
2806 # We don't want to create targets for source directories
2807 # when building out of source
2808 next if ($config{sourcedir} ne $config{builddir}
2809 && $d =~ m|^\Q$config{sourcedir}\E|);
2810 # We already have a "test" target, and the current directory
2811 # is just silly to make a target for
2812 next if $d eq "test" || $d eq ".";
2815 push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
2818 foreach (sort keys %dirs) {
2819 push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
2826 # For the schemes that need it, we provide the old *_obj configs
2827 # from the *_asm_obj ones
2828 foreach (grep /_(asm|aux)_src$/, keys %target) {
2830 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
2831 $target{$obj} = $target{$src};
2832 $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
2833 $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
2836 # Write down our configuration where it fits #########################
2838 my %template_vars = (
2841 disablables => \@disablables,
2842 disablables_int => \@disablables_int,
2843 disabled => \%disabled,
2844 withargs => \%withargs,
2845 unified_info => \%unified_info,
2848 makevars => [ sort keys %user ],
2849 disabled_info => \%disabled_info,
2850 user_crossable => \@user_crossable,
2852 my $configdata_outname = 'configdata.pm';
2853 open CONFIGDATA, ">$configdata_outname.new"
2854 or die "Trying to create $configdata_outname.new: $!";
2855 my $configdata_tmplname = cleanfile($srcdir, "configdata.pm.in", $blddir);
2856 my $configdata_tmpl =
2857 OpenSSL::Template->new(TYPE => 'FILE', SOURCE => $configdata_tmplname);
2858 $configdata_tmpl->fill_in(
2859 FILENAME => $configdata_tmplname,
2860 OUTPUT => \*CONFIGDATA,
2861 HASH => { %template_vars,
2863 'WARNING: do not edit!',
2864 "Generated by Configure from $configdata_tmplname",
2866 ) or die $Text::Template::ERROR;
2869 rename "$configdata_outname.new", $configdata_outname;
2870 if ($builder_platform eq 'unix') {
2871 my $mode = (0755 & ~umask);
2872 chmod $mode, 'configdata.pm'
2873 or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!);
2875 print "Created $configdata_outname\n";
2877 print "Running $configdata_outname\n";
2878 my $perlcmd = (quotify("maybeshell", $config{PERL}))[0];
2879 my $cmd = "$perlcmd $configdata_outname";
2880 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2884 $SIG{__DIE__} = $orig_death_handler;
2886 print <<"EOF" if ($disabled{threads} eq "unavailable");
2888 The library could not be configured for supporting multi-threaded
2889 applications as the compiler options required on this system are not known.
2890 See file INSTALL.md for details if you need multi-threading.
2893 print <<"EOF" if ($no_shared_warn);
2895 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2896 platform, so we will pretend you gave the option 'no-pic', which also disables
2897 'shared' and 'dynamic-engine'. If you know how to implement shared libraries
2898 or position independent code, please let us know (but please first make sure
2899 you have tried with a current version of OpenSSL).
2906 ######################################################################
2908 # Helpers and utility functions
2911 # Death handler, to print a helpful message in case of failure #######
2914 die @_ if $^S; # To prevent the added message in eval blocks
2915 my $build_file = $target{build_file} // "build file";
2916 my @message = ( <<"_____", @_ );
2918 Failure! $build_file wasn't produced.
2919 Please read INSTALL.md and associated NOTES-* files. You may also have to
2920 look over your available compiler tool chain or change your configuration.
2924 # Dying is terminal, so it's ok to reset the signal handler here.
2925 $SIG{__DIE__} = $orig_death_handler;
2929 # Configuration file reading #########################################
2931 # Note: All of the helper functions are for lazy evaluation. They all
2932 # return a CODE ref, which will return the intended value when evaluated.
2933 # Thus, whenever there's mention of a returned value, it's about that
2936 # Helper function to implement conditional value variants, with a default
2937 # plus additional values based on the value of $config{build_type}.
2938 # Arguments are given in hash table form:
2940 # picker(default => "Basic string: ",
2942 # release => "release")
2944 # When configuring with --debug, the resulting string will be
2945 # "Basic string: debug", and when not, it will be "Basic string: release"
2947 # This can be used to create variants of sets of flags according to the
2950 # cflags => picker(default => "-Wall",
2951 # debug => "-g -O0",
2956 return sub { add($opts{default} || (),
2957 $opts{$config{build_type}} || ())->(); }
2960 # Helper function to combine several values of different types into one.
2961 # This is useful if you want to combine a string with the result of a
2962 # lazy function, such as:
2964 # cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2968 return sub { add(@stuff)->(); }
2971 # Helper function to implement conditional values depending on the value
2972 # of $disabled{threads}. Can be used as follows:
2974 # cflags => combine("-Wall", threads("-pthread"))
2978 return sub { add($disabled{threads} ? () : @flags)->(); }
2983 return sub { add($disabled{shared} ? () : @flags)->(); }
2986 our $add_called = 0;
2987 # Helper function to implement adding values to already existing configuration
2988 # values. It handles elements that are ARRAYs, CODEs and scalars
2990 my $separator = shift;
2992 # If there's any ARRAY in the collection of values OR the separator
2993 # is undef, we will return an ARRAY of combined values, otherwise a
2994 # string of joined values with $separator as the separator.
2995 my $found_array = !defined($separator);
3000 while (ref($res) eq "CODE") {
3003 if (defined($res)) {
3004 if (ref($res) eq "ARRAY") {
3020 join($separator, grep { defined($_) && $_ ne "" } @values);
3024 my $separator = " ";
3025 if (ref($_[$#_]) eq "HASH") {
3027 $separator = $opts->{separator};
3030 sub { _add($separator, @x, @_) };
3033 my $separator = " ";
3034 if (ref($_[$#_]) eq "HASH") {
3036 $separator = $opts->{separator};
3039 sub { _add($separator, @_, @x) };
3042 sub read_eval_file {
3047 open F, "< $fname" or die "Can't open '$fname': $!\n";
3056 @result = ( eval $content );
3059 return wantarray ? @result : $result[0];
3062 # configuration reader, evaluates the input file as a perl script and expects
3063 # it to fill %targets with target configurations. Those are then added to
3070 # Protect certain tables from tampering
3073 %targets = read_eval_file($fname);
3075 my %preexisting = ();
3076 foreach (sort keys %targets) {
3077 $preexisting{$_} = 1 if $table{$_};
3080 The following config targets from $fname
3081 shadow pre-existing config targets with the same name:
3083 map { " $_\n" } sort keys %preexisting
3087 # For each target, check that it's configured with a hash table.
3088 foreach (keys %targets) {
3089 if (ref($targets{$_}) ne "HASH") {
3090 if (ref($targets{$_}) eq "") {
3091 warn "Deprecated target configuration for $_, ignoring...\n";
3093 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
3095 delete $targets{$_};
3097 $targets{$_}->{_conf_fname_int} = add([ $fname ]);
3101 %table = (%table, %targets);
3105 # configuration resolver. Will only resolve all the lazy evaluation
3106 # codeblocks for the chosen target and all those it inherits from,
3108 sub resolve_config {
3110 my @breadcrumbs = @_;
3112 # my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
3114 if (grep { $_ eq $target } @breadcrumbs) {
3115 die "inherit_from loop! target backtrace:\n "
3116 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
3119 if (!defined($table{$target})) {
3120 warn "Warning! target $target doesn't exist!\n";
3123 # Recurse through all inheritances. They will be resolved on the
3124 # fly, so when this operation is done, they will all just be a
3125 # bunch of attributes with string values.
3126 # What we get here, though, are keys with references to lists of
3127 # the combined values of them all. We will deal with lists after
3128 # this stage is done.
3129 my %combined_inheritance = ();
3130 if ($table{$target}->{inherit_from}) {
3132 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
3133 foreach (@inherit_from) {
3134 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
3136 # 'template' is a marker that's considered private to
3137 # the config that had it.
3138 delete $inherited_config{template};
3140 foreach (keys %inherited_config) {
3141 if (!$combined_inheritance{$_}) {
3142 $combined_inheritance{$_} = [];
3144 push @{$combined_inheritance{$_}}, $inherited_config{$_};
3149 # We won't need inherit_from in this target any more, since we've
3150 # resolved all the inheritances that lead to this
3151 delete $table{$target}->{inherit_from};
3153 # Now is the time to deal with those lists. Here's the place to
3154 # decide what shall be done with those lists, all based on the
3155 # values of the target we're currently dealing with.
3156 # - If a value is a coderef, it will be executed with the list of
3157 # inherited values as arguments.
3158 # - If the corresponding key doesn't have a value at all or is the
3159 # empty string, the inherited value list will be run through the
3160 # default combiner (below), and the result becomes this target's
3162 # - Otherwise, this target's value is assumed to be a string that
3163 # will simply override the inherited list of values.
3164 my $default_combiner = add();
3167 map { $_ => 1 } (keys %combined_inheritance,
3168 keys %{$table{$target}});
3170 sub process_values {
3172 my $inherited = shift; # Always a [ list ]
3178 while(ref($object) eq "CODE") {
3179 $object = $object->(@$inherited);
3181 if (!defined($object)) {
3184 elsif (ref($object) eq "ARRAY") {
3185 local $add_called; # To make sure recursive calls don't affect it
3186 return [ map { process_values($_, $inherited, $target, $entry) }
3188 } elsif (ref($object) eq "") {
3191 die "cannot handle reference type ",ref($object)
3192 ," found in target ",$target," -> ",$entry,"\n";
3196 foreach my $key (sort keys %all_keys) {
3197 my $previous = $combined_inheritance{$key};
3199 # Current target doesn't have a value for the current key?
3200 # Assign it the default combiner, the rest of this loop body
3201 # will handle it just like any other coderef.
3202 if (!exists $table{$target}->{$key}) {
3203 $table{$target}->{$key} = $default_combiner;
3206 $table{$target}->{$key} = process_values($table{$target}->{$key},
3207 $combined_inheritance{$key},
3209 unless(defined($table{$target}->{$key})) {
3210 delete $table{$target}->{$key};
3212 # if ($extra_checks &&
3213 # $previous && !($add_called || $previous ~~ $table{$target}->{$key})) {
3214 # warn "$key got replaced in $target\n";
3218 # Finally done, return the result.
3219 return %{$table{$target}};
3224 print STDERR $usage;
3225 print STDERR "\npick os/compiler from:\n";
3229 foreach $i (sort keys %table)
3231 next if $table{$i}->{template};
3232 next if $i =~ /^debug/;
3233 $k += length($i) + 1;
3239 print STDERR $i . " ";
3241 foreach $i (sort keys %table)
3243 next if $table{$i}->{template};
3244 next if $i !~ /^debug/;
3245 $k += length($i) + 1;
3251 print STDERR $i . " ";
3256 sub compiler_predefined {
3260 return () if $^O eq 'VMS';
3262 die 'compiler_predefined called without a compiler command'
3265 if (! $predefined{$cc}) {
3267 $predefined{$cc} = {};
3269 # collect compiler pre-defines from gcc or gcc-alike...
3270 open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
3271 while (my $l = <PIPE>) {
3272 $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
3273 $predefined{$cc}->{$1} = $2 // '';
3278 return %{$predefined{$cc}};
3285 if (eval { require IPC::Cmd; 1; }) {
3287 return scalar IPC::Cmd::can_run($name);
3289 # if there is $directories component in splitpath,
3290 # then it's not something to test with $PATH...
3291 return $name if (File::Spec->splitpath($name))[1];
3293 foreach (File::Spec->path()) {
3294 my $fullpath = catfile($_, "$name$target{exe_extension}");
3295 if (-f $fullpath and -x $fullpath) {
3307 unless ($opts{cacheonly}) {
3308 # Note that if $ENV{$name} doesn't exist or is undefined,
3309 # $config{perlenv}->{$name} will be created with the value
3310 # undef. This is intentional.
3312 $config{perlenv}->{$name} = $ENV{$name}
3313 if ! exists $config{perlenv}->{$name};
3315 return $config{perlenv}->{$name};
3318 # Configuration printer ##############################################
3320 sub print_table_entry
3322 local $now_printing = shift;
3323 my %target = resolve_config($now_printing);
3326 # Don't print the templates
3327 return if $target{template};
3372 if ($type eq "TABLE") {
3374 print "*** $now_printing\n";
3375 foreach (@sequence) {
3376 if (ref($target{$_}) eq "ARRAY") {
3377 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
3379 printf "\$%-12s = %s\n", $_, $target{$_};
3382 } elsif ($type eq "HASH") {
3384 length((sort { length($a) <=> length($b) } @sequence)[-1]);
3385 print " '$now_printing' => {\n";
3386 foreach (@sequence) {
3388 if (ref($target{$_}) eq "ARRAY") {
3389 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
3391 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
3399 # Utility routines ###################################################
3401 # On VMS, if the given file is a logical name, File::Spec::Functions
3402 # will consider it an absolute path. There are cases when we want a
3403 # purely syntactic check without checking the environment.
3407 # On non-platforms, we just use file_name_is_absolute().
3408 return file_name_is_absolute($file) unless $^O eq "VMS";
3410 # If the file spec includes a device or a directory spec,
3411 # file_name_is_absolute() is perfectly safe.
3412 return file_name_is_absolute($file) if $file =~ m|[:\[]|;
3414 # Here, we know the given file spec isn't absolute
3418 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
3419 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
3420 # realpath() requires that at least all path components except the last is an
3421 # existing directory. On VMS, the last component of the directory spec must
3426 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
3427 # will return the volume name for the device, no matter what. Also,
3428 # it will return an incorrect directory spec if the argument is a
3429 # directory that doesn't exist.
3431 return rel2abs($dir);
3434 # We use realpath() on Unix, since no other will properly clean out
3436 use Cwd qw/realpath/;
3438 return realpath($dir);
3441 # Check if all paths are one and the same, using stat. They must both exist
3442 # We need this for the cases when File::Spec doesn't detect case insensitivity
3443 # (File::Spec::Unix assumes case sensitivity)
3445 die "samedir expects two arguments\n" unless scalar @_ == 2;
3447 my @stat0 = stat($_[0]); # First argument
3448 my @stat1 = stat($_[1]); # Second argument
3450 die "Couldn't stat $_[0]" unless @stat0;
3451 die "Couldn't stat $_[1]" unless @stat1;
3453 # Compare device number
3454 return 0 unless ($stat0[0] == $stat1[0]);
3455 # Compare "inode". The perl manual recommends comparing as
3456 # string rather than as number.
3457 return 0 unless ($stat0[1] eq $stat1[1]);
3459 return 1; # All the same
3464 perl => sub { my $x = shift;
3465 $x =~ s/([\\\$\@"])/\\$1/g;
3466 return '"'.$x.'"'; },
3467 maybeshell => sub { my $x = shift;
3468 (my $y = $x) =~ s/([\\\"])/\\$1/g;
3469 if ($x ne $y || $x =~ m|\s|) {
3478 defined($processors{$for}) ? $processors{$for} : sub { shift; };
3480 return map { $processor->($_); } @_;
3483 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
3484 # $filename is a file name to read from
3485 # $line_concat_cond_re is a regexp detecting a line continuation ending
3486 # $line_concat is a CODEref that takes care of concatenating two lines
3487 sub collect_from_file {
3488 my $filename = shift;
3489 my $line_concat_cond_re = shift;
3490 my $line_concat = shift;
3492 open my $fh, $filename || die "unable to read $filename: $!\n";
3494 my $saved_line = "";
3498 if (defined $line_concat) {
3499 $_ = $line_concat->($saved_line, $_);
3502 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3508 die "$filename ending with continuation line\n" if $_;
3514 # collect_from_array($array, $line_concat_cond_re, $line_concat)
3515 # $array is an ARRAYref of lines
3516 # $line_concat_cond_re is a regexp detecting a line continuation ending
3517 # $line_concat is a CODEref that takes care of concatenating two lines
3518 sub collect_from_array {
3520 my $line_concat_cond_re = shift;
3521 my $line_concat = shift;
3522 my @array = (@$array);
3525 my $saved_line = "";
3527 while (defined($_ = shift @array)) {
3529 if (defined $line_concat) {
3530 $_ = $line_concat->($saved_line, $_);
3533 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3539 die "input text ending with continuation line\n" if $_;
3544 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
3545 # $lineiterator is a CODEref that delivers one line at a time.
3546 # All following arguments are regex/CODEref pairs, where the regexp detects a
3547 # line and the CODEref does something with the result of the regexp.
3548 sub collect_information {
3549 my $lineiterator = shift;
3550 my %collectors = @_;
3552 while(defined($_ = $lineiterator->())) {
3555 if ($collectors{"BEFORE"}) {
3556 $collectors{"BEFORE"}->($_);
3558 foreach my $re (keys %collectors) {
3559 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
3560 $collectors{$re}->($lineiterator);
3564 if ($collectors{"OTHERWISE"}) {
3565 $collectors{"OTHERWISE"}->($lineiterator, $_)
3566 unless $found || !defined $collectors{"OTHERWISE"};
3568 if ($collectors{"AFTER"}) {
3569 $collectors{"AFTER"}->($_);
3575 # tokenize($line,$separator)
3576 # $line is a line of text to split up into tokens
3577 # $separator [optional] is a regular expression that separates the tokens,
3578 # the default being spaces. Do not use quotes of any kind as separators,
3579 # that will give undefined results.
3580 # Returns a list of tokens.
3582 # Tokens are divided by separator (spaces by default). If the tokens include
3583 # the separators, they have to be quoted with single or double quotes.
3584 # Double quotes inside a double quoted token must be escaped. Escaping is done
3586 # Basically, the same quoting rules apply for " and ' as in any
3589 my $line = my $debug_line = shift;
3590 my $separator = shift // qr|\s+|;
3593 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3594 print STDERR "DEBUG[tokenize]: \$separator = $separator\n";
3597 while ($line =~ s|^${separator}||, $line ne "") {
3600 $line =~ m/^(.*?)(${separator}|"|'|$)/;
3604 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
3608 } elsif ($line =~ m/^'([^']*)'/) {
3613 push @result, $token;
3616 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3617 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
3618 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";