3 # Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
5 # Licensed under the OpenSSL license (the "License"). You may not use
6 # this file except in compliance with the License. You can obtain a copy
7 # in the file LICENSE in the source distribution or at
8 # https://www.openssl.org/source/license.html
10 ## Configure -- OpenSSL source tree configuration script
16 use lib "$FindBin::Bin/util/perl";
18 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
19 use File::Path qw/mkpath/;
22 # see INSTALL for instructions.
24 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
28 # --config add the given configuration file, which will be read after
29 # any "Configurations*" files that are found in the same
30 # directory as this script.
31 # --prefix prefix for the OpenSSL installation, which includes the
32 # directories bin, lib, include, share/man, share/doc/openssl
33 # This becomes the value of INSTALLTOP in Makefile
34 # (Default: /usr/local)
35 # --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys.
36 # If it's a relative directory, it will be added on the directory
37 # given with --prefix.
38 # This becomes the value of OPENSSLDIR in Makefile and in C.
39 # (Default: PREFIX/ssl)
41 # --cross-compile-prefix Add specified prefix to binutils components.
43 # --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for
44 # interfaces deprecated as of the specified OpenSSL version.
46 # no-hw-xxx do not compile support for specific crypto hardware.
47 # Generic OpenSSL-style methods relating to this support
48 # are always compiled but return NULL if the hardware
49 # support isn't compiled.
50 # no-hw do not compile support for any crypto hardware.
51 # [no-]threads [don't] try to create a library that is suitable for
52 # multithreaded applications (default is "threads" if we
54 # [no-]shared [don't] try to create shared libraries when supported.
55 # [no-]pic [don't] try to build position independent code when supported.
56 # If disabled, it also disables shared and dynamic-engine.
57 # no-asm do not use assembler
58 # no-dso do not compile in any native shared-library methods. This
59 # will ensure that all methods just return NULL.
60 # no-egd do not compile support for the entropy-gathering daemon APIs
61 # [no-]zlib [don't] compile support for zlib compression.
62 # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
63 # library and will be loaded in run-time by the OpenSSL library.
64 # sctp include SCTP support
65 # enable-weak-ssl-ciphers
66 # Enable weak ciphers that are disabled by default.
67 # 386 generate 80386 code in assembly modules
68 # no-sse2 disables IA-32 SSE2 code in assembly modules, the above
69 # mentioned '386' option implies this one
70 # no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
71 # -<xxx> +<xxx> compiler options are passed through
72 # -static while -static is also a pass-through compiler option (and
73 # as such is limited to environments where it's actually
74 # meaningful), it triggers a number configuration options,
75 # namely no-dso, no-pic, no-shared and no-threads. It is
76 # argued that the only reason to produce statically linked
77 # binaries (and in context it means executables linked with
78 # -static flag, and not just executables linked with static
79 # libcrypto.a) is to eliminate dependency on specific run-time,
80 # a.k.a. libc version. The mentioned config options are meant
81 # to achieve just that. Unfortunately on Linux it's impossible
82 # to eliminate the dependency completely for openssl executable
83 # because of getaddrinfo and gethostbyname calls, which can
84 # invoke dynamically loadable library facility anyway to meet
85 # the lookup requests. For this reason on Linux statically
86 # linked openssl executable has rather debugging value than
89 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
90 # provided to stack calls. Generates unique stack functions for
91 # each possible stack type.
92 # BN_LLONG use the type 'long long' in crypto/bn/bn.h
93 # RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
94 # Following are set automatically by this script
96 # MD5_ASM use some extra md5 assembler,
97 # SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86
98 # RMD160_ASM use some extra ripemd160 assembler,
99 # SHA256_ASM sha256_block is implemented in assembler
100 # SHA512_ASM sha512_block is implemented in assembler
101 # AES_ASM AES_[en|de]crypt is implemented in assembler
103 # Minimum warning options... any contributions to OpenSSL should at least get
106 # DEBUG_UNUSED enables __owur (warn unused result) checks.
107 # -DPEDANTIC complements -pedantic and is meant to mask code that
108 # is not strictly standard-compliant and/or implementation-specific,
109 # e.g. inline assembly, disregards to alignment requirements, such
110 # that -pedantic would complain about. Incidentally -DPEDANTIC has
111 # to be used even in sanitized builds, because sanitizer too is
112 # supposed to and does take notice of non-standard behaviour. Then
113 # -pedantic with pre-C9x compiler would also complain about 'long
114 # long' not being supported. As 64-bit algorithms are common now,
115 # it grew impossible to resolve this without sizeable additional
116 # code, so we just tell compiler to be pedantic about everything
117 # but 'long long' type.
119 my $gcc_devteam_warn = "-DDEBUG_UNUSED"
120 . " -DPEDANTIC -pedantic -Wno-long-long"
123 . " -Wno-unused-parameter"
124 . " -Wno-missing-field-initializers"
127 . " -Wmissing-prototypes"
135 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
136 # TODO(openssl-team): fix problems and investigate if (at least) the
137 # following warnings can also be enabled:
139 # -Wunreachable-code -- no, too ugly/compiler-specific
140 # -Wlanguage-extension-token -- no, we use asm()
141 # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
142 # -Wextended-offsetof -- no, needed in CMS ASN1 code
143 my $clang_devteam_warn = ""
144 . " -Wswitch-default"
145 . " -Wno-parentheses-equality"
146 . " -Wno-language-extension-token"
147 . " -Wno-extended-offsetof"
148 . " -Wconditional-uninitialized"
149 . " -Wincompatible-pointer-types-discards-qualifiers"
150 . " -Wmissing-variable-declarations"
151 . " -Wno-unknown-warning-option"
154 # This adds backtrace information to the memory leak info. Is only used
155 # when crypto-mdebug-backtrace is enabled.
156 my $memleak_devteam_backtrace = "-rdynamic";
158 my $strict_warnings = 0;
160 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
161 # which would cover all BSD flavors. -pthread applies to them all,
162 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
163 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
164 # which has to be accompanied by explicit -D_THREAD_SAFE and
165 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
166 # seems to be sufficient?
167 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
170 # API compatibility name to version number mapping.
172 my $maxapi = "1.1.0"; # API for "no-deprecated" builds
174 "1.1.0" => "0x10100000L",
175 "1.0.0" => "0x10000000L",
176 "0.9.8" => "0x00908000L",
183 # Forward declarations ###############################################
185 # read_config(filename)
187 # Reads a configuration file and populates %table with the contents
188 # (which the configuration file places in %targets).
191 # resolve_config(target)
193 # Resolves all the late evaluations, inheritances and so on for the
194 # chosen target and any target it inherits from.
198 # Information collection #############################################
200 # Unified build supports separate build dir
201 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
202 my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
203 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
205 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
207 $config{sourcedir} = abs2rel($srcdir);
208 $config{builddir} = abs2rel($blddir);
210 # Collect reconfiguration information if needed
213 if (grep /^reconf(igure)?$/, @argvcopy) {
214 die "reconfiguring with other arguments present isn't supported"
215 if scalar @argvcopy > 1;
216 if (-f "./configdata.pm") {
217 my $file = "./configdata.pm";
218 unless (my $return = do $file) {
219 die "couldn't parse $file: $@" if $@;
220 die "couldn't do $file: $!" unless defined $return;
221 die "couldn't run $file" unless $return;
224 @argvcopy = defined($configdata::config{perlargv}) ?
225 @{$configdata::config{perlargv}} : ();
226 die "Incorrect data to reconfigure, please do a normal configuration\n"
227 if (grep(/^reconf/,@argvcopy));
228 $config{perlenv} = $configdata::config{perlenv} // {};
230 die "Insufficient data to reconfigure, please do a normal configuration\n";
234 $config{perlargv} = [ @argvcopy ];
236 # Collect version numbers
237 $config{version} = "unknown";
238 $config{version_num} = "unknown";
239 $config{shlib_version_number} = "unknown";
240 $config{shlib_version_history} = "unknown";
243 collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
244 qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
245 qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 },
246 qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 },
247 qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 }
249 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
251 ($config{major}, $config{minor})
252 = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
253 ($config{shlib_major}, $config{shlib_minor})
254 = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
255 die "erroneous version information in opensslv.h: ",
256 "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
257 if ($config{major} eq "" || $config{minor} eq ""
258 || $config{shlib_major} eq "" || $config{shlib_minor} eq "");
260 # Collect target configurations
262 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
263 foreach (sort glob($pattern)) {
267 if (defined env($local_config_envname)) {
269 # VMS environment variables are logical names,
270 # which can be used as is
271 $pattern = $local_config_envname . ':' . '*.conf';
273 $pattern = catfile(env($local_config_envname), '*.conf');
276 foreach (sort glob($pattern)) {
282 $config{openssldir}="";
283 $config{processor}="";
285 $config{cross_compile_prefix}="";
286 my $auto_threads=1; # enable threads automatically? true by default
289 # Top level directories to build
290 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
291 # crypto/ subdirectories to build
294 "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3",
295 "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes",
296 "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
297 "buffer", "bio", "stack", "lhash", "rand", "err",
298 "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
299 "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store"
301 # test/ subdirectories to build
302 $config{tdirs} = [ "ossl_shim" ];
304 # Known TLS and DTLS protocols
305 my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3);
306 my @dtls = qw(dtls1 dtls1_2);
308 # Explicitly known options that are possible to disable. They can
309 # be regexps, and will be used like this: /^no-${option}$/
310 # For developers: keep it sorted alphabetically
330 "crypto-mdebug-backtrace",
345 "ec_nistp_64_gcc_128",
404 foreach my $proto ((@tls, @dtls))
406 push(@disablables, $proto);
407 push(@disablables, "$proto-method") unless $proto eq "tls1_3";
410 my %deprecated_disablables = (
412 "buf-freelists" => undef,
413 "ripemd" => "rmd160",
414 "ui" => "ui-console",
417 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
419 our %disabled = ( # "what" => "comment"
421 "crypto-mdebug" => "default",
422 "crypto-mdebug-backtrace" => "default",
423 "devcryptoeng" => "default",
424 "ec_nistp_64_gcc_128" => "default",
426 "external-tests" => "default",
427 "fuzz-libfuzzer" => "default",
428 "fuzz-afl" => "default",
429 "heartbeats" => "default",
434 "ssl-trace" => "default",
436 "ssl3-method" => "default",
437 "ubsan" => "default",
438 #TODO(TLS1.3): Temporarily disabled while this is a WIP
439 "tls1_3" => "default",
440 "tls13downgrade" => "default",
441 "unit-test" => "default",
442 "weak-ssl-ciphers" => "default",
444 "zlib-dynamic" => "default",
447 # Note: => pair form used for aesthetics, not to truly make a hash table
448 my @disable_cascades = (
449 # "what" => [ "cascade", ... ]
450 sub { $config{processor} eq "386" }
453 "ssl3-method" => [ "ssl3" ],
454 "zlib" => [ "zlib-dynamic" ],
456 "ec" => [ "ecdsa", "ecdh" ],
458 "dgram" => [ "dtls", "sctp" ],
459 "sock" => [ "dgram" ],
461 sub { 0 == scalar grep { !$disabled{$_} } @dtls }
465 sub { 0 == scalar grep { !$disabled{$_} } @tls }
468 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
470 # Without DSO, we can't load dynamic engines, so don't build them dynamic
471 "dso" => [ "dynamic-engine" ],
473 # Without position independent code, there can be no shared libraries or DSOs
474 "pic" => [ "shared" ],
475 "shared" => [ "dynamic-engine" ],
476 "engine" => [ "afalgeng", "devcryptoeng" ],
478 # no-autoalginit is only useful when building non-shared
479 "autoalginit" => [ "shared", "apps" ],
481 "stdio" => [ "apps", "capieng", "egd" ],
482 "apps" => [ "tests" ],
483 "tests" => [ "external-tests" ],
484 "comp" => [ "zlib" ],
485 "ec" => [ "tls1_3" ],
486 sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
488 sub { !$disabled{"msan"} } => [ "asm" ],
491 # Avoid protocol support holes. Also disable all versions below N, if version
492 # N is disabled while N+1 is enabled.
494 my @list = (reverse @tls);
495 while ((my $first, my $second) = (shift @list, shift @list)) {
497 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
499 unshift @list, $second;
501 my @list = (reverse @dtls);
502 while ((my $first, my $second) = (shift @list, shift @list)) {
504 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
506 unshift @list, $second;
509 # Explicit "no-..." options will be collected in %disabled along with the defaults.
510 # To remove something from %disabled, use "enable-foo".
511 # For symmetry, "disable-foo" is a synonym for "no-foo".
513 &usage if ($#ARGV < 0);
515 # For the "make variables" CINCLUDES and CDEFINES, we support lists with
516 # platform specific list separators. Users from those platforms should
517 # recognise those separators from how you set up the PATH to find executables.
518 # The default is the Unix like separator, :, but as an exception, we also
519 # support the space as separator.
520 my $list_separator_re =
521 { VMS => qr/(?<!\^),/,
522 MSWin32 => qr/(?<!\\);/ } -> {$^O} // qr/(?<!\\)[:\s]/;
523 # All the "make variables" we support
534 CPPFLAGS => [], # -D, -I, -Wp,
535 CPPDEFINES => [], # Alternative for -D
536 CPPINCLUDES => [], # Alternative for -I
537 HASHBANGPERL=> undef,
539 LDFLAGS => [], # -L, -Wl,
548 # The same but for flags given as Configure options. These are *additional*
549 # input, as opposed to the VAR=string option that override the corresponding
550 # config target attributes
561 my %user_synonyms = (
562 HASHBANGPERL=> 'PERL',
565 my %user_to_target = (
566 # If not given here, the value is the lc of the key
567 CPPDEFINES => 'defines',
568 CPPINCLUDES => 'includes',
573 $config{openssl_api_defines}=[];
574 $config{openssl_algorithm_defines}=[];
575 $config{openssl_thread_defines}=[];
576 $config{openssl_sys_defines}=[];
577 $config{openssl_other_defines}=[];
579 $config{build_type} = "release";
582 my %unsupported_options = ();
583 my %deprecated_options = ();
584 # If you change this, update apps/version.c
585 my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
586 my @seed_sources = ();
589 $_ = shift @argvcopy;
591 # Support env variable assignments among the options
592 if (m|^(\w+)=(.+)?$|)
594 $config{perlenv}->{$1} = $2;
595 # Every time a variable is given as a configuration argument,
596 # it acts as a reset if the variable.
597 if (exists $user{$1})
599 $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef;
601 if (exists $useradd{$1})
608 # VMS is a case insensitive environment, and depending on settings
609 # out of our control, we may receive options uppercased. Let's
610 # downcase at least the part before any equal sign.
615 s /^-no-/no-/; # some people just can't read the instructions
617 # rewrite some options in "enable-..." form
618 s /^-?-?shared$/enable-shared/;
619 s /^sctp$/enable-sctp/;
620 s /^threads$/enable-threads/;
621 s /^zlib$/enable-zlib/;
622 s /^zlib-dynamic$/enable-zlib-dynamic/;
624 if (/^(no|disable|enable)-(.+)$/)
627 if (!exists $deprecated_disablables{$word}
628 && !grep { $word =~ /^${_}$/ } @disablables)
630 $unsupported_options{$_} = 1;
634 if (/^no-(.+)$/ || /^disable-(.+)$/)
636 foreach my $proto ((@tls, @dtls))
638 if ($1 eq "$proto-method")
640 $disabled{"$proto"} = "option($proto-method)";
646 foreach my $proto (@dtls)
648 $disabled{$proto} = "option(dtls)";
650 $disabled{"dtls"} = "option(dtls)";
654 # Last one of its kind
655 $disabled{"ssl3"} = "option(ssl)";
659 # XXX: Tests will fail if all SSL/TLS
660 # protocols are disabled.
661 foreach my $proto (@tls)
663 $disabled{$proto} = "option(tls)";
666 elsif ($1 eq "static-engine")
668 delete $disabled{"dynamic-engine"};
670 elsif ($1 eq "dynamic-engine")
672 $disabled{"dynamic-engine"} = "option";
674 elsif (exists $deprecated_disablables{$1})
676 $deprecated_options{$_} = 1;
677 if (defined $deprecated_disablables{$1})
679 $disabled{$deprecated_disablables{$1}} = "option";
684 $disabled{$1} = "option";
686 # No longer an automatic choice
687 $auto_threads = 0 if ($1 eq "threads");
689 elsif (/^enable-(.+)$/)
691 if ($1 eq "static-engine")
693 $disabled{"dynamic-engine"} = "option";
695 elsif ($1 eq "dynamic-engine")
697 delete $disabled{"dynamic-engine"};
699 elsif ($1 eq "zlib-dynamic")
701 delete $disabled{"zlib"};
704 delete $disabled{$algo};
706 # No longer an automatic choice
707 $auto_threads = 0 if ($1 eq "threads");
709 elsif (/^--strict-warnings$/)
711 $strict_warnings = 1;
715 $config{build_type} = "debug";
717 elsif (/^--release$/)
719 $config{build_type} = "release";
722 { $config{processor}=386; }
725 die "FIPS mode not supported\n";
729 # No RSAref support any more since it's not needed.
730 # The check for the option is there so scripts aren't
733 elsif (/^nofipscanistercheck$/)
735 die "FIPS mode not supported\n";
739 if (/^--prefix=(.*)$/)
742 die "Directory given with --prefix MUST be absolute\n"
743 unless file_name_is_absolute($config{prefix});
745 elsif (/^--api=(.*)$/)
749 elsif (/^--libdir=(.*)$/)
753 elsif (/^--openssldir=(.*)$/)
755 $config{openssldir}=$1;
757 elsif (/^--with-zlib-lib=(.*)$/)
759 $withargs{zlib_lib}=$1;
761 elsif (/^--with-zlib-include=(.*)$/)
763 $withargs{zlib_include}=$1;
765 elsif (/^--with-fuzzer-lib=(.*)$/)
767 $withargs{fuzzer_lib}=$1;
769 elsif (/^--with-fuzzer-include=(.*)$/)
771 $withargs{fuzzer_include}=$1;
773 elsif (/^--with-rand-seed=(.*)$/)
775 foreach my $x (split(m|,|, $1))
777 die "Unknown --with-rand-seed choice $x\n"
778 if ! grep { $x eq $_ } @known_seed_sources;
779 push @seed_sources, $x;
782 elsif (/^--cross-compile-prefix=(.*)$/)
784 $config{cross_compile_prefix}=$1;
786 elsif (/^--config=(.*)$/)
792 push @{$useradd{LDFLAGS}}, $_;
794 elsif (/^-l(.*)$/ or /^-Wl,/)
796 push @{$useradd{LDLIBS}}, $_;
798 elsif (/^-framework$/)
800 push @{$useradd{LDLIBS}}, $_, shift(@argvcopy);
802 elsif (/^-rpath$/ or /^-R$/)
803 # -rpath is the OSF1 rpath flag
804 # -R is the old Solaris rpath flag
806 my $rpath = shift(@argvcopy) || "";
807 $rpath .= " " if $rpath ne "";
808 push @{$useradd{LDFLAGS}}, $_, $rpath;
812 push @{$useradd{LDFLAGS}}, $_;
813 $disabled{"dso"} = "forced";
814 $disabled{"pic"} = "forced";
815 $disabled{"shared"} = "forced";
816 $disabled{"threads"} = "forced";
820 push @{$useradd{CPPDEFINES}}, $1;
824 push @{$useradd{CPPINCLUDES}}, $1;
828 push @{$useradd{CPPFLAGS}}, $1;
830 else # common if (/^[-+]/), just pass down...
832 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
833 push @{$useradd{CFLAGS}}, $_;
834 push @{$useradd{CXXFLAGS}}, $_;
839 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
842 unless ($_ eq $target || /^no-/ || /^disable-/)
844 # "no-..." follows later after implied deactivations
845 # have been derived. (Don't take this too seriously,
846 # we really only write OPTIONS to the Makefile out of
849 if ($config{options} eq "")
850 { $config{options} = $_; }
852 { $config{options} .= " ".$_; }
855 if (defined($config{api}) && !exists $apitable->{$config{api}}) {
856 die "***** Unsupported api compatibility level: $config{api}\n",
859 if (keys %deprecated_options)
861 warn "***** Deprecated options: ",
862 join(", ", keys %deprecated_options), "\n";
864 if (keys %unsupported_options)
866 die "***** Unsupported options: ",
867 join(", ", keys %unsupported_options), "\n";
871 foreach (keys %user) {
873 $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef;
875 if (defined $value) {
876 if (ref $user{$_} eq 'ARRAY') {
877 $user{$_} = [ split /$list_separator_re/, $value ];
878 } elsif (!defined $user{$_}) {
884 if (grep { $_ =~ /(^|\s)-Wl,-rpath,/ } ($user{LDLIBS} ? @{$user{LDLIBS}} : ())
885 && !$disabled{shared}
886 && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
887 die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
888 "***** any of asan, msan or ubsan\n";
891 if (scalar(@seed_sources) == 0) {
892 print "Using implicit seed configuration\n";
893 push @seed_sources, 'os';
895 die "Cannot seed with none and anything else"
896 if scalar(grep { $_ eq 'none' } @seed_sources) > 0
897 && scalar(@seed_sources) > 1;
898 push @{$config{openssl_other_defines}},
899 map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
902 my @tocheckfor = (keys %disabled);
903 while (@tocheckfor) {
904 my %new_tocheckfor = ();
905 my @cascade_copy = (@disable_cascades);
906 while (@cascade_copy) {
907 my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
908 if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
909 foreach(grep { !defined($disabled{$_}) } @$descendents) {
910 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
914 @tocheckfor = (keys %new_tocheckfor);
917 our $die = sub { die @_; };
918 if ($target eq "TABLE") {
919 local $die = sub { warn @_; };
920 foreach (sort keys %table) {
921 print_table_entry($_, "TABLE");
926 if ($target eq "LIST") {
927 foreach (sort keys %table) {
928 print $_,"\n" unless $table{$_}->{template};
933 if ($target eq "HASH") {
934 local $die = sub { warn @_; };
935 print "%table = (\n";
936 foreach (sort keys %table) {
937 print_table_entry($_, "HASH");
942 print "Configuring OpenSSL version $config{version} ($config{version_num}) ";
943 print "for $target\n";
945 # Backward compatibility?
946 if ($target =~ m/^CygWin32(-.*)$/) {
947 $target = "Cygwin".$1;
950 # Support for legacy targets having a name starting with 'debug-'
951 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
953 $config{build_type} = "debug";
955 # If we do not find debug-foo in the table, the target is set to foo.
956 if (!$table{$target}) {
960 $config{target} = $target;
961 my %target = resolve_config($target);
963 &usage if (!%target || $target{template});
965 %target = ( %{$table{DEFAULTS}}, %target );
967 # Make the flags to build DSOs the same as for shared libraries unless they
968 # are already defined
969 $target{dso_cflags} = $target{shared_cflag} unless defined $target{dso_cflags};
970 $target{dso_cxxflags} = $target{shared_cxxflag} unless defined $target{dso_cxxflags};
971 $target{dso_lflags} = $target{shared_ldflag} unless defined $target{dso_lflags};
974 catfile(dirname($0), "Configurations", "shared-info.pl");
975 my %shared_info = read_eval_file($shared_info_pl);
976 push @{$target{_conf_fname_int}}, $shared_info_pl;
977 my $si = $target{shared_target};
978 while (ref $si ne "HASH") {
979 last if ! defined $si;
980 if (ref $si eq "CODE") {
983 $si = $shared_info{$si};
987 # Some of the 'shared_target' values don't have any entried in
988 # %shared_info. That's perfectly fine, AS LONG AS the build file
989 # template knows how to handle this. That is currently the case for
992 # Just as above, copy certain shared_* attributes to the corresponding
993 # dso_ attribute unless the latter is already defined
994 $si->{dso_cflags} = $si->{shared_cflag} unless defined $si->{dso_cflags};
995 $si->{dso_cxxflags} = $si->{shared_cxxflag} unless defined $si->{dso_cxxflags};
996 $si->{dso_lflags} = $si->{shared_ldflag} unless defined $si->{dso_lflags};
997 foreach (sort keys %$si) {
998 $target{$_} = defined $target{$_}
999 ? add($si->{$_})->($target{$_})
1005 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
1006 $config{conf_files} = [ sort keys %conf_files ];
1008 foreach my $feature (@{$target{disable}}) {
1009 if (exists $deprecated_disablables{$feature}) {
1010 warn "***** config $target disables deprecated feature $feature\n";
1011 } elsif (!grep { $feature eq $_ } @disablables) {
1012 die "***** config $target disables unknown feature $feature\n";
1014 $disabled{$feature} = 'config';
1016 foreach my $feature (@{$target{enable}}) {
1017 if ("default" eq ($disabled{$_} // "")) {
1018 if (exists $deprecated_disablables{$feature}) {
1019 warn "***** config $target enables deprecated feature $feature\n";
1020 } elsif (!grep { $feature eq $_ } @disablables) {
1021 die "***** config $target enables unknown feature $feature\n";
1023 delete $disabled{$_};
1027 $target{cxxflags}//=$target{cflags} if $target{cxx};
1028 $target{exe_extension}="";
1029 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
1030 || $config{target} =~ /^(?:Cygwin|mingw)/);
1031 $target{exe_extension}=".pm" if ($config{target} =~ /vos/);
1033 ($target{shared_extension_simple}=$target{shared_extension})
1034 =~ s|\.\$\(SHLIB_VERSION_NUMBER\)||;
1035 $target{dso_extension}=$target{shared_extension_simple};
1036 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
1037 if ($config{target} =~ /^(?:Cygwin|mingw)/);
1040 $config{cross_compile_prefix} = env('CROSS_COMPILE')
1041 if $config{cross_compile_prefix} eq "";
1043 # Allow overriding the names of some tools. USE WITH CARE
1044 # Note: only Unix cares about HASHBANGPERL... that explains
1045 # the default string.
1046 $config{perl} = ($^O ne "VMS" ? $^X : "perl");
1047 foreach (keys %user) {
1048 my $target_key = $user_to_target{$_} // lc $_;
1049 my $ref_type = ref $user{$_};
1051 # Temporary function. Takes an intended ref type (empty string or "ARRAY")
1052 # and a value that's to be coerced into that type.
1056 my $undef_p = shift;
1058 die "Too many arguments for \$mkvalue" if @_;
1060 while (ref $value eq 'CODE') {
1061 $value = $value->();
1064 if ($type eq 'ARRAY') {
1065 return undef unless defined $value;
1066 return undef if ref $value ne 'ARRAY' && !$value;
1067 return undef if ref $value eq 'ARRAY' && !@$value;
1068 return [ $value ] unless ref $value eq 'ARRAY';
1070 return undef unless $value;
1074 $config{$target_key} =
1075 $mkvalue->($ref_type, $user{$_})
1076 || $mkvalue->($ref_type, $target{$target_key});
1077 delete $config{$target_key} unless defined $config{$target_key};
1079 $config{plib_lflags} = [ $target{plib_lflags} ];
1081 # Allow overriding the build file name
1082 $config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile";
1084 my %disabled_info = (); # For configdata.pm
1085 foreach my $what (sort keys %disabled) {
1086 $config{options} .= " no-$what";
1088 if (!grep { $what eq $_ } ( 'dso', 'threads', 'shared', 'pic',
1089 'dynamic-engine', 'makedepend',
1090 'zlib-dynamic', 'zlib', 'sse2' )) {
1091 (my $WHAT = uc $what) =~ s|-|_|g;
1093 # Fix up C macro end names
1094 $WHAT = "RMD160" if $what eq "ripemd";
1096 # fix-up crypto/directory name(s)
1097 $what = "ripemd" if $what eq "rmd160";
1098 $what = "whrlpool" if $what eq "whirlpool";
1100 my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT";
1102 if ((grep { $what eq $_ } @{$config{sdirs}})
1103 && $what ne 'async' && $what ne 'err') {
1104 @{$config{sdirs}} = grep { $what ne $_} @{$config{sdirs}};
1105 $disabled_info{$what}->{skipped} = [ catdir('crypto', $what) ];
1107 if ($what ne 'engine') {
1108 push @{$config{openssl_algorithm_defines}}, $macro;
1110 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
1111 push @{$disabled_info{engine}->{skipped}}, catdir('engines');
1112 push @{$config{openssl_other_defines}}, $macro;
1115 push @{$config{openssl_other_defines}}, $macro;
1121 # Make sure build_scheme is consistent.
1122 $target{build_scheme} = [ $target{build_scheme} ]
1123 if ref($target{build_scheme}) ne "ARRAY";
1125 my ($builder, $builder_platform, @builder_opts) =
1126 @{$target{build_scheme}};
1128 foreach my $checker (($builder_platform."-".$target{build_file}."-checker.pm",
1129 $builder_platform."-checker.pm")) {
1130 my $checker_path = catfile($srcdir, "Configurations", $checker);
1131 if (-f $checker_path) {
1132 my $fn = $ENV{CONFIGURE_CHECKER_WARN}
1133 ? sub { warn $@; } : sub { die $@; };
1134 if (! do $checker_path) {
1140 $fn->("The detected tools didn't match the platform\n");
1147 push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
1149 if ($target =~ /^mingw/ && `$config{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
1151 push @{$config{cflags}}, "-mno-cygwin";
1152 push @{$config{cxxflags}}, "-mno-cygwin" if $config{cxx};
1153 push @{$config{shared_ldflag}}, "-mno-cygwin";
1156 if ($target =~ /linux.*-mips/ && !$disabled{asm}
1157 && !grep { $_ !~ /-m(ips|arch=)/ } (@{$user{CFLAGS}},
1158 @{$useradd{CFLAGS}})) {
1159 # minimally required architecture flags for assembly modules
1161 $value = '-mips2' if ($target =~ /mips32/);
1162 $value = '-mips3' if ($target =~ /mips64/);
1163 unshift @{$config{cflags}}, $value;
1164 unshift @{$config{cxxflags}}, $value if $config{cxx};
1167 # The DSO code currently always implements all functions so that no
1168 # applications will have to worry about that from a compilation point
1169 # of view. However, the "method"s may return zero unless that platform
1170 # has support compiled in for them. Currently each method is enabled
1171 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
1172 # string entry into using the following logic;
1173 if (!$disabled{dso} && $target{dso_scheme} ne "")
1175 $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
1176 if ($target{dso_scheme} eq "DLFCN")
1178 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
1180 elsif ($target{dso_scheme} eq "DLFCN_NO_H")
1182 unshift @{$config{defines}}, "DSO_DLFCN";
1186 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
1190 # If threads aren't disabled, check how possible they are
1191 unless ($disabled{threads}) {
1192 if ($auto_threads) {
1193 # Enabled by default, disable it forcibly if unavailable
1194 if ($target{thread_scheme} eq "(unknown)") {
1195 $disabled{threads} = "unavailable";
1198 # The user chose to enable threads explicitly, let's see
1199 # if there's a chance that's possible
1200 if ($target{thread_scheme} eq "(unknown)") {
1201 # If the user asked for "threads" and we don't have internal
1202 # knowledge how to do it, [s]he is expected to provide any
1203 # system-dependent compiler options that are necessary. We
1204 # can't truly check that the given options are correct, but
1205 # we expect the user to know what [s]He is doing.
1206 if (!@{$user{CFLAGS}} && !@{$useradd{CFLAGS}}
1207 && !@{$user{CPPDEFINES}} && !@{$useradd{CPPDEFINES}}) {
1208 die "You asked for multi-threading support, but didn't\n"
1209 ,"provide any system-specific compiler options\n";
1215 # If threads still aren't disabled, add a C macro to ensure the source
1216 # code knows about it. Any other flag is taken care of by the configs.
1217 unless($disabled{threads}) {
1218 push @{$config{openssl_thread_defines}}, "OPENSSL_THREADS";
1221 # With "deprecated" disable all deprecated features.
1222 if (defined($disabled{"deprecated"})) {
1223 $config{api} = $maxapi;
1226 my $no_shared_warn=0;
1227 if ($target{shared_target} eq "")
1230 if (!$disabled{shared} || !$disabled{"dynamic-engine"});
1231 $disabled{shared} = "no-shared-target";
1232 $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1236 if ($disabled{"dynamic-engine"}) {
1237 push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1238 $config{dynamic_engines} = 0;
1240 push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1241 $config{dynamic_engines} = 1;
1244 unless ($disabled{asan}) {
1245 push @{$config{cflags}}, "-fsanitize=address";
1246 push @{$config{cxxflags}}, "-fsanitize=address" if $config{cxx};
1249 unless ($disabled{ubsan}) {
1250 # -DPEDANTIC or -fnosanitize=alignment may also be required on some
1252 push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all";
1253 push @{$config{cxxflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all"
1257 unless ($disabled{msan}) {
1258 push @{$config{cflags}}, "-fsanitize=memory";
1259 push @{$config{cxxflags}}, "-fsanitize=memory" if $config{cxx};
1262 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1263 && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1264 push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g";
1265 push @{$config{cxxflags}}, "-fno-omit-frame-pointer", "-g" if $config{cxx};
1271 # This saves the build files from having to check
1274 foreach (qw(shared_cflag shared_cxxflag shared_cppflag
1275 shared_defines shared_includes shared_ldflag
1276 dso_cflags dso_cxxflags dso_cppflags
1277 dso_defines dso_includes dso_lflags))
1285 push @{$config{defines}}, "OPENSSL_PIC";
1288 if ($target{sys_id} ne "")
1290 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1293 unless ($disabled{asm}) {
1294 $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1295 push @{$config{defines}}, "OPENSSL_CPUID_OBJ" if ($target{cpuid_asm_src} ne "mem_clr.o");
1297 $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1299 # bn-586 is the only one implementing bn_*_part_words
1300 push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1301 push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$disabled{sse2} && $target{bn_asm_src} =~ /86/);
1303 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1304 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1305 push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1307 if ($target{sha1_asm_src}) {
1308 push @{$config{defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1309 push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1310 push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1312 if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
1313 push @{$config{defines}}, "RC4_ASM";
1315 if ($target{md5_asm_src}) {
1316 push @{$config{defines}}, "MD5_ASM";
1318 $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1319 if ($target{rmd160_asm_src}) {
1320 push @{$config{defines}}, "RMD160_ASM";
1322 if ($target{aes_asm_src}) {
1323 push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1324 # aes-ctr.fake is not a real file, only indication that assembler
1325 # module implements AES_ctr32_encrypt...
1326 push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1327 # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1328 push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1329 $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($disabled{sse2});
1330 push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1331 push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1333 if ($target{wp_asm_src} =~ /mmx/) {
1334 if ($config{processor} eq "386") {
1335 $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1336 } elsif (!$disabled{"whirlpool"}) {
1337 push @{$config{defines}}, "WHIRLPOOL_ASM";
1340 if ($target{modes_asm_src} =~ /ghash-/) {
1341 push @{$config{defines}}, "GHASH_ASM";
1343 if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1344 push @{$config{defines}}, "ECP_NISTZ256_ASM";
1346 if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) {
1347 push @{$config{defines}}, "PADLOCK_ASM";
1349 if ($target{poly1305_asm_src} ne "") {
1350 push @{$config{defines}}, "POLY1305_ASM";
1354 my %predefined = compiler_predefined($config{cc});
1356 # Check for makedepend capabilities.
1357 if (!$disabled{makedepend}) {
1358 if ($config{target} =~ /^(VC|vms)-/) {
1359 # For VC- and vms- targets, there's nothing more to do here. The
1360 # functionality is hard coded in the corresponding build files for
1361 # cl (Windows) and CC/DECC (VMS).
1362 } elsif ($predefined{__GNUC__} >= 3) {
1363 # We know that GNU C version 3 and up as well as all clang
1364 # versions support dependency generation
1365 $config{makedepprog} = "\$(CROSS_COMPILE)$config{cc}";
1367 # In all other cases, we look for 'makedepend', and disable the
1368 # capability if not found.
1369 $config{makedepprog} = which('makedepend');
1370 $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1375 # Deal with bn_ops ###################################################
1378 $config{export_var_as_fn} =0;
1379 my $def_int="unsigned int";
1380 $config{rc4_int} =$def_int;
1381 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1384 foreach (sort split(/\s+/,$target{bn_ops})) {
1385 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1386 $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN';
1387 $config{bn_ll}=1 if $_ eq 'BN_LLONG';
1388 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
1389 ($config{b64l},$config{b64},$config{b32})
1390 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
1391 ($config{b64l},$config{b64},$config{b32})
1392 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
1393 ($config{b64l},$config{b64},$config{b32})
1394 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
1396 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1400 # Hack cflags for better warnings (dev option) #######################
1402 # "Stringify" the C and C++ flags string. This permits it to be made part of
1403 # a string and works as well on command lines.
1404 $config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1405 @{$config{cflags}} ];
1406 $config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x }
1407 @{$config{cxxflags}} ] if $config{cxx};
1409 if (defined($config{api})) {
1410 $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1411 my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1412 push @{$config{defines}}, $apiflag;
1415 if (defined($predefined{__clang__}) && !$disabled{asm}) {
1416 push @{$config{cflags}}, "-Qunused-arguments";
1417 push @{$config{cxxflags}}, "-Qunused-arguments" if $config{cxx};
1420 if ($strict_warnings)
1423 my $gccver = $predefined{__GNUC__} // -1;
1425 die "ERROR --strict-warnings requires gcc[>=4] or gcc-alike"
1426 unless $gccver >= 4;
1427 $gcc_devteam_warn .= " -Wmisleading-indentation" if $gccver >= 6;
1428 foreach $wopt (split /\s+/, $gcc_devteam_warn)
1430 push @{$config{cflags}}, $wopt
1431 unless grep { $_ eq $wopt } @{$config{cflags}};
1432 push @{$config{cxxflags}}, $wopt
1434 && !grep { $_ eq $wopt } @{$config{cxxflags}});
1436 if (defined($predefined{__clang__}))
1438 foreach $wopt (split /\s+/, $clang_devteam_warn)
1440 push @{$config{cflags}}, $wopt
1441 unless grep { $_ eq $wopt } @{$config{cflags}};
1442 push @{$config{cxxflags}}, $wopt
1444 && !grep { $_ eq $wopt } @{$config{cxxflags}});
1449 unless ($disabled{"crypto-mdebug-backtrace"})
1451 foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1453 push @{$config{cflags}}, $wopt
1454 unless grep { $_ eq $wopt } @{$config{cflags}};
1455 push @{$config{cxxflags}}, $wopt
1457 && !grep { $_ eq $wopt } @{$config{cxxflags}});
1459 if ($target =~ /^BSD-/)
1461 push @{$config{ex_libs}}, "-lexecinfo";
1465 unless ($disabled{afalgeng}) {
1466 $config{afalgeng}="";
1467 if ($target =~ m/^linux/) {
1468 my $minver = 4*10000 + 1*100 + 0;
1469 if ($config{cross_compile_prefix} eq "") {
1470 my $verstr = `uname -r`;
1471 my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1472 ($mi2) = $mi2 =~ /(\d+)/;
1473 my $ver = $ma*10000 + $mi1*100 + $mi2;
1474 if ($ver < $minver) {
1475 $disabled{afalgeng} = "too-old-kernel";
1477 push @{$config{engdirs}}, "afalg";
1480 $disabled{afalgeng} = "cross-compiling";
1483 $disabled{afalgeng} = "not-linux";
1487 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1489 # Finish up %config by appending things the user gave us on the command line
1490 # apart from "make variables"
1491 foreach (keys %useradd) {
1492 # The must all be lists, so we assert that here
1493 die "internal error: \$useradd{$_} isn't an ARRAY\n"
1494 unless ref $useradd{$_} eq 'ARRAY';
1496 my $target_key = $user_to_target{$_} // lc $_;
1498 if (defined $config{$target_key}) {
1499 push @{$config{$target_key}}, @{$useradd{$_}};
1501 $config{$target_key} = [ @{$useradd{$_}} ];
1505 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1507 # If we use the unified build, collect information from build.info files
1508 my %unified_info = ();
1510 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1511 if ($builder eq "unified") {
1512 use with_fallback qw(Text::Template);
1517 my $relativeto = shift || ".";
1519 $dir = catdir($base,$dir) unless isabsolute($dir);
1521 # Make sure the directories we're building in exists
1524 my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1525 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1532 my $relativeto = shift || ".";
1534 $file = catfile($base,$file) unless isabsolute($file);
1536 my $d = dirname($file);
1537 my $f = basename($file);
1539 # Make sure the directories we're building in exists
1542 my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1543 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1547 # Store the name of the template file we will build the build file from
1548 # in %config. This may be useful for the build file itself.
1549 my @build_file_template_names =
1550 ( $builder_platform."-".$target{build_file}.".tmpl",
1551 $target{build_file}.".tmpl" );
1552 my @build_file_templates = ();
1554 # First, look in the user provided directory, if given
1555 if (defined env($local_config_envname)) {
1556 @build_file_templates =
1559 # VMS environment variables are logical names,
1560 # which can be used as is
1561 $local_config_envname . ':' . $_;
1563 catfile(env($local_config_envname), $_);
1566 @build_file_template_names;
1568 # Then, look in our standard directory
1569 push @build_file_templates,
1570 ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1571 @build_file_template_names );
1573 my $build_file_template;
1574 for $_ (@build_file_templates) {
1575 $build_file_template = $_;
1576 last if -f $build_file_template;
1578 $build_file_template = undef;
1580 if (!defined $build_file_template) {
1581 die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1583 $config{build_file_templates}
1584 = [ $build_file_template,
1585 cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1588 my @build_infos = ( [ ".", "build.info" ] );
1589 foreach (@{$config{dirs}}) {
1590 push @build_infos, [ $_, "build.info" ]
1591 if (-f catfile($srcdir, $_, "build.info"));
1593 foreach (@{$config{sdirs}}) {
1594 push @build_infos, [ catdir("crypto", $_), "build.info" ]
1595 if (-f catfile($srcdir, "crypto", $_, "build.info"));
1597 foreach (@{$config{engdirs}}) {
1598 push @build_infos, [ catdir("engines", $_), "build.info" ]
1599 if (-f catfile($srcdir, "engines", $_, "build.info"));
1601 foreach (@{$config{tdirs}}) {
1602 push @build_infos, [ catdir("test", $_), "build.info" ]
1603 if (-f catfile($srcdir, "test", $_, "build.info"));
1606 $config{build_infos} = [ ];
1609 foreach (@build_infos) {
1610 my $sourced = catdir($srcdir, $_->[0]);
1611 my $buildd = catdir($blddir, $_->[0]);
1616 # The basic things we're trying to build
1618 my @programs_install = ();
1620 my @libraries_install = ();
1622 my @engines_install = ();
1624 my @scripts_install = ();
1627 my @intermediates = ();
1631 my %shared_sources = ();
1635 my %sharednames = ();
1638 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1640 Text::Template->new(TYPE => 'FILE',
1641 SOURCE => catfile($sourced, $f),
1642 PREPEND => qq{use lib "$FindBin::Bin/util/perl";});
1643 die "Something went wrong with $sourced/$f: $!\n" unless $template;
1646 $template->fill_in(HASH => { config => \%config,
1648 disabled => \%disabled,
1649 withargs => \%withargs,
1650 builddir => abs2rel($buildd, $blddir),
1651 sourcedir => abs2rel($sourced, $blddir),
1652 buildtop => abs2rel($blddir, $blddir),
1653 sourcetop => abs2rel($srcdir, $blddir) },
1654 DELIMITERS => [ "{-", "-}" ]);
1656 # The top item of this stack has the following values
1657 # -2 positive already run and we found ELSE (following ELSIF should fail)
1658 # -1 positive already run (skip until ENDIF)
1659 # 0 negatives so far (if we're at a condition, check it)
1660 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1661 # 2 positive ELSE (following ELSIF should fail)
1663 collect_information(
1664 collect_from_array([ @text ],
1665 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1666 $l1 =~ s/\\$//; $l1.$l2 }),
1667 # Info we're looking for
1668 qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1670 if (! @skip || $skip[$#skip] > 0) {
1676 qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1677 => sub { die "ELSIF out of scope" if ! @skip;
1678 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1679 $skip[$#skip] = -1 if $skip[$#skip] != 0;
1680 $skip[$#skip] = !! $1
1681 if $skip[$#skip] == 0; },
1683 => sub { die "ELSE out of scope" if ! @skip;
1684 $skip[$#skip] = -2 if $skip[$#skip] != 0;
1685 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1687 => sub { die "ENDIF out of scope" if ! @skip;
1689 qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1691 if (!@skip || $skip[$#skip] > 0) {
1693 my @x = tokenize($2);
1695 push @programs_install, @x unless $install;
1698 qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1700 if (!@skip || $skip[$#skip] > 0) {
1702 my @x = tokenize($2);
1703 push @libraries, @x;
1704 push @libraries_install, @x unless $install;
1707 qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1709 if (!@skip || $skip[$#skip] > 0) {
1711 my @x = tokenize($2);
1713 push @engines_install, @x unless $install;
1716 qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1718 if (!@skip || $skip[$#skip] > 0) {
1720 my @x = tokenize($2);
1722 push @scripts_install, @x unless $install;
1725 qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1726 => sub { push @extra, tokenize($1)
1727 if !@skip || $skip[$#skip] > 0 },
1728 qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1729 => sub { push @overrides, tokenize($1)
1730 if !@skip || $skip[$#skip] > 0 },
1732 qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1733 => sub { push @{$ordinals{$1}}, tokenize($2)
1734 if !@skip || $skip[$#skip] > 0 },
1735 qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1736 => sub { push @{$sources{$1}}, tokenize($2)
1737 if !@skip || $skip[$#skip] > 0 },
1738 qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1739 => sub { push @{$shared_sources{$1}}, tokenize($2)
1740 if !@skip || $skip[$#skip] > 0 },
1741 qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1742 => sub { push @{$includes{$1}}, tokenize($2)
1743 if !@skip || $skip[$#skip] > 0 },
1744 qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
1745 => sub { push @{$depends{$1}}, tokenize($2)
1746 if !@skip || $skip[$#skip] > 0 },
1747 qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1748 => sub { push @{$generate{$1}}, $2
1749 if !@skip || $skip[$#skip] > 0 },
1750 qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1751 => sub { push @{$renames{$1}}, tokenize($2)
1752 if !@skip || $skip[$#skip] > 0 },
1753 qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1754 => sub { push @{$sharednames{$1}}, tokenize($2)
1755 if !@skip || $skip[$#skip] > 0 },
1756 qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1758 my $lineiterator = shift;
1759 my $target_kind = $1;
1760 while (defined $lineiterator->()) {
1762 if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1763 die "ENDRAW doesn't match BEGINRAW"
1764 if $1 ne $target_kind;
1767 next if @skip && $skip[$#skip] <= 0;
1769 if ($target_kind eq $target{build_file}
1770 || $target_kind eq $target{build_file}."(".$builder_platform.")");
1773 qr/^\s*(?:#.*)?$/ => sub { },
1774 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1776 if ($buildinfo_debug) {
1777 print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1778 print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1782 if ($buildinfo_debug) {
1783 print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1787 die "runaway IF?" if (@skip);
1789 foreach (keys %renames) {
1790 die "$_ renamed to more than one thing: "
1791 ,join(" ", @{$renames{$_}}),"\n"
1792 if scalar @{$renames{$_}} > 1;
1793 my $dest = cleanfile($buildd, $_, $blddir);
1794 my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1795 die "$dest renamed to more than one thing: "
1796 ,$unified_info{rename}->{$dest}, $to
1797 unless !defined($unified_info{rename}->{$dest})
1798 or $unified_info{rename}->{$dest} eq $to;
1799 $unified_info{rename}->{$dest} = $to;
1802 foreach (@programs) {
1803 my $program = cleanfile($buildd, $_, $blddir);
1804 if ($unified_info{rename}->{$program}) {
1805 $program = $unified_info{rename}->{$program};
1807 $unified_info{programs}->{$program} = 1;
1810 foreach (@programs_install) {
1811 my $program = cleanfile($buildd, $_, $blddir);
1812 if ($unified_info{rename}->{$program}) {
1813 $program = $unified_info{rename}->{$program};
1815 $unified_info{install}->{programs}->{$program} = 1;
1818 foreach (@libraries) {
1819 my $library = cleanfile($buildd, $_, $blddir);
1820 if ($unified_info{rename}->{$library}) {
1821 $library = $unified_info{rename}->{$library};
1823 $unified_info{libraries}->{$library} = 1;
1826 foreach (@libraries_install) {
1827 my $library = cleanfile($buildd, $_, $blddir);
1828 if ($unified_info{rename}->{$library}) {
1829 $library = $unified_info{rename}->{$library};
1831 $unified_info{install}->{libraries}->{$library} = 1;
1834 die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1835 ENGINES can only be used if configured with 'dynamic-engine'.
1836 This is usually a fault in a build.info file.
1838 foreach (@engines) {
1839 my $library = cleanfile($buildd, $_, $blddir);
1840 if ($unified_info{rename}->{$library}) {
1841 $library = $unified_info{rename}->{$library};
1843 $unified_info{engines}->{$library} = 1;
1846 foreach (@engines_install) {
1847 my $library = cleanfile($buildd, $_, $blddir);
1848 if ($unified_info{rename}->{$library}) {
1849 $library = $unified_info{rename}->{$library};
1851 $unified_info{install}->{engines}->{$library} = 1;
1854 foreach (@scripts) {
1855 my $script = cleanfile($buildd, $_, $blddir);
1856 if ($unified_info{rename}->{$script}) {
1857 $script = $unified_info{rename}->{$script};
1859 $unified_info{scripts}->{$script} = 1;
1862 foreach (@scripts_install) {
1863 my $script = cleanfile($buildd, $_, $blddir);
1864 if ($unified_info{rename}->{$script}) {
1865 $script = $unified_info{rename}->{$script};
1867 $unified_info{install}->{scripts}->{$script} = 1;
1871 my $extra = cleanfile($buildd, $_, $blddir);
1872 $unified_info{extra}->{$extra} = 1;
1875 foreach (@overrides) {
1876 my $override = cleanfile($buildd, $_, $blddir);
1877 $unified_info{overrides}->{$override} = 1;
1880 push @{$unified_info{rawlines}}, @rawlines;
1882 unless ($disabled{shared}) {
1883 # Check sharednames.
1884 foreach (keys %sharednames) {
1885 my $dest = cleanfile($buildd, $_, $blddir);
1886 if ($unified_info{rename}->{$dest}) {
1887 $dest = $unified_info{rename}->{$dest};
1889 die "shared_name for $dest with multiple values: "
1890 ,join(" ", @{$sharednames{$_}}),"\n"
1891 if scalar @{$sharednames{$_}} > 1;
1892 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1893 die "shared_name found for a library $dest that isn't defined\n"
1894 unless $unified_info{libraries}->{$dest};
1895 die "shared_name for $dest with multiple values: "
1896 ,$unified_info{sharednames}->{$dest}, ", ", $to
1897 unless !defined($unified_info{sharednames}->{$dest})
1898 or $unified_info{sharednames}->{$dest} eq $to;
1899 $unified_info{sharednames}->{$dest} = $to;
1902 # Additionally, we set up sharednames for libraries that don't
1903 # have any, as themselves. Only for libraries that aren't
1904 # explicitly static.
1905 foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) {
1906 if (!defined $unified_info{sharednames}->{$_}) {
1907 $unified_info{sharednames}->{$_} = $_
1911 # Check that we haven't defined any library as both shared and
1912 # explicitly static. That is forbidden.
1914 foreach (grep /\.a$/, keys %{$unified_info{libraries}}) {
1915 (my $l = $_) =~ s/\.a$//;
1916 push @doubles, $l if defined $unified_info{sharednames}->{$l};
1918 die "these libraries are both explicitly static and shared:\n ",
1919 join(" ", @doubles), "\n"
1923 foreach (keys %sources) {
1925 my $ddest = cleanfile($buildd, $_, $blddir);
1926 if ($unified_info{rename}->{$ddest}) {
1927 $ddest = $unified_info{rename}->{$ddest};
1929 foreach (@{$sources{$dest}}) {
1930 my $s = cleanfile($sourced, $_, $blddir);
1932 # If it isn't in the source tree, we assume it's generated
1935 $s = cleanfile($buildd, $_, $blddir);
1937 # We recognise C++, C and asm files
1938 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1940 $o =~ s/\.[csS]$/.o/; # C and assembler
1941 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1942 $o = cleanfile($buildd, $o, $blddir);
1943 $unified_info{sources}->{$ddest}->{$o} = 1;
1944 $unified_info{sources}->{$o}->{$s} = 1;
1946 $unified_info{sources}->{$ddest}->{$s} = 1;
1951 foreach (keys %shared_sources) {
1953 my $ddest = cleanfile($buildd, $_, $blddir);
1954 if ($unified_info{rename}->{$ddest}) {
1955 $ddest = $unified_info{rename}->{$ddest};
1957 foreach (@{$shared_sources{$dest}}) {
1958 my $s = cleanfile($sourced, $_, $blddir);
1960 # If it isn't in the source tree, we assume it's generated
1963 $s = cleanfile($buildd, $_, $blddir);
1966 if ($s =~ /\.(cc|cpp|c|s|S)$/) {
1967 # We recognise C++, C and asm files
1969 $o =~ s/\.[csS]$/.o/; # C and assembler
1970 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++
1971 $o = cleanfile($buildd, $o, $blddir);
1972 $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1973 $unified_info{sources}->{$o}->{$s} = 1;
1974 } elsif ($s =~ /\.rc$/) {
1975 # We also recognise resource files
1977 $o =~ s/\.rc$/.res/; # Resource configuration
1978 my $o = cleanfile($buildd, $o, $blddir);
1979 $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1980 $unified_info{sources}->{$o}->{$s} = 1;
1981 } elsif ($s =~ /\.(def|map|opt)$/) {
1982 # We also recognise .def / .map / .opt files
1983 # We know they are generated files
1984 my $def = cleanfile($buildd, $s, $blddir);
1985 $unified_info{shared_sources}->{$ddest}->{$def} = 1;
1987 die "unrecognised source file type for shared library: $s\n";
1992 foreach (keys %generate) {
1994 my $ddest = cleanfile($buildd, $_, $blddir);
1995 if ($unified_info{rename}->{$ddest}) {
1996 $ddest = $unified_info{rename}->{$ddest};
1998 die "more than one generator for $dest: "
1999 ,join(" ", @{$generate{$_}}),"\n"
2000 if scalar @{$generate{$_}} > 1;
2001 my @generator = split /\s+/, $generate{$dest}->[0];
2002 $generator[0] = cleanfile($sourced, $generator[0], $blddir),
2003 $unified_info{generate}->{$ddest} = [ @generator ];
2006 foreach (keys %depends) {
2008 my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
2010 # If the destination doesn't exist in source, it can only be
2011 # a generated file in the build tree.
2012 if ($ddest ne "" && ! -f $ddest) {
2013 $ddest = cleanfile($buildd, $_, $blddir);
2014 if ($unified_info{rename}->{$ddest}) {
2015 $ddest = $unified_info{rename}->{$ddest};
2018 foreach (@{$depends{$dest}}) {
2019 my $d = cleanfile($sourced, $_, $blddir);
2021 # If we know it's generated, or assume it is because we can't
2022 # find it in the source tree, we set file we depend on to be
2023 # in the build tree rather than the source tree, and assume
2024 # and that there are lines to build it in a BEGINRAW..ENDRAW
2025 # section or in the Makefile template.
2027 || (grep { $d eq $_ }
2028 map { cleanfile($srcdir, $_, $blddir) }
2029 grep { /\.h$/ } keys %{$unified_info{generate}})) {
2030 $d = cleanfile($buildd, $_, $blddir);
2032 # Take note if the file to depend on is being renamed
2033 # Take extra care with files ending with .a, they should
2034 # be treated without that extension, and the extension
2035 # should be added back after treatment.
2039 if ($unified_info{rename}->{$d}) {
2040 $d = $unified_info{rename}->{$d};
2043 $unified_info{depends}->{$ddest}->{$d} = 1;
2047 foreach (keys %includes) {
2049 my $ddest = cleanfile($sourced, $_, $blddir);
2051 # If the destination doesn't exist in source, it can only be
2052 # a generated file in the build tree.
2054 $ddest = cleanfile($buildd, $_, $blddir);
2055 if ($unified_info{rename}->{$ddest}) {
2056 $ddest = $unified_info{rename}->{$ddest};
2059 foreach (@{$includes{$dest}}) {
2060 my $is = cleandir($sourced, $_, $blddir);
2061 my $ib = cleandir($buildd, $_, $blddir);
2062 push @{$unified_info{includes}->{$ddest}->{source}}, $is
2063 unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
2064 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
2065 unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
2070 my $ordinals_text = join(', ', sort keys %ordinals);
2071 warn <<"EOF" if $ordinals_text;
2073 WARNING: ORDINALS were specified for $ordinals_text
2074 They are ignored and should be replaced with a combination of GENERATE,
2075 DEPEND and SHARED_SOURCE.
2078 # Massage the result
2080 # If we depend on a header file or a perl module, add an inclusion of
2081 # its directory to allow smoothe inclusion
2082 foreach my $dest (keys %{$unified_info{depends}}) {
2083 next if $dest eq "";
2084 foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
2085 next unless $d =~ /\.(h|pm)$/;
2086 if ($d eq "configdata.pm"
2087 || defined($unified_info{generate}->{$d})) {
2088 my $i = cleandir($blddir, dirname($d));
2089 push @{$unified_info{includes}->{$dest}->{build}}, $i
2090 unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{build}};
2092 my $i = cleandir($srcdir, dirname($d));
2093 push @{$unified_info{includes}->{$dest}->{source}}, $i
2094 unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{source}};
2099 # Trickle down includes placed on libraries, engines and programs to
2100 # their sources (i.e. object files)
2101 foreach my $dest (keys %{$unified_info{engines}},
2102 keys %{$unified_info{libraries}},
2103 keys %{$unified_info{programs}}) {
2104 foreach my $k (("source", "build")) {
2105 next unless defined($unified_info{includes}->{$dest}->{$k});
2106 my @incs = reverse @{$unified_info{includes}->{$dest}->{$k}};
2107 foreach my $obj (grep /\.o$/,
2108 (keys %{$unified_info{sources}->{$dest}},
2109 keys %{$unified_info{shared_sources}->{$dest}})) {
2110 foreach my $inc (@incs) {
2111 unshift @{$unified_info{includes}->{$obj}->{$k}}, $inc
2112 unless grep { $_ eq $inc } @{$unified_info{includes}->{$obj}->{$k}};
2116 delete $unified_info{includes}->{$dest};
2119 ### Make unified_info a bit more efficient
2120 # One level structures
2121 foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
2122 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
2124 # Two level structures
2125 foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
2126 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
2127 $unified_info{$l1}->{$l2} =
2128 [ sort keys %{$unified_info{$l1}->{$l2}} ];
2132 foreach my $dest (sort keys %{$unified_info{includes}}) {
2133 if (defined($unified_info{includes}->{$dest}->{build})) {
2134 my @source_includes = ();
2135 @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} )
2136 if defined($unified_info{includes}->{$dest}->{source});
2137 $unified_info{includes}->{$dest} =
2138 [ @{$unified_info{includes}->{$dest}->{build}} ];
2139 foreach my $inc (@source_includes) {
2140 push @{$unified_info{includes}->{$dest}}, $inc
2141 unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
2144 $unified_info{includes}->{$dest} =
2145 [ @{$unified_info{includes}->{$dest}->{source}} ];
2150 # For the schemes that need it, we provide the old *_obj configs
2151 # from the *_asm_obj ones
2152 foreach (grep /_(asm|aux)_src$/, keys %target) {
2154 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
2155 $target{$obj} = $target{$src};
2156 $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler
2157 $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++
2160 # Write down our configuration where it fits #########################
2162 print "Creating configdata.pm\n";
2163 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
2165 #! $config{hashbangperl}
2173 #use vars qw(\@ISA \@EXPORT);
2174 our \@ISA = qw(Exporter);
2175 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
2178 print OUT "our %config = (\n";
2179 foreach (sort keys %config) {
2180 if (ref($config{$_}) eq "ARRAY") {
2181 print OUT " ", $_, " => [ ", join(", ",
2182 map { quotify("perl", $_) }
2183 @{$config{$_}}), " ],\n";
2184 } elsif (ref($config{$_}) eq "HASH") {
2185 print OUT " ", $_, " => {";
2186 if (scalar keys %{$config{$_}} > 0) {
2188 foreach my $key (sort keys %{$config{$_}}) {
2191 quotify("perl", $key),
2192 defined $config{$_}->{$key}
2193 ? quotify("perl", $config{$_}->{$key})
2201 print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n"
2208 print OUT "our %target = (\n";
2209 foreach (sort keys %target) {
2210 if (ref($target{$_}) eq "ARRAY") {
2211 print OUT " ", $_, " => [ ", join(", ",
2212 map { quotify("perl", $_) }
2213 @{$target{$_}}), " ],\n";
2215 print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n"
2222 print OUT "our \%available_protocols = (\n";
2223 print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
2224 print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
2229 print OUT "our \@disablables = (\n";
2230 foreach (@disablables) {
2231 print OUT " ", quotify("perl", $_), ",\n";
2237 print OUT "our \%disabled = (\n";
2238 foreach (sort keys %disabled) {
2239 print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
2245 print OUT "our %withargs = (\n";
2246 foreach (sort keys %withargs) {
2247 if (ref($withargs{$_}) eq "ARRAY") {
2248 print OUT " ", $_, " => [ ", join(", ",
2249 map { quotify("perl", $_) }
2250 @{$withargs{$_}}), " ],\n";
2252 print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
2259 if ($builder eq "unified") {
2264 if (ref $_ eq "ARRAY") {
2265 print OUT " "x$indent, "[\n";
2267 $recurse->($indent + 4, $_);
2269 print OUT " "x$indent, "],\n";
2270 } elsif (ref $_ eq "HASH") {
2272 print OUT " "x$indent, "{\n";
2273 foreach (sort keys %h) {
2274 if (ref $h{$_} eq "") {
2275 print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
2277 print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
2278 $recurse->($indent + 8, $h{$_});
2281 print OUT " "x$indent, "},\n";
2283 print OUT " "x$indent, quotify("perl", $_), ",\n";
2287 print OUT "our %unified_info = (\n";
2288 foreach (sort keys %unified_info) {
2289 if (ref $unified_info{$_} eq "") {
2290 print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
2292 print OUT " "x4, quotify("perl", $_), " =>\n";
2293 $recurse->(8, $unified_info{$_});
2301 print OUT "my \%makevars = (\n";
2302 foreach (sort keys %user) {
2303 print OUT ' ',$_,' ' x (20 - length $_),'=> ',
2304 "'",$user_to_target{$_} || lc $_,"',\n";
2307 print OUT "my \%disabled_info = (\n";
2308 foreach my $what (sort keys %disabled_info) {
2309 print OUT " '$what' => {\n";
2310 foreach my $info (sort keys %{$disabled_info{$what}}) {
2311 if (ref $disabled_info{$what}->{$info} eq 'ARRAY') {
2312 print OUT " $info => [ ",
2313 join(', ', map { "'$_'" } @{$disabled_info{$what}->{$info}}),
2316 print OUT " $info => '", $disabled_info{$what}->{$info},
2324 # If run directly, we can give some answers, and even reconfigure
2327 use File::Spec::Functions;
2331 my $here = dirname($0);
2334 my $cmdline = undef;
2335 my $options = undef;
2337 my $envvars = undef;
2338 my $makevars = undef;
2339 my $buildparams = undef;
2341 my $verbose = undef;
2344 GetOptions('dump|d' => \$dump,
2345 'command-line|c' => \$cmdline,
2346 'options|o' => \$options,
2347 'target|t' => \$target,
2348 'environment|e' => \$envvars,
2349 'make-variables|m' => \$makevars,
2350 'build-parameters|b' => \$buildparams,
2351 'reconfigure|reconf|r' => \$reconf,
2352 'verbose|v' => \$verbose,
2355 or die "Errors in command line arguments\n";
2357 unless ($dump || $cmdline || $options || $target || $envvars || $makevars
2358 || $buildparams || $reconf || $verbose || $help || $man) {
2359 print STDERR <<"_____";
2360 You must give at least one option.
2361 For more information, do '$0 --help'
2367 pod2usage(-exitval => 0,
2371 pod2usage(-exitval => 0,
2374 if ($dump || $cmdline) {
2375 print "\n(with current working directory = $here)";
2376 print "\nCommand line:\n\n";
2379 catfile($config{sourcedir}, 'Configure'),
2380 @{$config{perlargv}}), "\n";
2382 if ($dump || $options) {
2384 foreach my $what (@disablables) {
2385 $longest = length($what) if $longest < length($what);
2387 print "\nEnabled features:\n\n";
2388 foreach my $what (@disablables) {
2389 print " $what\n" unless $disabled{$what};
2391 print "\nDisabled features:\n\n";
2392 foreach my $what (@disablables) {
2393 if ($disabled{$what}) {
2394 print " $what", ' ' x ($longest - length($what) + 1),
2395 "[$disabled{$what}]", ' ' x (10 - length($disabled{$what}));
2396 print $disabled_info{$what}->{macro}
2397 if $disabled_info{$what}->{macro};
2399 join(', ', @{$disabled_info{$what}->{skipped}}),
2401 if $disabled_info{$what}->{skipped};
2406 if ($dump || $target) {
2407 print "\nConfig target attributes:\n\n";
2408 foreach (sort keys %target) {
2409 next if $_ =~ m|^_| || $_ eq 'template';
2411 map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_;
2413 print ' ', $_, ' => ';
2414 if (ref($target{$_}) eq "ARRAY") {
2415 print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n";
2417 print $quotify->($target{$_}), ",\n"
2421 if ($dump || $envvars) {
2422 print "\nRecorded environment:\n\n";
2423 foreach (sort keys %{$config{perlenv}}) {
2424 print ' ',$_,' = ',($config{perlenv}->{$_} || ''),"\n";
2427 if ($dump || $makevars) {
2428 print "\nMakevars:\n\n";
2429 foreach (sort keys %makevars) {
2430 print ' ',$_,' ' x (16 - length $_),'= ',
2431 (ref $config{$makevars{$_}} eq 'ARRAY'
2432 ? join(' ', @{$config{$makevars{$_}}})
2433 : $config{$makevars{$_}}),
2435 if defined $config{$makevars{$_}};
2438 my @buildfile = ($config{builddir}, $config{build_file});
2439 unshift @buildfile, $here
2440 unless file_name_is_absolute($config{builddir});
2441 my $buildfile = canonpath(catdir(@buildfile));
2444 NOTE: These variables only represent the configuration view. The build file
2445 template may have processed these variables further, please have a look at the
2446 build file for more exact data:
2450 if ($dump || $buildparams) {
2451 my @buildfile = ($config{builddir}, $config{build_file});
2452 unshift @buildfile, $here
2453 unless file_name_is_absolute($config{builddir});
2454 print "\nbuild file:\n\n";
2455 print " ", canonpath(catfile(@buildfile)),"\n";
2457 print "\nbuild file templates:\n\n";
2458 foreach (@{$config{build_file_templates}}) {
2460 unshift @tmpl, $here
2461 unless file_name_is_absolute($config{sourcedir});
2462 print ' ',canonpath(catfile(@tmpl)),"\n";
2467 print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n";
2468 foreach (sort keys %{$config{perlenv}}) {
2469 print ' ',$_,' = ',($config{perlenv}->{$_} || ""),"\n";
2474 exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf';
2484 configdata.pm - configuration data for OpenSSL builds
2490 perl configdata.pm [options]
2492 As data bank module:
2498 This module can be used in two modes, interactively and as a module containing
2499 all the data recorded by OpenSSL's Configure script.
2501 When used interactively, simply run it as any perl script, with at least one
2502 option, and you will get the information you ask for. See L</OPTIONS> below.
2504 When loaded as a module, you get a few databanks with useful information to
2505 perform build related tasks. The databanks are:
2507 %config Configured things.
2508 %target The OpenSSL config target with all inheritances
2510 %disabled The features that are disabled.
2511 @disablables The list of features that can be disabled.
2512 %withargs All data given through --with-THING options.
2513 %unified_info All information that was computed from the build.info
2522 Print a brief help message and exit.
2526 Print the manual page and exit.
2528 =item B<--dump> | B<-d>
2530 Print all relevant configuration data. This is equivalent to B<--command-line>
2531 B<--options> B<--target> B<--environment> B<--make-variables>
2532 B<--build-parameters>.
2534 =item B<--command-line> | B<-c>
2536 Print the current configuration command line.
2538 =item B<--options> | B<-o>
2540 Print the features, both enabled and disabled, and display defined macro and
2541 skipped directories where applicable.
2543 =item B<--target> | B<-t>
2545 Print the config attributes for this config target.
2547 =item B<--environment> | B<-e>
2549 Print the environment variables and their values at the time of configuration.
2551 =item B<--make-variables> | B<-m>
2553 Print the main make variables generated in the current configuration
2555 =item B<--build-parameters> | B<-b>
2557 Print the build parameters, i.e. build file and build file templates.
2559 =item B<--reconfigure> | B<--reconf> | B<-r>
2561 Redo the configuration.
2563 =item B<--verbose> | B<-v>
2573 if ($builder_platform eq 'unix') {
2574 my $mode = (0755 & ~umask);
2575 chmod $mode, 'configdata.pm'
2576 or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!);
2581 print 'Creating ',$target{build_file},"\n";
2582 run_dofile(catfile($blddir, $target{build_file}),
2583 @{$config{build_file_templates}});
2587 $builders{$builder}->($builder_platform, @builder_opts);
2589 # Show a note on the use of configdata.pm, but ONLY for release 1.1.1
2590 # (i.e. this message disappears with the following update, 1.1.1a)
2591 print <<"EOF" if ($config{version_num} =~ m|^0x1010100.L$|);
2593 NOTE: Starting with OpenSSL 1.1.1, 'Configure' doesn't display all the disabled
2594 options or the "make variables" with their values. Instead, you must use
2595 'configdata.pm' as a script to get a display of the configuration data. For
2596 help, please do this:
2598 perl configdata.pm --help
2600 print <<"EOF" if ($disabled{threads} eq "unavailable");
2602 The library could not be configured for supporting multi-threaded
2603 applications as the compiler options required on this system are not known.
2604 See file INSTALL for details if you need multi-threading.
2607 print <<"EOF" if ($no_shared_warn);
2609 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2610 platform, so we will pretend you gave the option 'no-pic', which also disables
2611 'shared' and 'dynamic-engine'. If you know how to implement shared libraries
2612 or position independent code, please let us know (but please first make sure
2613 you have tried with a current version of OpenSSL).
2616 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2618 WARNING: there are indications that another build was made in the source
2619 directory. This build may have picked up artifacts from that build, the
2620 safest course of action is to clean the source directory and redo this
2626 ######################################################################
2628 # Helpers and utility functions
2631 # Configuration file reading #########################################
2633 # Note: All of the helper functions are for lazy evaluation. They all
2634 # return a CODE ref, which will return the intended value when evaluated.
2635 # Thus, whenever there's mention of a returned value, it's about that
2638 # Helper function to implement conditional inheritance depending on the
2639 # value of $disabled{asm}. Used in inherit_from values as follows:
2641 # inherit_from => [ "template", asm("asm_tmpl") ]
2646 $disabled{asm} ? () : @x;
2650 # Helper function to implement conditional value variants, with a default
2651 # plus additional values based on the value of $config{build_type}.
2652 # Arguments are given in hash table form:
2654 # picker(default => "Basic string: ",
2656 # release => "release")
2658 # When configuring with --debug, the resulting string will be
2659 # "Basic string: debug", and when not, it will be "Basic string: release"
2661 # This can be used to create variants of sets of flags according to the
2664 # cflags => picker(default => "-Wall",
2665 # debug => "-g -O0",
2670 return sub { add($opts{default} || (),
2671 $opts{$config{build_type}} || ())->(); }
2674 # Helper function to combine several values of different types into one.
2675 # This is useful if you want to combine a string with the result of a
2676 # lazy function, such as:
2678 # cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2682 return sub { add(@stuff)->(); }
2685 # Helper function to implement conditional values depending on the value
2686 # of $disabled{threads}. Can be used as follows:
2688 # cflags => combine("-Wall", threads("-pthread"))
2692 return sub { add($disabled{threads} ? () : @flags)->(); }
2697 our $add_called = 0;
2698 # Helper function to implement adding values to already existing configuration
2699 # values. It handles elements that are ARRAYs, CODEs and scalars
2701 my $separator = shift;
2703 # If there's any ARRAY in the collection of values OR the separator
2704 # is undef, we will return an ARRAY of combined values, otherwise a
2705 # string of joined values with $separator as the separator.
2706 my $found_array = !defined($separator);
2711 while (ref($res) eq "CODE") {
2714 if (defined($res)) {
2715 if (ref($res) eq "ARRAY") {
2731 join($separator, grep { defined($_) && $_ ne "" } @values);
2735 my $separator = " ";
2736 if (ref($_[$#_]) eq "HASH") {
2738 $separator = $opts->{separator};
2741 sub { _add($separator, @x, @_) };
2744 my $separator = " ";
2745 if (ref($_[$#_]) eq "HASH") {
2747 $separator = $opts->{separator};
2750 sub { _add($separator, @_, @x) };
2753 sub read_eval_file {
2758 open F, "< $fname" or die "Can't open '$fname': $!\n";
2767 @result = ( eval $content );
2770 return wantarray ? @result : $result[0];
2773 # configuration reader, evaluates the input file as a perl script and expects
2774 # it to fill %targets with target configurations. Those are then added to
2781 # Protect certain tables from tampering
2784 %targets = read_eval_file($fname);
2786 my %preexisting = ();
2787 foreach (sort keys %targets) {
2788 $preexisting{$_} = 1 if $table{$_};
2791 The following config targets from $fname
2792 shadow pre-existing config targets with the same name:
2794 map { " $_\n" } sort keys %preexisting
2798 # For each target, check that it's configured with a hash table.
2799 foreach (keys %targets) {
2800 if (ref($targets{$_}) ne "HASH") {
2801 if (ref($targets{$_}) eq "") {
2802 warn "Deprecated target configuration for $_, ignoring...\n";
2804 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2806 delete $targets{$_};
2808 $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2812 %table = (%table, %targets);
2816 # configuration resolver. Will only resolve all the lazy evaluation
2817 # codeblocks for the chosen target and all those it inherits from,
2819 sub resolve_config {
2821 my @breadcrumbs = @_;
2823 # my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2825 if (grep { $_ eq $target } @breadcrumbs) {
2826 die "inherit_from loop! target backtrace:\n "
2827 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
2830 if (!defined($table{$target})) {
2831 warn "Warning! target $target doesn't exist!\n";
2834 # Recurse through all inheritances. They will be resolved on the
2835 # fly, so when this operation is done, they will all just be a
2836 # bunch of attributes with string values.
2837 # What we get here, though, are keys with references to lists of
2838 # the combined values of them all. We will deal with lists after
2839 # this stage is done.
2840 my %combined_inheritance = ();
2841 if ($table{$target}->{inherit_from}) {
2843 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2844 foreach (@inherit_from) {
2845 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2847 # 'template' is a marker that's considered private to
2848 # the config that had it.
2849 delete $inherited_config{template};
2851 foreach (keys %inherited_config) {
2852 if (!$combined_inheritance{$_}) {
2853 $combined_inheritance{$_} = [];
2855 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2860 # We won't need inherit_from in this target any more, since we've
2861 # resolved all the inheritances that lead to this
2862 delete $table{$target}->{inherit_from};
2864 # Now is the time to deal with those lists. Here's the place to
2865 # decide what shall be done with those lists, all based on the
2866 # values of the target we're currently dealing with.
2867 # - If a value is a coderef, it will be executed with the list of
2868 # inherited values as arguments.
2869 # - If the corresponding key doesn't have a value at all or is the
2870 # empty string, the inherited value list will be run through the
2871 # default combiner (below), and the result becomes this target's
2873 # - Otherwise, this target's value is assumed to be a string that
2874 # will simply override the inherited list of values.
2875 my $default_combiner = add();
2878 map { $_ => 1 } (keys %combined_inheritance,
2879 keys %{$table{$target}});
2881 sub process_values {
2883 my $inherited = shift; # Always a [ list ]
2889 while(ref($object) eq "CODE") {
2890 $object = $object->(@$inherited);
2892 if (!defined($object)) {
2895 elsif (ref($object) eq "ARRAY") {
2896 local $add_called; # To make sure recursive calls don't affect it
2897 return [ map { process_values($_, $inherited, $target, $entry) }
2899 } elsif (ref($object) eq "") {
2902 die "cannot handle reference type ",ref($object)
2903 ," found in target ",$target," -> ",$entry,"\n";
2907 foreach (sort keys %all_keys) {
2908 my $previous = $combined_inheritance{$_};
2910 # Current target doesn't have a value for the current key?
2911 # Assign it the default combiner, the rest of this loop body
2912 # will handle it just like any other coderef.
2913 if (!exists $table{$target}->{$_}) {
2914 $table{$target}->{$_} = $default_combiner;
2917 $table{$target}->{$_} = process_values($table{$target}->{$_},
2918 $combined_inheritance{$_},
2920 unless(defined($table{$target}->{$_})) {
2921 delete $table{$target}->{$_};
2923 # if ($extra_checks &&
2924 # $previous && !($add_called || $previous ~~ $table{$target}->{$_})) {
2925 # warn "$_ got replaced in $target\n";
2929 # Finally done, return the result.
2930 return %{$table{$target}};
2935 print STDERR $usage;
2936 print STDERR "\npick os/compiler from:\n";
2940 foreach $i (sort keys %table)
2942 next if $table{$i}->{template};
2943 next if $i =~ /^debug/;
2944 $k += length($i) + 1;
2950 print STDERR $i . " ";
2952 foreach $i (sort keys %table)
2954 next if $table{$i}->{template};
2955 next if $i !~ /^debug/;
2956 $k += length($i) + 1;
2962 print STDERR $i . " ";
2964 print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2973 unlink $out || warn "Can't remove $out, $!"
2975 foreach (@templates) {
2976 die "Can't open $_, $!" unless -f $_;
2978 my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2979 my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2980 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2983 rename("$out.new", $out) || die "Can't rename $out.new, $!";
2986 sub compiler_predefined {
2988 my $default_compiler = shift;
2990 return () if $^O eq 'VMS';
2992 die 'compiler_predefines called without a default compiler'
2993 unless $default_compiler;
2995 if (! $predefined{$default_compiler}) {
2996 my $cc = "$config{cross_compile_prefix}$default_compiler";
2998 $predefined{$default_compiler} = {};
3000 # collect compiler pre-defines from gcc or gcc-alike...
3001 open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |");
3002 while (my $l = <PIPE>) {
3003 $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last;
3004 $predefined{$default_compiler}->{$1} = $2 // '';
3009 return %{$predefined{$default_compiler}};
3016 if (eval { require IPC::Cmd; 1; }) {
3018 return scalar IPC::Cmd::can_run($name);
3020 # if there is $directories component in splitpath,
3021 # then it's not something to test with $PATH...
3022 return $name if (File::Spec->splitpath($name))[1];
3024 foreach (File::Spec->path()) {
3025 my $fullpath = catfile($_, "$name$target{exe_extension}");
3026 if (-f $fullpath and -x $fullpath) {
3037 # Note that if $ENV{$name} doesn't exist or is undefined,
3038 # $config{perlenv}->{$name} will be created with the value
3039 # undef. This is intentional.
3041 $config{perlenv}->{$name} = $ENV{$name}
3042 if ! exists $config{perlenv}->{$name};
3043 return $config{perlenv}->{$name};
3046 # Configuration printer ##############################################
3048 sub print_table_entry
3051 my %target = resolve_config($target);
3054 # Don't print the templates
3055 return if $target{template};
3119 if ($type eq "TABLE") {
3121 print "*** $target\n";
3122 foreach (@sequence) {
3123 if (ref($target{$_}) eq "ARRAY") {
3124 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
3126 printf "\$%-12s = %s\n", $_, $target{$_};
3129 } elsif ($type eq "HASH") {
3131 length((sort { length($a) <=> length($b) } @sequence)[-1]);
3132 print " '$target' => {\n";
3133 foreach (@sequence) {
3135 if (ref($target{$_}) eq "ARRAY") {
3136 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
3138 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
3146 # Utility routines ###################################################
3148 # On VMS, if the given file is a logical name, File::Spec::Functions
3149 # will consider it an absolute path. There are cases when we want a
3150 # purely syntactic check without checking the environment.
3154 # On non-platforms, we just use file_name_is_absolute().
3155 return file_name_is_absolute($file) unless $^O eq "VMS";
3157 # If the file spec includes a device or a directory spec,
3158 # file_name_is_absolute() is perfectly safe.
3159 return file_name_is_absolute($file) if $file =~ m|[:\[]|;
3161 # Here, we know the given file spec isn't absolute
3165 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
3166 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
3167 # realpath() requires that at least all path components except the last is an
3168 # existing directory. On VMS, the last component of the directory spec must
3173 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
3174 # will return the volume name for the device, no matter what. Also,
3175 # it will return an incorrect directory spec if the argument is a
3176 # directory that doesn't exist.
3178 return rel2abs($dir);
3181 # We use realpath() on Unix, since no other will properly clean out
3183 use Cwd qw/realpath/;
3185 return realpath($dir);
3190 perl => sub { my $x = shift;
3191 $x =~ s/([\\\$\@"])/\\$1/g;
3192 return '"'.$x.'"'; },
3193 maybeshell => sub { my $x = shift;
3194 (my $y = $x) =~ s/([\\\"])/\\$1/g;
3195 if ($x ne $y || $x =~ m|\s|) {
3204 defined($processors{$for}) ? $processors{$for} : sub { shift; };
3206 return map { $processor->($_); } @_;
3209 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
3210 # $filename is a file name to read from
3211 # $line_concat_cond_re is a regexp detecting a line continuation ending
3212 # $line_concat is a CODEref that takes care of concatenating two lines
3213 sub collect_from_file {
3214 my $filename = shift;
3215 my $line_concat_cond_re = shift;
3216 my $line_concat = shift;
3218 open my $fh, $filename || die "unable to read $filename: $!\n";
3220 my $saved_line = "";
3224 if (defined $line_concat) {
3225 $_ = $line_concat->($saved_line, $_);
3228 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3234 die "$filename ending with continuation line\n" if $_;
3240 # collect_from_array($array, $line_concat_cond_re, $line_concat)
3241 # $array is an ARRAYref of lines
3242 # $line_concat_cond_re is a regexp detecting a line continuation ending
3243 # $line_concat is a CODEref that takes care of concatenating two lines
3244 sub collect_from_array {
3246 my $line_concat_cond_re = shift;
3247 my $line_concat = shift;
3248 my @array = (@$array);
3251 my $saved_line = "";
3253 while (defined($_ = shift @array)) {
3255 if (defined $line_concat) {
3256 $_ = $line_concat->($saved_line, $_);
3259 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
3265 die "input text ending with continuation line\n" if $_;
3270 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
3271 # $lineiterator is a CODEref that delivers one line at a time.
3272 # All following arguments are regex/CODEref pairs, where the regexp detects a
3273 # line and the CODEref does something with the result of the regexp.
3274 sub collect_information {
3275 my $lineiterator = shift;
3276 my %collectors = @_;
3278 while(defined($_ = $lineiterator->())) {
3281 if ($collectors{"BEFORE"}) {
3282 $collectors{"BEFORE"}->($_);
3284 foreach my $re (keys %collectors) {
3285 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
3286 $collectors{$re}->($lineiterator);
3290 if ($collectors{"OTHERWISE"}) {
3291 $collectors{"OTHERWISE"}->($lineiterator, $_)
3292 unless $found || !defined $collectors{"OTHERWISE"};
3294 if ($collectors{"AFTER"}) {
3295 $collectors{"AFTER"}->($_);
3301 # $line is a line of text to split up into tokens
3302 # returns a list of tokens
3304 # Tokens are divided by spaces. If the tokens include spaces, they
3305 # have to be quoted with single or double quotes. Double quotes
3306 # inside a double quoted token must be escaped. Escaping is done
3308 # Basically, the same quoting rules apply for " and ' as in any
3311 my $line = my $debug_line = shift;
3314 while ($line =~ s|^\s+||, $line ne "") {
3316 while ($line ne "" && $line !~ m|^\s|) {
3317 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
3320 } elsif ($line =~ m/^'([^']*)'/) {
3323 } elsif ($line =~ m/^(\S+)/) {
3328 push @result, $token;
3331 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
3332 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
3333 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";