3 # Copyright 2016 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 File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
17 use File::Path qw/mkpath/;
18 use if $^O ne "VMS", 'File::Glob' => qw/glob/;
20 # see INSTALL for instructions.
22 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";
26 # --config add the given configuration file, which will be read after
27 # any "Configurations*" files that are found in the same
28 # directory as this script.
29 # --prefix prefix for the OpenSSL installation, which includes the
30 # directories bin, lib, include, share/man, share/doc/openssl
31 # This becomes the value of INSTALLTOP in Makefile
32 # (Default: /usr/local)
33 # --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys.
34 # If it's a relative directory, it will be added on the directory
35 # given with --prefix.
36 # This becomes the value of OPENSSLDIR in Makefile and in C.
37 # (Default: PREFIX/ssl)
39 # --cross-compile-prefix Add specified prefix to binutils components.
41 # --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for
42 # interfaces deprecated as of the specified OpenSSL version.
44 # no-hw-xxx do not compile support for specific crypto hardware.
45 # Generic OpenSSL-style methods relating to this support
46 # are always compiled but return NULL if the hardware
47 # support isn't compiled.
48 # no-hw do not compile support for any crypto hardware.
49 # [no-]threads [don't] try to create a library that is suitable for
50 # multithreaded applications (default is "threads" if we
52 # [no-]shared [don't] try to create shared libraries when supported.
53 # [no-]pic [don't] try to build position independent code when supported.
54 # If disabled, it also disables shared and dynamic-engine.
55 # no-asm do not use assembler
56 # no-dso do not compile in any native shared-library methods. This
57 # will ensure that all methods just return NULL.
58 # no-egd do not compile support for the entropy-gathering daemon APIs
59 # [no-]zlib [don't] compile support for zlib compression.
60 # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
61 # library and will be loaded in run-time by the OpenSSL library.
62 # sctp include SCTP support
63 # 386 generate 80386 code
64 # enable-weak-ssl-ciphers
65 # Enable weak ciphers that are disabled by default. This currently
66 # only includes RC4 based ciphers.
67 # no-sse2 disables IA-32 SSE2 code, above option implies no-sse2
68 # no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
69 # -<xxx> +<xxx> compiler options are passed through
70 # -static while -static is also a pass-through compiler option (and
71 # as such is limited to environments where it's actually
72 # meaningful), it triggers a number configuration options,
73 # namely no-dso, no-pic, no-shared and no-threads. It is
74 # argued that the only reason to produce statically linked
75 # binaries (and in context it means executables linked with
76 # -static flag, and not just executables linked with static
77 # libcrypto.a) is to eliminate dependency on specific run-time,
78 # a.k.a. libc version. The mentioned config options are meant
79 # to achieve just that. Unfortunately on Linux it's impossible
80 # to eliminate the dependency completely for openssl executable
81 # because of getaddrinfo and gethostbyname calls, which can
82 # invoke dynamically loadable library facility anyway to meet
83 # the lookup requests. For this reason on Linux statically
84 # linked openssl executable has rather debugging value than
87 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
88 # provided to stack calls. Generates unique stack functions for
89 # each possible stack type.
90 # BN_LLONG use the type 'long long' in crypto/bn/bn.h
91 # RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
92 # Following are set automatically by this script
94 # MD5_ASM use some extra md5 assembler,
95 # SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86
96 # RMD160_ASM use some extra ripemd160 assembler,
97 # SHA256_ASM sha256_block is implemented in assembler
98 # SHA512_ASM sha512_block is implemented in assembler
99 # AES_ASM AES_[en|de]crypt is implemented in assembler
101 # Minimum warning options... any contributions to OpenSSL should at least get
104 # DEBUG_UNUSED enables __owur (warn unused result) checks.
105 my $gcc_devteam_warn = "-DDEBUG_UNUSED"
106 # -DPEDANTIC complements -pedantic and is meant to mask code that
107 # is not strictly standard-compliant and/or implementation-specific,
108 # e.g. inline assembly, disregards to alignment requirements, such
109 # that -pedantic would complain about. Incidentally -DPEDANTIC has
110 # to be used even in sanitized builds, because sanitizer too is
111 # supposed to and does take notice of non-standard behaviour. Then
112 # -pedantic with pre-C9x compiler would also complain about 'long
113 # long' not being supported. As 64-bit algorithms are common now,
114 # it grew impossible to resolve this without sizeable additional
115 # code, so we just tell compiler to be pedantic about everything
116 # but 'long long' type.
118 . " -DPEDANTIC -pedantic -Wno-long-long"
121 . " -Wmissing-prototypes"
128 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
129 # TODO(openssl-team): fix problems and investigate if (at least) the
130 # following warnings can also be enabled:
133 # -Wlanguage-extension-token -- no, we use asm()
134 # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
135 # -Wextended-offsetof -- no, needed in CMS ASN1 code
136 my $clang_devteam_warn = ""
137 . " -Qunused-arguments"
139 . " -Wswitch -Wswitch-default"
140 . " -Wno-unused-parameter"
141 . " -Wno-missing-field-initializers"
142 . " -Wno-language-extension-token"
143 . " -Wno-extended-offsetof"
144 . " -Wconditional-uninitialized"
145 . " -Wincompatible-pointer-types-discards-qualifiers"
146 . " -Wmissing-variable-declarations"
149 # This adds backtrace information to the memory leak info. Is only used
150 # when crypto-mdebug-backtrace is enabled.
151 my $memleak_devteam_backtrace = "-rdynamic";
153 my $strict_warnings = 0;
155 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
156 # which would cover all BSD flavors. -pthread applies to them all,
157 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
158 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
159 # which has to be accompanied by explicit -D_THREAD_SAFE and
160 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
161 # seems to be sufficient?
162 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
165 # API compatibility name to version number mapping.
167 my $maxapi = "1.1.0"; # API for "no-deprecated" builds
169 "1.1.0" => "0x10100000L",
170 "1.0.0" => "0x10000000L",
171 "0.9.8" => "0x00908000L",
178 # Forward declarations ###############################################
180 # read_config(filename)
182 # Reads a configuration file and populates %table with the contents
183 # (which the configuration file places in %targets).
186 # resolve_config(target)
188 # Resolves all the late evaluations, inheritances and so on for the
189 # chosen target and any target it inherits from.
193 # Information collection #############################################
195 # Unified build supports separate build dir
196 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
197 my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
198 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
200 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
202 $config{sourcedir} = abs2rel($srcdir);
203 $config{builddir} = abs2rel($blddir);
205 # Collect reconfiguration information if needed
208 if (grep /^reconf(igure)?$/, @argvcopy) {
209 if (-f "./configdata.pm") {
210 my $file = "./configdata.pm";
211 unless (my $return = do $file) {
212 die "couldn't parse $file: $@" if $@;
213 die "couldn't do $file: $!" unless defined $return;
214 die "couldn't run $file" unless $return;
217 @argvcopy = defined($configdata::config{perlargv}) ?
218 @{$configdata::config{perlargv}} : ();
219 die "Incorrect data to reconfigure, please do a normal configuration\n"
220 if (grep(/^reconf/,@argvcopy));
221 $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
222 if defined($configdata::config{cross_compile_prefix});
223 $ENV{CC} = $configdata::config{cc}
224 if defined($configdata::config{cc});
225 $ENV{BUILDFILE} = $configdata::config{build_file}
226 if defined($configdata::config{build_file});
227 $ENV{$local_config_envname} = $configdata::config{local_config_dir}
228 if defined($configdata::config{local_config_dir});
230 print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
231 print " CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
232 if $ENV{CROSS_COMPILE};
233 print " CC = ",$ENV{CC},"\n" if $ENV{CC};
234 print " BUILDFILE = ",$ENV{BUILDFILE},"\n" if $ENV{BUILDFILE};
235 print " $local_config_envname = ",$ENV{$local_config_envname},"\n"
236 if $ENV{$local_config_envname};
238 die "Insufficient data to reconfigure, please do a normal configuration\n";
242 $config{perlargv} = [ @argvcopy ];
244 # Collect version numbers
245 $config{version} = "unknown";
246 $config{version_num} = "unknown";
247 $config{shlib_version_number} = "unknown";
248 $config{shlib_version_history} = "unknown";
251 collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
252 qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
253 qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 },
254 qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 },
255 qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 }
257 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
259 ($config{major}, $config{minor})
260 = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
261 ($config{shlib_major}, $config{shlib_minor})
262 = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
263 die "erroneous version information in opensslv.h: ",
264 "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
265 if ($config{major} eq "" || $config{minor} eq ""
266 || $config{shlib_major} eq "" || $config{shlib_minor} eq "");
268 # Collect target configurations
270 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
271 foreach (sort glob($pattern)) {
275 if (defined $ENV{$local_config_envname}) {
277 # VMS environment variables are logical names,
278 # which can be used as is
279 $pattern = $local_config_envname . ':' . '*.conf';
281 $pattern = catfile($ENV{$local_config_envname}, '*.conf');
284 foreach (sort glob($pattern)) {
290 print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n";
293 $config{openssldir}="";
294 $config{processor}="";
296 $config{cross_compile_prefix}="";
297 $config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
298 my $nofipscanistercheck=0;
299 $config{baseaddr}="0xFB00000";
300 my $auto_threads=1; # enable threads automatically? true by default
304 # Top level directories to build
305 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ];
306 # crypto/ subdirectories to build
309 "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2",
310 "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes",
311 "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
312 "buffer", "bio", "stack", "lhash", "rand", "err",
313 "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
314 "cms", "ts", "srp", "cmac", "ct", "async", "kdf"
317 # Known TLS and DTLS protocols
318 my @tls = qw(ssl3 tls1 tls1_1 tls1_2);
319 my @dtls = qw(dtls1 dtls1_2);
321 # Explicitly known options that are possible to disable. They can
322 # be regexps, and will be used like this: /^no-${option}$/
323 # For developers: keep it sorted alphabetically
342 "crypto-mdebug-backtrace",
356 "ec_nistp_64_gcc_128",
409 foreach my $proto ((@tls, @dtls))
411 push(@disablables, $proto);
412 push(@disablables, "$proto-method");
415 my %deprecated_disablables = (
417 "buf-freelists" => undef,
421 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
423 our %disabled = ( # "what" => "comment"
425 "crypto-mdebug" => "default",
426 "crypto-mdebug-backtrace" => "default",
427 "ec_nistp_64_gcc_128" => "default",
429 "fuzz-libfuzzer" => "default",
430 "fuzz-afl" => "default",
431 "heartbeats" => "default",
436 "ssl-trace" => "default",
438 "ssl3-method" => "default",
439 "ubsan" => "default",
440 "unit-test" => "default",
441 "weak-ssl-ciphers" => "default",
443 "zlib-dynamic" => "default",
446 # Note: => pair form used for aesthetics, not to truly make a hash table
447 my @disable_cascades = (
448 # "what" => [ "cascade", ... ]
449 sub { $config{processor} eq "386" }
452 "ssl3-method" => [ "ssl3" ],
453 "zlib" => [ "zlib-dynamic" ],
455 "ec" => [ "ecdsa", "ecdh" ],
457 "dgram" => [ "dtls", "sctp" ],
458 "sock" => [ "dgram" ],
461 # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
462 "md5" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
463 "sha" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
465 # Additionally, SSL 3.0 requires either RSA or DSA+DH
467 && ($disabled{dsa} || $disabled{dh}); }
470 # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
471 # or ECDSA + ECDH. (D)TLS 1.2 has this requirement as well.
472 # (XXX: We don't support PSK-only builds).
474 && ($disabled{dsa} || $disabled{dh})
475 && ($disabled{ecdsa} || $disabled{ecdh}); }
476 => [ "tls1", "tls1_1", "tls1_2",
477 "dtls1", "dtls1_2" ],
481 # SRP and HEARTBEATS require TLSEXT
482 "tlsext" => [ "srp", "heartbeats" ],
484 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
486 # Without DSO, we can't load dynamic engines, so don't build them dynamic
487 "dso" => [ "dynamic-engine" ],
489 # Without position independent code, there can be no shared libraries or DSOs
490 "pic" => [ "shared" ],
491 "shared" => [ "dynamic-engine" ],
492 "engine" => [ "afalgeng" ],
494 # no-autoalginit is only useful when building non-shared
495 "autoalginit" => [ "shared", "apps" ],
497 "stdio" => [ "apps", "capieng" ],
498 "apps" => [ "tests" ],
499 "comp" => [ "zlib" ],
500 sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
502 sub { !$disabled{"msan"} } => [ "asm" ],
505 # Avoid protocol support holes. Also disable all versions below N, if version
506 # N is disabled while N+1 is enabled.
508 my @list = (reverse @tls);
509 while ((my $first, my $second) = (shift @list, shift @list)) {
511 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
513 unshift @list, $second;
515 my @list = (reverse @dtls);
516 while ((my $first, my $second) = (shift @list, shift @list)) {
518 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
520 unshift @list, $second;
523 # Explicit "no-..." options will be collected in %disabled along with the defaults.
524 # To remove something from %disabled, use "enable-foo".
525 # For symmetry, "disable-foo" is a synonym for "no-foo".
529 &usage if ($#ARGV < 0);
533 $config{openssl_api_defines}=[];
534 $config{openssl_algorithm_defines}=[];
535 $config{openssl_thread_defines}=[];
536 $config{openssl_sys_defines}=[];
537 $config{openssl_other_defines}=[];
541 $config{build_type} = "release";
543 my %unsupported_options = ();
544 my %deprecated_options = ();
547 # VMS is a case insensitive environment, and depending on settings
548 # out of our control, we may receive options uppercased. Let's
549 # downcase at least the part before any equal sign.
554 s /^-no-/no-/; # some people just can't read the instructions
556 # rewrite some options in "enable-..." form
557 s /^-?-?shared$/enable-shared/;
558 s /^sctp$/enable-sctp/;
559 s /^threads$/enable-threads/;
560 s /^zlib$/enable-zlib/;
561 s /^zlib-dynamic$/enable-zlib-dynamic/;
563 if (/^(no|disable|enable)-(.+)$/)
566 if (!exists $deprecated_disablables{$word}
567 && !grep { $word =~ /^${_}$/ } @disablables)
569 $unsupported_options{$_} = 1;
573 if (/^no-(.+)$/ || /^disable-(.+)$/)
575 foreach my $proto ((@tls, @dtls))
577 if ($1 eq "$proto-method")
579 $disabled{"$proto"} = "option($proto-method)";
585 foreach my $proto (@dtls)
587 $disabled{$proto} = "option(dtls)";
589 $disabled{"dtls"} = "option(dtls)";
593 # Last one of its kind
594 $disabled{"ssl3"} = "option(ssl)";
598 # XXX: Tests will fail if all SSL/TLS
599 # protocols are disabled.
600 foreach my $proto (@tls)
602 $disabled{$proto} = "option(tls)";
605 elsif ($1 eq "static-engine")
607 delete $disabled{"dynamic-engine"};
609 elsif ($1 eq "dynamic-engine")
611 $disabled{"dynamic-engine"} = "option";
613 elsif (exists $deprecated_disablables{$1})
615 $deprecated_options{$_} = 1;
616 if (defined $deprecated_disablables{$1})
618 $disabled{$deprecated_disablables{$1}} = "option";
623 $disabled{$1} = "option";
625 # No longer an automatic choice
626 $auto_threads = 0 if ($1 eq "threads");
628 elsif (/^enable-(.+)$/)
630 if ($1 eq "static-engine")
632 $disabled{"dynamic-engine"} = "option";
634 elsif ($1 eq "dynamic-engine")
636 delete $disabled{"dynamic-engine"};
638 elsif ($1 eq "zlib-dynamic")
640 delete $disabled{"zlib"};
643 delete $disabled{$algo};
645 # No longer an automatic choice
646 $auto_threads = 0 if ($1 eq "threads");
648 elsif (/^--strict-warnings$/)
650 $strict_warnings = 1;
654 $config{build_type} = "debug";
656 elsif (/^--release$/)
658 $config{build_type} = "release";
661 { $config{processor}=386; }
668 # No RSAref support any more since it's not needed.
669 # The check for the option is there so scripts aren't
672 elsif (/^nofipscanistercheck$/)
675 $nofipscanistercheck = 1;
679 if (/^--prefix=(.*)$/)
682 die "Directory given with --prefix MUST be absolute\n"
683 unless file_name_is_absolute($config{prefix});
685 elsif (/^--api=(.*)$/)
689 elsif (/^--libdir=(.*)$/)
693 elsif (/^--openssldir=(.*)$/)
695 $config{openssldir}=$1;
697 elsif (/^--with-zlib-lib=(.*)$/)
699 $withargs{zlib_lib}=$1;
701 elsif (/^--with-zlib-include=(.*)$/)
703 $withargs{zlib_include}=$1;
705 elsif (/^--with-fuzzer-lib=(.*)$/)
707 $withargs{fuzzer_lib}=$1;
709 elsif (/^--with-fuzzer-include=(.*)$/)
711 $withargs{fuzzer_include}=$1;
713 elsif (/^--with-fipslibdir=(.*)$/)
715 $config{fipslibdir}="$1/";
717 elsif (/^--with-baseaddr=(.*)$/)
719 $config{baseaddr}="$1";
721 elsif (/^--cross-compile-prefix=(.*)$/)
723 $config{cross_compile_prefix}=$1;
725 elsif (/^--config=(.*)$/)
729 elsif (/^-[lL](.*)$/ or /^-Wl,/)
736 $disabled{"dso"} = "forced";
737 $disabled{"pic"} = "forced";
738 $disabled{"shared"} = "forced";
739 $disabled{"threads"} = "forced";
743 push @user_defines, $1;
745 else # common if (/^[-+]/), just pass down...
747 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
748 $user_cflags.=" ".$_;
753 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
756 unless ($_ eq $target || /^no-/ || /^disable-/)
758 # "no-..." follows later after implied disactivations
759 # have been derived. (Don't take this too seriously,
760 # we really only write OPTIONS to the Makefile out of
763 if ($config{options} eq "")
764 { $config{options} = $_; }
766 { $config{options} .= " ".$_; }
769 if (defined($config{api}) && !exists $apitable->{$config{api}}) {
770 die "***** Unsupported api compatibility level: $config{api}\n",
773 if (keys %deprecated_options)
775 warn "***** Deprecated options: ",
776 join(", ", keys %deprecated_options), "\n";
778 if (keys %unsupported_options)
780 die "***** Unsupported options: ",
781 join(", ", keys %unsupported_options), "\n";
785 if ($libs =~ /(^|\s)-Wl,-rpath,/
786 && !$disabled{shared}
787 && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) {
788 die "***** Cannot simultaneously use -rpath, shared libraries, and\n",
789 "***** any of asan, msan or ubsan\n";
794 delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/);
798 @{$config{dirs}} = grep !/^fips$/, @{$config{dirs}};
801 my @tocheckfor = (keys %disabled);
802 while (@tocheckfor) {
803 my %new_tocheckfor = ();
804 my @cascade_copy = (@disable_cascades);
805 while (@cascade_copy) {
806 my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
807 if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
808 foreach(grep { !defined($disabled{$_}) } @$descendents) {
809 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
813 @tocheckfor = (keys %new_tocheckfor);
816 our $die = sub { die @_; };
817 if ($target eq "TABLE") {
818 local $die = sub { warn @_; };
819 foreach (sort keys %table) {
820 print_table_entry($_, "TABLE");
825 if ($target eq "LIST") {
826 foreach (sort keys %table) {
827 print $_,"\n" unless $table{$_}->{template};
832 if ($target eq "HASH") {
833 local $die = sub { warn @_; };
834 print "%table = (\n";
835 foreach (sort keys %table) {
836 print_table_entry($_, "HASH");
841 # Backward compatibility?
842 if ($target =~ m/^CygWin32(-.*)$/) {
843 $target = "Cygwin".$1;
846 foreach (sort (keys %disabled))
848 $config{options} .= " no-$_";
850 printf " no-%-12s %-10s", $_, "[$disabled{$_}]";
862 elsif (/^dynamic-engine$/)
864 elsif (/^makedepend$/)
866 elsif (/^zlib-dynamic$/)
872 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
873 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
874 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
875 print " OPENSSL_NO_ENGINE (skip engines)";
881 ($WHAT = $what = $_) =~ tr/[\-a-z]/[_A-Z]/;
883 # Fix up C macro end names
884 $WHAT = "RMD160" if $what eq "ripemd";
886 # fix-up crypto/directory name(s)
887 $what = "ripemd" if $what eq "rmd160";
888 $what = "whrlpool" if $what eq "whirlpool";
890 if ($what ne "async" && $what ne "err"
891 && grep { $_ eq $what } @{$config{sdirs}})
893 push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$WHAT";
894 @{$config{sdirs}} = grep { $_ ne $what} @{$config{sdirs}};
896 print " OPENSSL_NO_$WHAT (skip dir)";
900 push @{$config{openssl_other_defines}}, "OPENSSL_NO_$WHAT";
901 print " OPENSSL_NO_$WHAT";
903 if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; }
910 print "Configuring for $target\n";
911 # Support for legacy targets having a name starting with 'debug-'
912 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
914 $config{build_type} = "debug";
916 # If we do not find debug-foo in the table, the target is set to foo.
917 if (!$table{$target}) {
921 $config{target} = $target;
922 my %target = resolve_config($target);
924 &usage if (!%target || $target{template});
926 my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}});
927 $config{conf_files} = [ sort keys %conf_files ];
928 %target = ( %{$table{DEFAULTS}}, %target );
930 $target{exe_extension}="";
931 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
932 || $config{target} =~ /^(?:Cygwin|mingw)/);
933 $target{exe_extension}=".pm" if ($config{target} =~ /vos/);
935 ($target{shared_extension_simple}=$target{shared_extension})
936 =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||;
937 $target{dso_extension}=$target{shared_extension_simple};
938 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
939 if ($config{target} =~ /^(?:Cygwin|mingw)/);
942 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
943 if $config{cross_compile_prefix} eq "";
945 # Allow overriding the names of some tools. USE WITH CARE
946 # Note: only Unix cares about HASHBANGPERL... that explains
947 # the default string.
948 $config{perl} = ($^O ne "VMS" ? $^X : "perl");
949 $config{hashbangperl} =
950 $ENV{'HASHBANGPERL'} || $ENV{'PERL'} || "/usr/bin/env perl";
951 $target{cc} = $ENV{'CC'} || $target{cc} || "cc";
952 $target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} ||
953 (which("$config{cross_compile_prefix}ranlib") ?
954 "\$(CROSS_COMPILE)ranlib" : "true");
955 $target{ar} = $ENV{'AR'} || $target{ar} || "ar";
956 $target{nm} = $ENV{'NM'} || $target{nm} || "nm";
958 $ENV{'RC'} || $ENV{'WINDRES'} || $target{rc} || "windres";
960 # Allow overriding the build file name
961 $target{build_file} = $ENV{BUILDFILE} || $target{build_file} || "Makefile";
963 # Cache information necessary for reconfiguration
964 $config{cc} = $target{cc};
965 $config{build_file} = $target{build_file};
967 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
968 # or release_ attributes.
969 # Do it in such a way that no spurious space is appended (hence the grep).
970 $config{defines} = [];
971 $config{cflags} = "";
972 $config{ex_libs} = "";
973 $config{shared_ldflag} = "";
975 # Make sure build_scheme is consistent.
976 $target{build_scheme} = [ $target{build_scheme} ]
977 if ref($target{build_scheme}) ne "ARRAY";
979 my ($builder, $builder_platform, @builder_opts) =
980 @{$target{build_scheme}};
982 push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
984 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
986 $config{cflags} .= " -mno-cygwin";
987 $config{shared_ldflag} .= " -mno-cygwin";
990 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
991 # minimally required architecture flags for assembly modules
992 $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
993 $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
996 my $no_shared_warn=0;
997 my $no_user_cflags=0;
998 my $no_user_defines=0;
1000 # The DSO code currently always implements all functions so that no
1001 # applications will have to worry about that from a compilation point
1002 # of view. However, the "method"s may return zero unless that platform
1003 # has support compiled in for them. Currently each method is enabled
1004 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
1005 # string entry into using the following logic;
1006 if (!$disabled{dso} && $target{dso_scheme} ne "")
1008 $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
1009 if ($target{dso_scheme} eq "DLFCN")
1011 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
1013 elsif ($target{dso_scheme} eq "DLFCN_NO_H")
1015 unshift @{$config{defines}}, "DSO_DLFCN";
1019 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
1023 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
1029 @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}};
1030 @{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}};
1034 # If threads aren't disabled, check how possible they are
1035 unless ($disabled{threads}) {
1036 if ($auto_threads) {
1037 # Enabled by default, disable it forcibly if unavailable
1038 if ($target{thread_scheme} eq "(unknown)") {
1039 $disabled{threads} = "unavailable";
1042 # The user chose to enable threads explicitly, let's see
1043 # if there's a chance that's possible
1044 if ($target{thread_scheme} eq "(unknown)") {
1045 # If the user asked for "threads" and we don't have internal
1046 # knowledge how to do it, [s]he is expected to provide any
1047 # system-dependent compiler options that are necessary. We
1048 # can't truly check that the given options are correct, but
1049 # we expect the user to know what [s]He is doing.
1050 if ($no_user_cflags && $no_user_defines) {
1051 die "You asked for multi-threading support, but didn't\n"
1052 ,"provide any system-specific compiler options\n";
1058 # If threads still aren't disabled, add a C macro to ensure the source
1059 # code knows about it. Any other flag is taken care of by the configs.
1060 unless($disabled{threads}) {
1061 foreach (("defines", "openssl_thread_defines")) {
1062 push @{$config{$_}}, "OPENSSL_THREADS";
1066 # With "deprecated" disable all deprecated features.
1067 if (defined($disabled{"deprecated"})) {
1068 $config{api} = $maxapi;
1071 if ($target{shared_target} eq "")
1074 if ((!$disabled{shared} || !$disabled{"dynamic-engine"})
1076 $disabled{shared} = "no-shared-target";
1077 $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1081 if ($disabled{"dynamic-engine"}) {
1082 push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1083 $config{dynamic_engines} = 0;
1085 push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1086 $config{dynamic_engines} = 1;
1089 unless ($disabled{"fuzz-libfuzzer"}) {
1090 $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls ";
1093 unless ($disabled{asan}) {
1094 $config{cflags} .= "-fsanitize=address ";
1097 unless ($disabled{ubsan}) {
1098 # -DPEDANTIC or -fnosanitize=alignment may also be required on some
1100 $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
1103 unless ($disabled{msan}) {
1104 $config{cflags} .= "-fsanitize=memory ";
1107 unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"}
1108 && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) {
1109 $config{cflags} .= "-fno-omit-frame-pointer -g ";
1115 # This saves the build files from having to check
1118 $target{shared_cflag} = $target{shared_ldflag} =
1119 $target{shared_rcflag} = "";
1123 push @{$config{defines}}, "OPENSSL_PIC";
1126 if ($target{sys_id} ne "")
1128 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1131 unless ($disabled{asm}) {
1132 $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1133 $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1135 # bn-586 is the only one implementing bn_*_part_words
1136 push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1137 push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1139 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1140 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1141 push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1143 if ($config{fips}) {
1144 push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
1147 if ($target{sha1_asm_src}) {
1148 push @{$config{defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1149 push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1150 push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1152 if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) {
1153 push @{$config{defines}}, "RC4_ASM";
1155 if ($target{md5_asm_src}) {
1156 push @{$config{defines}}, "MD5_ASM";
1158 $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1159 if ($target{rmd160_asm_src}) {
1160 push @{$config{defines}}, "RMD160_ASM";
1162 if ($target{aes_asm_src}) {
1163 push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1164 # aes-ctr.fake is not a real file, only indication that assembler
1165 # module implements AES_ctr32_encrypt...
1166 push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1167 # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1168 push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1169 $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1170 push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1171 push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1173 if ($target{wp_asm_src} =~ /mmx/) {
1174 if ($config{processor} eq "386") {
1175 $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1176 } elsif (!$disabled{"whirlpool"}) {
1177 push @{$config{defines}}, "WHIRLPOOL_ASM";
1180 if ($target{modes_asm_src} =~ /ghash-/) {
1181 push @{$config{defines}}, "GHASH_ASM";
1183 if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1184 push @{$config{defines}}, "ECP_NISTZ256_ASM";
1186 if ($target{poly1305_asm_src} ne "") {
1187 push @{$config{defines}}, "POLY1305_ASM";
1191 my $ecc = $target{cc};
1192 if ($^O ne "VMS" && !$disabled{makedepend}) {
1193 # Is the compiler gcc or clang? $ecc is used below to see if
1194 # error-checking can be turned on.
1195 my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1196 open(PIPE, "$ccpcc --version 2>&1 |");
1199 # Find the version number and save the major.
1200 m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
1201 my $compiler_major = $1;
1202 # We know that GNU C version 3 and up as well as all clang
1203 # versions support dependency generation
1204 $config{makedepprog} = $ccpcc
1205 if (/clang/ || (/gcc/ && $compiler_major >= 3));
1206 $ecc = "clang" if /clang/;
1207 $ecc = "gcc" if /gcc/;
1208 last if ($config{makedepprog} || !$lines--);
1212 $config{makedepprog} = which('makedepend') unless $config{makedepprog};
1213 $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1218 # Deal with bn_ops ###################################################
1221 $config{export_var_as_fn} =0;
1222 my $def_int="unsigned int";
1223 $config{rc4_int} =$def_int;
1224 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1227 foreach (sort split(/\s+/,$target{bn_ops})) {
1228 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1229 $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN';
1230 $config{bn_ll}=1 if $_ eq 'BN_LLONG';
1231 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
1232 ($config{b64l},$config{b64},$config{b32})
1233 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
1234 ($config{b64l},$config{b64},$config{b32})
1235 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
1236 ($config{b64l},$config{b64},$config{b32})
1237 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
1239 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1243 # Hack cflags for better warnings (dev option) #######################
1245 # "Stringify" the C flags string. This permits it to be made part of a string
1246 # and works as well on command lines.
1247 $config{cflags} =~ s/([\\\"])/\\$1/g;
1249 if (defined($config{api})) {
1250 $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1251 my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1252 push @{$config{defines}}, $apiflag;
1255 if ($strict_warnings)
1258 die "ERROR --strict-warnings requires gcc or clang"
1259 unless $ecc eq 'gcc' || $ecc eq 'clang';
1260 foreach $wopt (split /\s+/, $gcc_devteam_warn)
1262 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1264 if ($ecc eq "clang")
1266 foreach $wopt (split /\s+/, $clang_devteam_warn)
1268 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1273 unless ($disabled{"crypto-mdebug-backtrace"})
1275 foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1277 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1279 if ($target =~ /^BSD-/)
1281 $config{ex_libs} .= " -lexecinfo";
1285 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; }
1286 else { $no_user_cflags=1; }
1287 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1288 else { $no_user_defines=1; }
1290 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1292 unless ($disabled{afalgeng}) {
1293 $config{afalgeng}="";
1294 if ($target =~ m/^linux/) {
1295 my $minver = 4*10000 + 1*100 + 0;
1296 if ($config{cross_compile_prefix} eq "") {
1297 my $verstr = `uname -r`;
1298 my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1299 ($mi2) = $mi2 =~ /(\d+)/;
1300 my $ver = $ma*10000 + $mi1*100 + $mi2;
1301 if ($ver < $minver) {
1302 $disabled{afalgeng} = "too-old-kernel";
1304 push @{$config{engdirs}}, "afalg";
1307 $disabled{afalgeng} = "cross-compiling";
1310 $disabled{afalgeng} = "not-linux";
1314 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1316 # If we use the unified build, collect information from build.info files
1317 my %unified_info = ();
1319 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1320 if ($builder eq "unified") {
1321 use lib catdir(dirname(__FILE__),"util");
1322 use with_fallback qw(Text::Template);
1327 my $relativeto = shift || ".";
1329 $dir = catdir($base,$dir) unless isabsolute($dir);
1331 # Make sure the directories we're building in exists
1334 my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1335 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1342 my $relativeto = shift || ".";
1344 $file = catfile($base,$file) unless isabsolute($file);
1346 my $d = dirname($file);
1347 my $f = basename($file);
1349 # Make sure the directories we're building in exists
1352 my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1353 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1357 # Store the name of the template file we will build the build file from
1358 # in %config. This may be useful for the build file itself.
1359 my @build_file_template_names =
1360 ( $builder_platform."-".$target{build_file}.".tmpl",
1361 $target{build_file}.".tmpl" );
1362 my @build_file_templates = ();
1364 # First, look in the user provided directory, if given
1365 if (defined $ENV{$local_config_envname}) {
1366 @build_file_templates =
1369 # VMS environment variables are logical names,
1370 # which can be used as is
1371 $local_config_envname . ':' . $_;
1373 catfile($ENV{$local_config_envname}, $_);
1376 @build_file_template_names;
1378 # Then, look in our standard directory
1379 push @build_file_templates,
1380 ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) }
1381 @build_file_template_names );
1383 my $build_file_template;
1384 for $_ (@build_file_templates) {
1385 $build_file_template = $_;
1386 last if -f $build_file_template;
1388 $build_file_template = undef;
1390 if (!defined $build_file_template) {
1391 die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n";
1393 $config{build_file_templates}
1394 = [ $build_file_template,
1395 cleanfile($srcdir, catfile("Configurations", "common.tmpl"),
1398 my @build_infos = ( [ ".", "build.info" ] );
1399 foreach (@{$config{dirs}}) {
1400 push @build_infos, [ $_, "build.info" ]
1401 if (-f catfile($srcdir, $_, "build.info"));
1403 foreach (@{$config{sdirs}}) {
1404 push @build_infos, [ catdir("crypto", $_), "build.info" ]
1405 if (-f catfile($srcdir, "crypto", $_, "build.info"));
1407 foreach (@{$config{engdirs}}) {
1408 push @build_infos, [ catdir("engines", $_), "build.info" ]
1409 if (-f catfile($srcdir, "engines", $_, "build.info"));
1412 $config{build_infos} = [ ];
1414 foreach (@build_infos) {
1415 my $sourced = catdir($srcdir, $_->[0]);
1416 my $buildd = catdir($blddir, $_->[0]);
1421 # The basic things we're trying to build
1423 my @programs_install = ();
1425 my @libraries_install = ();
1427 my @engines_install = ();
1429 my @scripts_install = ();
1432 my @intermediates = ();
1437 my %shared_sources = ();
1441 my %sharednames = ();
1444 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1445 my $template = Text::Template->new(TYPE => 'FILE',
1446 SOURCE => catfile($sourced, $f));
1447 die "Something went wrong with $sourced/$f: $!\n" unless $template;
1450 $template->fill_in(HASH => { config => \%config,
1452 disabled => \%disabled,
1453 withargs => \%withargs,
1454 builddir => abs2rel($buildd, $blddir),
1455 sourcedir => abs2rel($sourced, $blddir),
1456 buildtop => abs2rel($blddir, $blddir),
1457 sourcetop => abs2rel($srcdir, $blddir) },
1458 DELIMITERS => [ "{-", "-}" ]);
1460 # The top item of this stack has the following values
1461 # -2 positive already run and we found ELSE (following ELSIF should fail)
1462 # -1 positive already run (skip until ENDIF)
1463 # 0 negatives so far (if we're at a condition, check it)
1464 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1465 # 2 positive ELSE (following ELSIF should fail)
1467 collect_information(
1468 collect_from_array([ @text ],
1469 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1470 $l1 =~ s/\\$//; $l1.$l2 }),
1471 # Info we're looking for
1472 qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1474 if (! @skip || $skip[$#skip] > 0) {
1480 qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1481 => sub { die "ELSIF out of scope" if ! @skip;
1482 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1483 $skip[$#skip] = -1 if $skip[$#skip] != 0;
1484 $skip[$#skip] = !! $1
1485 if $skip[$#skip] == 0; },
1487 => sub { die "ELSE out of scope" if ! @skip;
1488 $skip[$#skip] = -2 if $skip[$#skip] != 0;
1489 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1491 => sub { die "ENDIF out of scope" if ! @skip;
1493 qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/
1495 if (!@skip || $skip[$#skip] > 0) {
1497 my @x = tokenize($2);
1499 push @programs_install, @x unless $install;
1502 qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/
1504 if (!@skip || $skip[$#skip] > 0) {
1506 my @x = tokenize($2);
1507 push @libraries, @x;
1508 push @libraries_install, @x unless $install;
1511 qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/
1513 if (!@skip || $skip[$#skip] > 0) {
1515 my @x = tokenize($2);
1517 push @engines_install, @x unless $install;
1520 qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/
1522 if (!@skip || $skip[$#skip] > 0) {
1524 my @x = tokenize($2);
1526 push @scripts_install, @x unless $install;
1529 qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1530 => sub { push @extra, tokenize($1)
1531 if !@skip || $skip[$#skip] > 0 },
1532 qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1533 => sub { push @overrides, tokenize($1)
1534 if !@skip || $skip[$#skip] > 0 },
1536 qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1537 => sub { push @{$ordinals{$1}}, tokenize($2)
1538 if !@skip || $skip[$#skip] > 0 },
1539 qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1540 => sub { push @{$sources{$1}}, tokenize($2)
1541 if !@skip || $skip[$#skip] > 0 },
1542 qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1543 => sub { push @{$shared_sources{$1}}, tokenize($2)
1544 if !@skip || $skip[$#skip] > 0 },
1545 qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1546 => sub { push @{$includes{$1}}, tokenize($2)
1547 if !@skip || $skip[$#skip] > 0 },
1548 qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
1549 => sub { push @{$depends{$1}}, tokenize($2)
1550 if !@skip || $skip[$#skip] > 0 },
1551 qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1552 => sub { push @{$generate{$1}}, $2
1553 if !@skip || $skip[$#skip] > 0 },
1554 qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1555 => sub { push @{$renames{$1}}, tokenize($2)
1556 if !@skip || $skip[$#skip] > 0 },
1557 qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1558 => sub { push @{$sharednames{$1}}, tokenize($2)
1559 if !@skip || $skip[$#skip] > 0 },
1560 qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1562 my $lineiterator = shift;
1563 my $target_kind = $1;
1564 while (defined $lineiterator->()) {
1566 if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1567 die "ENDRAW doesn't match BEGINRAW"
1568 if $1 ne $target_kind;
1571 next if @skip && $skip[$#skip] <= 0;
1573 if ($target_kind eq $target{build_file}
1574 || $target_kind eq $target{build_file}."(".$builder_platform.")");
1577 qr/^(?:#.*|\s*)$/ => sub { },
1578 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1580 if ($buildinfo_debug) {
1581 print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1582 print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1586 if ($buildinfo_debug) {
1587 print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1591 die "runaway IF?" if (@skip);
1593 foreach (keys %renames) {
1594 die "$_ renamed to more than one thing: "
1595 ,join(" ", @{$renames{$_}}),"\n"
1596 if scalar @{$renames{$_}} > 1;
1597 my $dest = cleanfile($buildd, $_, $blddir);
1598 my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1599 die "$dest renamed to more than one thing: "
1600 ,$unified_info{rename}->{$dest}, $to
1601 unless !defined($unified_info{rename}->{$dest})
1602 or $unified_info{rename}->{$dest} eq $to;
1603 $unified_info{rename}->{$dest} = $to;
1606 foreach (@programs) {
1607 my $program = cleanfile($buildd, $_, $blddir);
1608 if ($unified_info{rename}->{$program}) {
1609 $program = $unified_info{rename}->{$program};
1611 $unified_info{programs}->{$program} = 1;
1614 foreach (@programs_install) {
1615 my $program = cleanfile($buildd, $_, $blddir);
1616 if ($unified_info{rename}->{$program}) {
1617 $program = $unified_info{rename}->{$program};
1619 $unified_info{install}->{programs}->{$program} = 1;
1622 foreach (@libraries) {
1623 my $library = cleanfile($buildd, $_, $blddir);
1624 if ($unified_info{rename}->{$library}) {
1625 $library = $unified_info{rename}->{$library};
1627 $unified_info{libraries}->{$library} = 1;
1630 foreach (@libraries_install) {
1631 my $library = cleanfile($buildd, $_, $blddir);
1632 if ($unified_info{rename}->{$library}) {
1633 $library = $unified_info{rename}->{$library};
1635 $unified_info{install}->{libraries}->{$library} = 1;
1638 die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1639 ENGINES can only be used if configured with 'dynamic-engine'.
1640 This is usually a fault in a build.info file.
1642 foreach (@engines) {
1643 my $library = cleanfile($buildd, $_, $blddir);
1644 if ($unified_info{rename}->{$library}) {
1645 $library = $unified_info{rename}->{$library};
1647 $unified_info{engines}->{$library} = 1;
1650 foreach (@engines_install) {
1651 my $library = cleanfile($buildd, $_, $blddir);
1652 if ($unified_info{rename}->{$library}) {
1653 $library = $unified_info{rename}->{$library};
1655 $unified_info{install}->{engines}->{$library} = 1;
1658 foreach (@scripts) {
1659 my $script = cleanfile($buildd, $_, $blddir);
1660 if ($unified_info{rename}->{$script}) {
1661 $script = $unified_info{rename}->{$script};
1663 $unified_info{scripts}->{$script} = 1;
1666 foreach (@scripts_install) {
1667 my $script = cleanfile($buildd, $_, $blddir);
1668 if ($unified_info{rename}->{$script}) {
1669 $script = $unified_info{rename}->{$script};
1671 $unified_info{install}->{scripts}->{$script} = 1;
1675 my $extra = cleanfile($buildd, $_, $blddir);
1676 $unified_info{extra}->{$extra} = 1;
1679 foreach (@overrides) {
1680 my $override = cleanfile($buildd, $_, $blddir);
1681 $unified_info{overrides}->{$override} = 1;
1684 push @{$unified_info{rawlines}}, @rawlines;
1686 unless ($disabled{shared}) {
1687 # Check sharednames.
1688 foreach (keys %sharednames) {
1689 my $dest = cleanfile($buildd, $_, $blddir);
1690 if ($unified_info{rename}->{$dest}) {
1691 $dest = $unified_info{rename}->{$dest};
1693 die "shared_name for $dest with multiple values: "
1694 ,join(" ", @{$sharednames{$_}}),"\n"
1695 if scalar @{$sharednames{$_}} > 1;
1696 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1697 die "shared_name found for a library $dest that isn't defined\n"
1698 unless $unified_info{libraries}->{$dest};
1699 die "shared_name for $dest with multiple values: "
1700 ,$unified_info{sharednames}->{$dest}, ", ", $to
1701 unless !defined($unified_info{sharednames}->{$dest})
1702 or $unified_info{sharednames}->{$dest} eq $to;
1703 $unified_info{sharednames}->{$dest} = $to;
1706 # Additionally, we set up sharednames for libraries that don't
1707 # have any, as themselves.
1708 foreach (keys %{$unified_info{libraries}}) {
1709 if (!defined $unified_info{sharednames}->{$_}) {
1710 $unified_info{sharednames}->{$_} = $_
1715 foreach (keys %ordinals) {
1717 my $ddest = cleanfile($buildd, $_, $blddir);
1718 if ($unified_info{rename}->{$ddest}) {
1719 $ddest = $unified_info{rename}->{$ddest};
1721 foreach (@{$ordinals{$dest}}) {
1722 my %known_ordinals =
1725 cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1727 cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1729 my $o = $known_ordinals{$_};
1730 die "Ordinals for $ddest defined more than once\n"
1731 if $unified_info{ordinals}->{$ddest};
1732 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1736 foreach (keys %sources) {
1738 my $ddest = cleanfile($buildd, $_, $blddir);
1739 if ($unified_info{rename}->{$ddest}) {
1740 $ddest = $unified_info{rename}->{$ddest};
1742 foreach (@{$sources{$dest}}) {
1743 my $s = cleanfile($sourced, $_, $blddir);
1745 # If it isn't in the source tree, we assume it's generated
1748 $s = cleanfile($buildd, $_, $blddir);
1750 # We recognise C and asm files
1751 if ($s =~ /\.[csS]\b$/) {
1752 (my $o = $_) =~ s/\.[csS]\b$/.o/;
1753 $o = cleanfile($buildd, $o, $blddir);
1754 $unified_info{sources}->{$ddest}->{$o} = 1;
1755 $unified_info{sources}->{$o}->{$s} = 1;
1757 $unified_info{sources}->{$ddest}->{$s} = 1;
1762 foreach (keys %shared_sources) {
1764 my $ddest = cleanfile($buildd, $_, $blddir);
1765 if ($unified_info{rename}->{$ddest}) {
1766 $ddest = $unified_info{rename}->{$ddest};
1768 foreach (@{$shared_sources{$dest}}) {
1769 my $s = cleanfile($sourced, $_, $blddir);
1771 # If it isn't in the source tree, we assume it's generated
1774 $s = cleanfile($buildd, $_, $blddir);
1776 # We recognise C and asm files
1777 if ($s =~ /\.[csS]\b$/) {
1778 (my $o = $_) =~ s/\.[csS]\b$/.o/;
1779 $o = cleanfile($buildd, $o, $blddir);
1780 $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1781 $unified_info{sources}->{$o}->{$s} = 1;
1783 die "unrecognised source file type for shared library: $s\n";
1788 foreach (keys %generate) {
1790 my $ddest = cleanfile($buildd, $_, $blddir);
1791 if ($unified_info{rename}->{$ddest}) {
1792 $ddest = $unified_info{rename}->{$ddest};
1794 die "more than one generator for $dest: "
1795 ,join(" ", @{$generate{$_}}),"\n"
1796 if scalar @{$generate{$_}} > 1;
1797 my @generator = split /\s+/, $generate{$dest}->[0];
1798 $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1799 $unified_info{generate}->{$ddest} = [ @generator ];
1802 foreach (keys %depends) {
1804 my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir);
1806 # If the destination doesn't exist in source, it can only be
1807 # a generated file in the build tree.
1808 if ($ddest ne "" && ! -f $ddest) {
1809 $ddest = cleanfile($buildd, $_, $blddir);
1810 if ($unified_info{rename}->{$ddest}) {
1811 $ddest = $unified_info{rename}->{$ddest};
1814 foreach (@{$depends{$dest}}) {
1815 my $d = cleanfile($sourced, $_, $blddir);
1817 # If we know it's generated, or assume it is because we can't
1818 # find it in the source tree, we set file we depend on to be
1819 # in the build tree rather than the source tree, and assume
1820 # and that there are lines to build it in a BEGINRAW..ENDRAW
1821 # section or in the Makefile template.
1823 || (grep { $d eq $_ }
1824 map { cleanfile($srcdir, $_, $blddir) }
1825 grep { /\.h$/ } keys %{$unified_info{generate}})) {
1826 $d = cleanfile($buildd, $_, $blddir);
1828 # Take note if the file to depend on is being renamed
1829 if ($unified_info{rename}->{$d}) {
1830 $d = $unified_info{rename}->{$d};
1832 $unified_info{depends}->{$ddest}->{$d} = 1;
1833 # If we depend on a header file or a perl module, let's make
1834 # sure it can get included
1835 if ($dest ne "" && $d =~ /\.(h|pm)$/) {
1836 my $i = dirname($d);
1837 push @{$unified_info{includes}->{$ddest}->{source}}, $i
1838 unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}->{source}};
1843 foreach (keys %includes) {
1845 my $ddest = cleanfile($sourced, $_, $blddir);
1847 # If the destination doesn't exist in source, it can only be
1848 # a generated file in the build tree.
1850 $ddest = cleanfile($buildd, $_, $blddir);
1851 if ($unified_info{rename}->{$ddest}) {
1852 $ddest = $unified_info{rename}->{$ddest};
1855 foreach (@{$includes{$dest}}) {
1856 my $is = cleandir($sourced, $_, $blddir);
1857 my $ib = cleandir($buildd, $_, $blddir);
1858 push @{$unified_info{includes}->{$ddest}->{source}}, $is
1859 unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}};
1860 push @{$unified_info{includes}->{$ddest}->{build}}, $ib
1861 unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}};
1866 ### Make unified_info a bit more efficient
1867 # One level structures
1868 foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1869 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1871 # Two level structures
1872 foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) {
1873 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1874 $unified_info{$l1}->{$l2} =
1875 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1879 foreach my $dest (sort keys %{$unified_info{includes}}) {
1880 if (defined($unified_info{includes}->{$dest}->{build})) {
1881 my @source_includes =
1882 ( @{$unified_info{includes}->{$dest}->{source}} );
1883 $unified_info{includes}->{$dest} =
1884 [ @{$unified_info{includes}->{$dest}->{build}} ];
1885 foreach my $inc (@source_includes) {
1886 push @{$unified_info{includes}->{$dest}}, $inc
1887 unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}};
1890 $unified_info{includes}->{$dest} =
1891 [ @{$unified_info{includes}->{$dest}->{source}} ];
1896 # For the schemes that need it, we provide the old *_obj configs
1897 # from the *_asm_obj ones
1898 foreach (grep /_(asm|aux)_src$/, keys %target) {
1900 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1901 ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1904 # Write down our configuration where it fits #########################
1906 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1914 #use vars qw(\@ISA \@EXPORT);
1915 our \@ISA = qw(Exporter);
1916 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
1919 print OUT "our %config = (\n";
1920 foreach (sort keys %config) {
1921 if (ref($config{$_}) eq "ARRAY") {
1922 print OUT " ", $_, " => [ ", join(", ",
1923 map { quotify("perl", $_) }
1924 @{$config{$_}}), " ],\n";
1926 print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1933 print OUT "our %target = (\n";
1934 foreach (sort keys %target) {
1935 if (ref($target{$_}) eq "ARRAY") {
1936 print OUT " ", $_, " => [ ", join(", ",
1937 map { quotify("perl", $_) }
1938 @{$target{$_}}), " ],\n";
1940 print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1947 print OUT "our \%available_protocols = (\n";
1948 print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1949 print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1954 print OUT "our \@disablables = (\n";
1955 foreach (@disablables) {
1956 print OUT " ", quotify("perl", $_), ",\n";
1962 print OUT "our \%disabled = (\n";
1963 foreach (sort keys %disabled) {
1964 print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1970 print OUT "our %withargs = (\n";
1971 foreach (sort keys %withargs) {
1972 if (ref($withargs{$_}) eq "ARRAY") {
1973 print OUT " ", $_, " => [ ", join(", ",
1974 map { quotify("perl", $_) }
1975 @{$withargs{$_}}), " ],\n";
1977 print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1984 if ($builder eq "unified") {
1989 if (ref $_ eq "ARRAY") {
1990 print OUT " "x$indent, "[\n";
1992 $recurse->($indent + 4, $_);
1994 print OUT " "x$indent, "],\n";
1995 } elsif (ref $_ eq "HASH") {
1997 print OUT " "x$indent, "{\n";
1998 foreach (sort keys %h) {
1999 if (ref $h{$_} eq "") {
2000 print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
2002 print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
2003 $recurse->($indent + 8, $h{$_});
2006 print OUT " "x$indent, "},\n";
2008 print OUT " "x$indent, quotify("perl", $_), ",\n";
2012 print OUT "our %unified_info = (\n";
2013 foreach (sort keys %unified_info) {
2014 if (ref $unified_info{$_} eq "") {
2015 print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
2017 print OUT " "x4, quotify("perl", $_), " =>\n";
2018 $recurse->(8, $unified_info{$_});
2030 print "PROCESSOR =$config{processor}\n" if $config{processor};
2031 print "PERL =$config{perl}\n";
2032 print "PERLVERSION =$Config{version} for $Config{archname}\n";
2033 print "HASHBANGPERL =$config{hashbangperl}\n";
2034 print "CC =$config{cross_compile_prefix}$target{cc}\n";
2035 print "CFLAG =$target{cflags} $config{cflags}\n";
2036 print "DEFINES =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
2037 #print "RANLIB =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
2038 # "$config{cross_compile_prefix}ranlib" :
2039 # "$target{ranlib}", "\n";
2040 print "EX_LIBS =$target{ex_libs} $config{ex_libs}\n";
2044 run_dofile(catfile($blddir, $target{build_file}),
2045 @{$config{build_file_templates}});
2049 $builders{$builder}->($builder_platform, @builder_opts);
2051 print <<"EOF" if ($disabled{threads} eq "unavailable");
2053 The library could not be configured for supporting multi-threaded
2054 applications as the compiler options required on this system are not known.
2055 See file INSTALL for details if you need multi-threading.
2058 print <<"EOF" if ($no_shared_warn);
2060 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
2061 platform, so we will pretend you gave the option 'no-pic', which also disables
2062 'shared' and 'dynamic-engine'. If you know how to implement shared libraries
2063 or position independent code, please let us know (but please first make sure
2064 you have tried with a current version of OpenSSL).
2067 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2069 WARNING: there are indications that another build was made in the source
2070 directory. This build may have picked up artifacts from that build, the
2071 safest course of action is to clean the source directory and redo this
2077 ######################################################################
2079 # Helpers and utility functions
2082 # Configuration file reading #########################################
2084 # Note: All of the helper functions are for lazy evaluation. They all
2085 # return a CODE ref, which will return the intended value when evaluated.
2086 # Thus, whenever there's mention of a returned value, it's about that
2089 # Helper function to implement conditional inheritance depending on the
2090 # value of $disabled{asm}. Used in inherit_from values as follows:
2092 # inherit_from => [ "template", asm("asm_tmpl") ]
2097 $disabled{asm} ? () : @x;
2101 # Helper function to implement conditional value variants, with a default
2102 # plus additional values based on the value of $config{build_type}.
2103 # Arguments are given in hash table form:
2105 # picker(default => "Basic string: ",
2107 # release => "release")
2109 # When configuring with --debug, the resulting string will be
2110 # "Basic string: debug", and when not, it will be "Basic string: release"
2112 # This can be used to create variants of sets of flags according to the
2115 # cflags => picker(default => "-Wall",
2116 # debug => "-g -O0",
2121 return sub { add($opts{default} || (),
2122 $opts{$config{build_type}} || ())->(); }
2125 # Helper function to combine several values of different types into one.
2126 # This is useful if you want to combine a string with the result of a
2127 # lazy function, such as:
2129 # cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2133 return sub { add(@stuff)->(); }
2136 # Helper function to implement conditional values depending on the value
2137 # of $disabled{threads}. Can be used as follows:
2139 # cflags => combine("-Wall", threads("-pthread"))
2143 return sub { add($disabled{threads} ? () : @flags)->(); }
2148 our $add_called = 0;
2149 # Helper function to implement adding values to already existing configuration
2150 # values. It handles elements that are ARRAYs, CODEs and scalars
2152 my $separator = shift;
2154 # If there's any ARRAY in the collection of values OR the separator
2155 # is undef, we will return an ARRAY of combined values, otherwise a
2156 # string of joined values with $separator as the separator.
2157 my $found_array = !defined($separator);
2162 while (ref($res) eq "CODE") {
2165 if (defined($res)) {
2166 if (ref($res) eq "ARRAY") {
2182 join($separator, grep { defined($_) && $_ ne "" } @values);
2186 my $separator = " ";
2187 if (ref($_[$#_]) eq "HASH") {
2189 $separator = $opts->{separator};
2192 sub { _add($separator, @x, @_) };
2195 my $separator = " ";
2196 if (ref($_[$#_]) eq "HASH") {
2198 $separator = $opts->{separator};
2201 sub { _add($separator, @_, @x) };
2204 # configuration reader, evaluates the input file as a perl script and expects
2205 # it to fill %targets with target configurations. Those are then added to
2209 open(CONFFILE, "< $fname")
2210 or die "Can't open configuration file '$fname'!\n";
2213 my $content = <CONFFILE>;
2218 # Protect certain tables from tampering
2219 local %table = %::table;
2225 # For each target, check that it's configured with a hash table.
2226 foreach (keys %targets) {
2227 if (ref($targets{$_}) ne "HASH") {
2228 if (ref($targets{$_}) eq "") {
2229 warn "Deprecated target configuration for $_, ignoring...\n";
2231 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2233 delete $targets{$_};
2235 $targets{$_}->{_conf_fname_int} = add([ $fname ]);
2239 %table = (%table, %targets);
2243 # configuration resolver. Will only resolve all the lazy evaluation
2244 # codeblocks for the chosen target and all those it inherits from,
2246 sub resolve_config {
2248 my @breadcrumbs = @_;
2250 # my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2252 if (grep { $_ eq $target } @breadcrumbs) {
2253 die "inherit_from loop! target backtrace:\n "
2254 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
2257 if (!defined($table{$target})) {
2258 warn "Warning! target $target doesn't exist!\n";
2261 # Recurse through all inheritances. They will be resolved on the
2262 # fly, so when this operation is done, they will all just be a
2263 # bunch of attributes with string values.
2264 # What we get here, though, are keys with references to lists of
2265 # the combined values of them all. We will deal with lists after
2266 # this stage is done.
2267 my %combined_inheritance = ();
2268 if ($table{$target}->{inherit_from}) {
2270 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2271 foreach (@inherit_from) {
2272 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2274 # 'template' is a marker that's considered private to
2275 # the config that had it.
2276 delete $inherited_config{template};
2278 foreach (keys %inherited_config) {
2279 if (!$combined_inheritance{$_}) {
2280 $combined_inheritance{$_} = [];
2282 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2287 # We won't need inherit_from in this target any more, since we've
2288 # resolved all the inheritances that lead to this
2289 delete $table{$target}->{inherit_from};
2291 # Now is the time to deal with those lists. Here's the place to
2292 # decide what shall be done with those lists, all based on the
2293 # values of the target we're currently dealing with.
2294 # - If a value is a coderef, it will be executed with the list of
2295 # inherited values as arguments.
2296 # - If the corresponding key doesn't have a value at all or is the
2297 # empty string, the inherited value list will be run through the
2298 # default combiner (below), and the result becomes this target's
2300 # - Otherwise, this target's value is assumed to be a string that
2301 # will simply override the inherited list of values.
2302 my $default_combiner = add();
2305 map { $_ => 1 } (keys %combined_inheritance,
2306 keys %{$table{$target}});
2308 sub process_values {
2310 my $inherited = shift; # Always a [ list ]
2316 while(ref($object) eq "CODE") {
2317 $object = $object->(@$inherited);
2319 if (!defined($object)) {
2322 elsif (ref($object) eq "ARRAY") {
2323 local $add_called; # To make sure recursive calls don't affect it
2324 return [ map { process_values($_, $inherited, $target, $entry) }
2326 } elsif (ref($object) eq "") {
2329 die "cannot handle reference type ",ref($object)
2330 ," found in target ",$target," -> ",$entry,"\n";
2334 foreach (sort keys %all_keys) {
2335 my $previous = $combined_inheritance{$_};
2337 # Current target doesn't have a value for the current key?
2338 # Assign it the default combiner, the rest of this loop body
2339 # will handle it just like any other coderef.
2340 if (!exists $table{$target}->{$_}) {
2341 $table{$target}->{$_} = $default_combiner;
2344 $table{$target}->{$_} = process_values($table{$target}->{$_},
2345 $combined_inheritance{$_},
2347 unless(defined($table{$target}->{$_})) {
2348 delete $table{$target}->{$_};
2350 # if ($extra_checks &&
2351 # $previous && !($add_called || $previous ~~ $table{$target}->{$_})) {
2352 # warn "$_ got replaced in $target\n";
2356 # Finally done, return the result.
2357 return %{$table{$target}};
2362 print STDERR $usage;
2363 print STDERR "\npick os/compiler from:\n";
2367 foreach $i (sort keys %table)
2369 next if $table{$i}->{template};
2370 next if $i =~ /^debug/;
2371 $k += length($i) + 1;
2377 print STDERR $i . " ";
2379 foreach $i (sort keys %table)
2381 next if $table{$i}->{template};
2382 next if $i !~ /^debug/;
2383 $k += length($i) + 1;
2389 print STDERR $i . " ";
2391 print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2400 unlink $out || warn "Can't remove $out, $!"
2402 foreach (@templates) {
2403 die "Can't open $_, $!" unless -f $_;
2405 my $perlcmd = (quotify("maybeshell", $config{perl}))[0];
2406 my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2407 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2410 rename("$out.new", $out) || die "Can't rename $out.new, $!";
2417 if (eval { require IPC::Cmd; 1; }) {
2419 return scalar IPC::Cmd::can_run($name);
2421 # if there is $directories component in splitpath,
2422 # then it's not something to test with $PATH...
2423 return $name if (File::Spec->splitpath($name))[1];
2425 foreach (File::Spec->path()) {
2426 my $fullpath = catfile($_, "$name$target{exe_extension}");
2427 if (-f $fullpath and -x $fullpath) {
2434 # Configuration printer ##############################################
2436 sub print_table_entry
2439 my %target = resolve_config($target);
2442 # Don't print the templates
2443 return if $target{template};
2504 if ($type eq "TABLE") {
2506 print "*** $target\n";
2507 foreach (@sequence) {
2508 if (ref($target{$_}) eq "ARRAY") {
2509 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2511 printf "\$%-12s = %s\n", $_, $target{$_};
2514 } elsif ($type eq "HASH") {
2516 length((sort { length($a) <=> length($b) } @sequence)[-1]);
2517 print " '$target' => {\n";
2518 foreach (@sequence) {
2520 if (ref($target{$_}) eq "ARRAY") {
2521 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2523 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2531 # Utility routines ###################################################
2533 # On VMS, if the given file is a logical name, File::Spec::Functions
2534 # will consider it an absolute path. There are cases when we want a
2535 # purely syntactic check without checking the environment.
2539 # On non-platforms, we just use file_name_is_absolute().
2540 return file_name_is_absolute($file) unless $^O eq "VMS";
2542 # If the file spec includes a device or a directpry spec,
2543 # file_name_is_absolute() is perfectly safe.
2544 return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2546 # Here, we know the given file spec isn't absolute
2550 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2551 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2552 # realpath() requires that at least all path components except the last is an
2553 # existing directory. On VMS, the last component of the directory spec must
2558 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
2559 # will return the volume name for the device, no matter what. Also,
2560 # it will return an incorrect directory spec if the argument is a
2561 # directory that doesn't exist.
2563 return rel2abs($dir);
2566 # We use realpath() on Unix, since no other will properly clean out
2568 use Cwd qw/realpath/;
2570 return realpath($dir);
2575 perl => sub { my $x = shift;
2576 $x =~ s/([\\\$\@"])/\\$1/g;
2577 return '"'.$x.'"'; },
2578 maybeshell => sub { my $x = shift;
2579 (my $y = $x) =~ s/([\\\"])/\\$1/g;
2580 if ($x ne $y || $x =~ m|\s|) {
2589 defined($processors{$for}) ? $processors{$for} : sub { shift; };
2591 return map { $processor->($_); } @_;
2594 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2595 # $filename is a file name to read from
2596 # $line_concat_cond_re is a regexp detecting a line continuation ending
2597 # $line_concat is a CODEref that takes care of concatenating two lines
2598 sub collect_from_file {
2599 my $filename = shift;
2600 my $line_concat_cond_re = shift;
2601 my $line_concat = shift;
2603 open my $fh, $filename || die "unable to read $filename: $!\n";
2605 my $saved_line = "";
2609 if (defined $line_concat) {
2610 $_ = $line_concat->($saved_line, $_);
2613 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2619 die "$filename ending with continuation line\n" if $_;
2625 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2626 # $array is an ARRAYref of lines
2627 # $line_concat_cond_re is a regexp detecting a line continuation ending
2628 # $line_concat is a CODEref that takes care of concatenating two lines
2629 sub collect_from_array {
2631 my $line_concat_cond_re = shift;
2632 my $line_concat = shift;
2633 my @array = (@$array);
2636 my $saved_line = "";
2638 while (defined($_ = shift @array)) {
2640 if (defined $line_concat) {
2641 $_ = $line_concat->($saved_line, $_);
2644 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2650 die "input text ending with continuation line\n" if $_;
2655 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2656 # $lineiterator is a CODEref that delivers one line at a time.
2657 # All following arguments are regex/CODEref pairs, where the regexp detects a
2658 # line and the CODEref does something with the result of the regexp.
2659 sub collect_information {
2660 my $lineiterator = shift;
2661 my %collectors = @_;
2663 while(defined($_ = $lineiterator->())) {
2666 if ($collectors{"BEFORE"}) {
2667 $collectors{"BEFORE"}->($_);
2669 foreach my $re (keys %collectors) {
2670 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2671 $collectors{$re}->($lineiterator);
2675 if ($collectors{"OTHERWISE"}) {
2676 $collectors{"OTHERWISE"}->($lineiterator, $_)
2677 unless $found || !defined $collectors{"OTHERWISE"};
2679 if ($collectors{"AFTER"}) {
2680 $collectors{"AFTER"}->($_);
2686 # $line is a line of text to split up into tokens
2687 # returns a list of tokens
2689 # Tokens are divided by spaces. If the tokens include spaces, they
2690 # have to be quoted with single or double quotes. Double quotes
2691 # inside a double quoted token must be escaped. Escaping is done
2693 # Basically, the same quoting rules apply for " and ' as in any
2696 my $line = my $debug_line = shift;
2699 while ($line =~ s|^\s+||, $line ne "") {
2701 while ($line ne "" && $line !~ m|^\s|) {
2702 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2705 } elsif ($line =~ m/^'([^']*)'/) {
2708 } elsif ($line =~ m/^(\S+)/) {
2713 push @result, $token;
2716 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2717 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2718 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";