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
15 use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/;
16 use File::Path qw/mkpath/;
17 use if $^O ne "VMS", 'File::Glob' => qw/glob/;
19 # see INSTALL for instructions.
21 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";
25 # --config add the given configuration file, which will be read after
26 # any "Configurations*" files that are found in the same
27 # directory as this script.
28 # --prefix prefix for the OpenSSL installation, which includes the
29 # directories bin, lib, include, share/man, share/doc/openssl
30 # This becomes the value of INSTALLTOP in Makefile
31 # (Default: /usr/local)
32 # --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys.
33 # If it's a relative directory, it will be added on the directory
34 # given with --prefix.
35 # This becomes the value of OPENSSLDIR in Makefile and in C.
36 # (Default: PREFIX/ssl)
38 # --cross-compile-prefix Add specified prefix to binutils components.
40 # --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for
41 # interfaces deprecated as of the specified OpenSSL version.
43 # no-hw-xxx do not compile support for specific crypto hardware.
44 # Generic OpenSSL-style methods relating to this support
45 # are always compiled but return NULL if the hardware
46 # support isn't compiled.
47 # no-hw do not compile support for any crypto hardware.
48 # [no-]threads [don't] try to create a library that is suitable for
49 # multithreaded applications (default is "threads" if we
51 # [no-]shared [don't] try to create shared libraries when supported.
52 # [no-]pic [don't] try to build position independent code when supported.
53 # If disabled, it also disables shared and dynamic-engine.
54 # no-asm do not use assembler
55 # no-dso do not compile in any native shared-library methods. This
56 # will ensure that all methods just return NULL.
57 # no-egd do not compile support for the entropy-gathering daemon APIs
58 # [no-]zlib [don't] compile support for zlib compression.
59 # zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
60 # library and will be loaded in run-time by the OpenSSL library.
61 # sctp include SCTP support
62 # 386 generate 80386 code
63 # enable-weak-ssl-ciphers
64 # Enable weak ciphers that are disabled by default. This currently
65 # only includes RC4 based ciphers.
66 # no-sse2 disables IA-32 SSE2 code, above option implies no-sse2
67 # no-<cipher> build without specified algorithm (rsa, idea, rc5, ...)
68 # -<xxx> +<xxx> compiler options are passed through
70 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
71 # provided to stack calls. Generates unique stack functions for
72 # each possible stack type.
73 # BN_LLONG use the type 'long long' in crypto/bn/bn.h
74 # RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
75 # Following are set automatically by this script
77 # MD5_ASM use some extra md5 assembler,
78 # SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86
79 # RMD160_ASM use some extra ripemd160 assembler,
80 # SHA256_ASM sha256_block is implemented in assembler
81 # SHA512_ASM sha512_block is implemented in assembler
82 # AES_ASM ASE_[en|de]crypt is implemented in assembler
84 # Minimum warning options... any contributions to OpenSSL should at least get
87 # DEBUG_UNUSED enables __owur (warn unused result) checks.
88 my $gcc_devteam_warn = "-DDEBUG_UNUSED"
89 # -DPEDANTIC complements -pedantic and is meant to mask code that
90 # is not strictly standard-compliant and/or implementation-specifc,
91 # e.g. inline assembly, disregards to alignment requirements, such
92 # that -pedantic would complain about. Incidentally -DPEDANTIC has
93 # to be used even in sanitized builds, because sanitizer too is
94 # supposed to and does take notice of non-standard behaviour. Then
95 # -pedantic with pre-C9x compiler would also complain about 'long
96 # long' not being supported. As 64-bit algorithms are common now,
97 # it grew impossible to resolve this without sizeable additional
98 # code, so we just tell compiler to be pedantic about everything
99 # but 'long long' type.
100 . " -DPEDANTIC -pedantic -Wno-long-long"
103 . " -Wmissing-prototypes"
110 # These are used in addition to $gcc_devteam_warn when the compiler is clang.
111 # TODO(openssl-team): fix problems and investigate if (at least) the
112 # following warnings can also be enabled:
116 # -Wlanguage-extension-token -- no, we use asm()
117 # -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc
118 # -Wextended-offsetof -- no, needed in CMS ASN1 code
119 my $clang_devteam_warn = ""
120 . " -Qunused-arguments"
122 . " -Wno-unused-parameter"
123 . " -Wno-missing-field-initializers"
124 . " -Wno-language-extension-token"
125 . " -Wno-extended-offsetof"
126 . " -Wconditional-uninitialized"
127 . " -Wincompatible-pointer-types-discards-qualifiers"
128 . " -Wmissing-variable-declarations"
131 # This adds backtrace information to the memory leak info. Is only used
132 # when crypto-mdebug-backtrace is enabled.
133 my $memleak_devteam_backtrace = "-rdynamic";
135 my $strict_warnings = 0;
137 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
138 # which would cover all BSD flavors. -pthread applies to them all,
139 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
140 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
141 # which has to be accompanied by explicit -D_THREAD_SAFE and
142 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
143 # seems to be sufficient?
144 our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
147 # API compability name to version number mapping.
149 my $maxapi = "1.1.0"; # API for "no-deprecated" builds
151 "1.1.0" => "0x10100000L",
152 "1.0.0" => "0x10000000L",
153 "0.9.8" => "0x00908000L",
160 # Forward declarations ###############################################
162 # read_config(filename)
164 # Reads a configuration file and populates %table with the contents
165 # (which the configuration file places in %targets).
168 # resolve_config(target)
170 # Resolves all the late evaluations, inheritances and so on for the
171 # chosen target and any target it inherits from.
175 # Information collection #############################################
177 # Unified build supports separate build dir
178 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
179 my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax
180 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
182 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
184 $config{sourcedir} = abs2rel($srcdir);
185 $config{builddir} = abs2rel($blddir);
187 # Collect version numbers
188 $config{version} = "unknown";
189 $config{version_num} = "unknown";
190 $config{shlib_version_number} = "unknown";
191 $config{shlib_version_history} = "unknown";
194 collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')),
195 qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; },
196 qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 },
197 qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 },
198 qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 }
200 if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; }
202 ($config{major}, $config{minor})
203 = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/);
204 ($config{shlib_major}, $config{shlib_minor})
205 = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/);
206 die "erroneous version information in opensslv.h: ",
207 "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n"
208 if ($config{major} eq "" || $config{minor} eq ""
209 || $config{shlib_major} eq "" || $config{shlib_minor} eq "");
211 # Collect target configurations
213 my $pattern = catfile(dirname($0), "Configurations", "*.conf");
214 foreach (sort glob($pattern)) {
218 if (defined $ENV{$local_config_envname}) {
220 # VMS environment variables are logical names,
221 # which can be used as is
222 $pattern = $local_config_envname . ':' . '*.conf';
224 $pattern = catfile($ENV{$local_config_envname}, '*.conf');
227 foreach (sort glob($pattern)) {
233 print "Configuring OpenSSL version $config{version} (0x$config{version_num})\n";
236 $config{openssldir}="";
237 $config{processor}="";
239 $config{cross_compile_prefix}="";
240 $config{fipslibdir}="/usr/local/ssl/fips-2.0/lib/";
241 my $nofipscanistercheck=0;
242 $config{baseaddr}="0xFB00000";
243 my $auto_threads=1; # enable threads automatically? true by default
247 # Top level directories to build
248 $config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "tools" ];
249 # crypto/ subdirectories to build
252 "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2",
253 "des", "aes", "rc2", "rc4", "rc5", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes",
254 "bn", "ec", "rsa", "dsa", "dh", "dso", "engine",
255 "buffer", "bio", "stack", "lhash", "rand", "err",
256 "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui",
257 "cms", "ts", "srp", "cmac", "ct", "async", "kdf"
260 # Known TLS and DTLS protocols
261 my @tls = qw(ssl3 tls1 tls1_1 tls1_2);
262 my @dtls = qw(dtls1 dtls1_2);
264 # Explicitly known options that are possible to disable. They can
265 # be regexps, and will be used like this: /^no-${option}$/
266 # For developers: keep it sorted alphabetically
285 "crypto-mdebug-backtrace",
299 "ec_nistp_64_gcc_128",
351 foreach my $proto ((@tls, @dtls))
353 push(@disablables, $proto);
354 push(@disablables, "$proto-method");
357 my @deprecated_disablables = (
362 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
364 our %disabled = ( # "what" => "comment"
366 "ec_nistp_64_gcc_128" => "default",
372 "ssl-trace" => "default",
374 "ssl3-method" => "default",
375 "ubsan" => "default",
376 "unit-test" => "default",
377 "weak-ssl-ciphers" => "default",
379 "zlib-dynamic" => "default",
380 "crypto-mdebug" => "default",
381 "crypto-mdebug-backtrace" => "default",
382 "heartbeats" => "default",
385 # Note: => pair form used for aesthetics, not to truly make a hash table
386 my @disable_cascades = (
387 # "what" => [ "cascade", ... ]
388 sub { $config{processor} eq "386" }
391 "ssl3-method" => [ "ssl3" ],
392 "zlib" => [ "zlib-dynamic" ],
394 "ec" => [ "ecdsa", "ecdh" ],
396 "dgram" => [ "dtls", "sctp" ],
397 "sock" => [ "dgram" ],
400 # SSL 3.0, (D)TLS 1.0 and TLS 1.1 require MD5 and SHA
401 "md5" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
402 "sha" => [ "ssl", "tls1", "tls1_1", "dtls1" ],
404 # Additionally, SSL 3.0 requires either RSA or DSA+DH
406 && ($disabled{dsa} || $disabled{dh}); }
409 # (D)TLS 1.0 and TLS 1.1 also require either RSA or DSA+DH
410 # or ECDSA + ECDH. (D)TLS 1.2 has this requirement as well.
411 # (XXX: We don't support PSK-only builds).
413 && ($disabled{dsa} || $disabled{dh})
414 && ($disabled{ecdsa} || $disabled{ecdh}); }
415 => [ "tls1", "tls1_1", "tls1_2",
416 "dtls1", "dtls1_2" ],
420 # SRP and HEARTBEATS require TLSEXT
421 "tlsext" => [ "srp", "heartbeats" ],
423 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
425 # Without DSO, we can't load dynamic engines, so don't build them dynamic
426 "dso" => [ "dynamic-engine" ],
428 # Without position independent code, there can be no shared libraries or DSOs
429 "pic" => [ "shared" ],
430 "shared" => [ "dynamic-engine" ],
431 "engine" => [ "afalgeng" ],
433 # no-autoalginit is only useful when building non-shared
434 "autoalginit" => [ "shared", "apps" ],
436 "stdio" => [ "apps" ],
437 "apps" => [ "tests" ],
438 "comp" => [ "zlib" ],
439 sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
442 # Avoid protocol support holes. Also disable all versions below N, if version
443 # N is disabled while N+1 is enabled.
445 my @list = (reverse @tls);
446 while ((my $first, my $second) = (shift @list, shift @list)) {
448 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
450 unshift @list, $second;
452 my @list = (reverse @dtls);
453 while ((my $first, my $second) = (shift @list, shift @list)) {
455 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} }
457 unshift @list, $second;
460 # Explicit "no-..." options will be collected in %disabled along with the defaults.
461 # To remove something from %disabled, use "enable-foo".
462 # For symmetry, "disable-foo" is a synonym for "no-foo".
464 my @generated_headers = (
465 "include/openssl/opensslconf.h",
466 "crypto/include/internal/bn_conf.h",
467 "crypto/include/internal/dso_conf.h"
470 my @generated_by_make_headers = (
477 &usage if ($#ARGV < 0);
481 $config{openssl_api_defines}=[];
482 $config{openssl_algorithm_defines}=[];
483 $config{openssl_thread_defines}=[];
484 $config{openssl_sys_defines}=[];
485 $config{openssl_other_defines}=[];
489 $config{build_type} = "release";
493 if (grep /^reconf(igure)?$/, @argvcopy) {
494 if (-f "./configdata.pm") {
495 my $file = "./configdata.pm";
496 unless (my $return = do $file) {
497 die "couldn't parse $file: $@" if $@;
498 die "couldn't do $file: $!" unless defined $return;
499 die "couldn't run $file" unless $return;
502 @argvcopy = defined($configdata::config{perlargv}) ?
503 @{$configdata::config{perlargv}} : ();
504 die "Incorrect data to reconfigure, please do a normal configuration\n"
505 if (grep(/^reconf/,@argvcopy));
506 $ENV{CROSS_COMPILE} = $configdata::config{cross_compile_prefix}
507 if defined($configdata::config{cross_compile_prefix});
508 $ENV{CROSS_COMPILE} = $configdata::config{cc}
509 if defined($configdata::config{cc});
511 print "Reconfiguring with: ", join(" ",@argvcopy), "\n";
512 print " CROSS_COMPILE = ",$ENV{CROSS_COMPILE},"\n"
513 if $ENV{CROSS_COMPILE};
514 print " CC = ",$ENV{CC},"\n" if $ENV{CC};
515 } elsif (open IN, "<Makefile") {
517 # THIS SECTION IS TEMPORARY, it helps transitioning from Makefile
518 # centered information gathering the reading configdata.pm
522 if (/^CONFIGURE_ARGS=\s*(.*)\s*/) {
523 # Older form, we split the string and hope for the best
524 @argvcopy = split /\s+/, $_;
525 die "Incorrect data to reconfigure, please do a normal configuration\n"
526 if (grep(/^reconf/,@argvcopy));
527 } elsif (/^CROSS_COMPILE=\s*(.*)/) {
528 $ENV{CROSS_COMPILE}=$1;
529 } elsif (/^CC=\s*(?:\$\(CROSS_COMPILE\))?(.*?)$/) {
534 # END OF TEMPORARY SECTION
537 die "Insufficient data to reconfigure, please do a normal configuration\n";
541 $config{perlargv} = [ @argvcopy ];
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 (grep { $word =~ /^${_}$/ } @deprecated_disablables)
568 $deprecated_options{$_} = 1;
571 elsif (!grep { $word =~ /^${_}$/ } @disablables)
573 $unsupported_options{$_} = 1;
577 if (/^no-(.+)$/ || /^disable-(.+)$/)
579 foreach my $proto ((@tls, @dtls))
581 if ($1 eq "$proto-method")
583 $disabled{"$proto"} = "option($proto-method)";
589 foreach my $proto (@dtls)
591 $disabled{$proto} = "option(dtls)";
593 $disabled{"dtls"} = "option(dtls)";
597 # Last one of its kind
598 $disabled{"ssl3"} = "option(ssl)";
602 # XXX: Tests will fail if all SSL/TLS
603 # protocols are disabled.
604 foreach my $proto (@tls)
606 $disabled{$proto} = "option(tls)";
609 elsif ($1 eq "static-engine")
611 delete $disabled{"dynamic-engine"};
613 elsif ($1 eq "dynamic-engine")
615 $disabled{"dynamic-engine"} = "option";
619 $disabled{$1} = "option";
621 # No longer an automatic choice
622 $auto_threads = 0 if ($1 eq "threads");
624 elsif (/^enable-(.+)$/)
626 if ($1 eq "static-engine")
628 $disabled{"dynamic-engine"} = "option";
630 elsif ($1 eq "dynamic-engine")
632 delete $disabled{"dynamic-engine"};
634 elsif ($1 eq "zlib-dynamic")
636 delete $disabled{"zlib"};
639 delete $disabled{$algo};
641 # No longer an automatic choice
642 $auto_threads = 0 if ($1 eq "threads");
644 elsif (/^--strict-warnings$/)
646 $strict_warnings = 1;
650 $config{build_type} = "debug";
652 elsif (/^--release$/)
654 $config{build_type} = "release";
657 { $config{processor}=386; }
664 # No RSAref support any more since it's not needed.
665 # The check for the option is there so scripts aren't
668 elsif (/^nofipscanistercheck$/)
671 $nofipscanistercheck = 1;
675 if (/^--prefix=(.*)$/)
678 die "Directory given with --prefix MUST be absolute\n"
679 unless file_name_is_absolute($config{prefix});
681 elsif (/^--api=(.*)$/)
685 elsif (/^--libdir=(.*)$/)
689 elsif (/^--openssldir=(.*)$/)
691 $config{openssldir}=$1;
693 elsif (/^--with-zlib-lib=(.*)$/)
695 $withargs{zlib_lib}=$1;
697 elsif (/^--with-zlib-include=(.*)$/)
699 $withargs{zlib_include}=$1;
701 elsif (/^--with-fipslibdir=(.*)$/)
703 $config{fipslibdir}="$1/";
705 elsif (/^--with-baseaddr=(.*)$/)
707 $config{baseaddr}="$1";
709 elsif (/^--cross-compile-prefix=(.*)$/)
711 $config{cross_compile_prefix}=$1;
713 elsif (/^--config=(.*)$/)
717 elsif (/^-[lL](.*)$/ or /^-Wl,/)
723 push @user_defines, $1;
725 else # common if (/^[-+]/), just pass down...
727 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
728 $user_cflags.=" ".$_;
733 die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
736 unless ($_ eq $target || /^no-/ || /^disable-/)
738 # "no-..." follows later after implied disactivations
739 # have been derived. (Don't take this too seriously,
740 # we really only write OPTIONS to the Makefile out of
743 if ($config{options} eq "")
744 { $config{options} = $_; }
746 { $config{options} .= " ".$_; }
749 if (defined($config{api}) && !exists $apitable->{$config{api}}) {
750 die "***** Unsupported api compatibility level: $config{api}\n",
753 if (keys %deprecated_options)
755 warn "***** Deprecated options: ",
756 join(", ", keys %deprecated_options), "\n";
758 if (keys %unsupported_options)
760 die "***** Unsupported options: ",
761 join(", ", keys %unsupported_options), "\n";
767 delete $disabled{"shared"} if ($disabled{"shared"} =~ /^default/);
771 @{$config{dirs}} = grep !/^fips$/, @{$config{dirs}};
774 my @tocheckfor = (keys %disabled);
775 while (@tocheckfor) {
776 my %new_tocheckfor = ();
777 my @cascade_copy = (@disable_cascades);
778 while (@cascade_copy) {
779 my ($test, $descendents) = (shift @cascade_copy, shift @cascade_copy);
780 if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) {
781 foreach(grep { !defined($disabled{$_}) } @$descendents) {
782 $new_tocheckfor{$_} = 1; $disabled{$_} = "forced";
786 @tocheckfor = (keys %new_tocheckfor);
789 if ($target eq "TABLE") {
790 foreach (sort keys %table) {
791 print_table_entry($_, "TABLE");
796 if ($target eq "LIST") {
797 foreach (sort keys %table) {
798 print $_,"\n" unless $table{$_}->{template};
803 if ($target eq "HASH") {
804 print "%table = (\n";
805 foreach (sort keys %table) {
806 print_table_entry($_, "HASH");
811 # Backward compatibility?
812 if ($target =~ m/^CygWin32(-.*)$/) {
813 $target = "Cygwin".$1;
816 foreach (sort (keys %disabled))
818 $config{options} .= " no-$_";
820 printf " no-%-12s %-10s", $_, "[$disabled{$_}]";
832 elsif (/^dynamic-engine$/)
834 elsif (/^makedepend$/)
836 elsif (/^zlib-dynamic$/)
842 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}};
843 @{$config{sdirs}} = grep !/^engine$/, @{$config{sdirs}};
844 push @{$config{openssl_other_defines}}, "OPENSSL_NO_ENGINE";
849 ($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
851 if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/ || /^async$/
852 || /^autoalginit/ || /^autoerrinit/)
854 push @{$config{openssl_other_defines}}, "OPENSSL_NO_$ALGO";
855 print " OPENSSL_NO_$ALGO";
857 if (/^err$/) { push @user_defines, "OPENSSL_NO_ERR"; }
861 ($ALGO,$algo) = ("RMD160","rmd160") if ($algo eq "ripemd");
863 push @{$config{openssl_algorithm_defines}}, "OPENSSL_NO_$ALGO";
864 print " OPENSSL_NO_$ALGO";
866 # fix-up crypto/directory name(s)
867 $algo="whrlpool" if $algo eq "whirlpool";
868 $algo="ripemd" if $algo eq "rmd160";
869 @{$config{sdirs}} = grep { $_ ne $algo} @{$config{sdirs}};
878 print "Configuring for $target\n";
880 # Support for legacy targets having a name starting with 'debug-'
881 my ($d, $t) = $target =~ m/^(debug-)?(.*)$/;
883 $config{build_type} = "debug";
885 # If we do not find debug-foo in the table, the target is set to foo.
886 if (!$table{$target}) {
890 $config{target} = $target;
891 my %target = resolve_config($target);
893 &usage if (!%target || $target{template});
895 %target = ( %{$table{DEFAULTS}}, %target );
897 $target{exe_extension}="";
898 $target{exe_extension}=".exe" if ($config{target} eq "DJGPP"
899 || $config{target} =~ /^(?:Cygwin|mingw)/);
900 $target{exe_extension}=".pm" if ($config{target} =~ /vos/);
902 ($target{shared_extension_simple}=$target{shared_extension})
903 =~ s|\.\$\(SHLIB_MAJOR\)\.\$\(SHLIB_MINOR\)||;
904 $target{dso_extension}=$target{shared_extension_simple};
905 ($target{shared_import_extension}=$target{shared_extension_simple}.".a")
906 if ($config{target} =~ /^(?:Cygwin|mingw)/);
909 $config{cross_compile_prefix} = $ENV{'CROSS_COMPILE'}
910 if $config{cross_compile_prefix} eq "";
912 # Allow overriding the names of some tools. USE WITH CARE
913 $config{perl} = $ENV{'PERL'} || ($^O ne "VMS" ? $^X : "perl");
914 $target{cc} = $ENV{'CC'} || $target{cc} || "cc";
915 $target{ranlib} = $ENV{'RANLIB'} || $target{ranlib} ||
916 (which("$config{cross_compile_prefix}ranlib") ?
917 "\$(CROSS_COMPILE)ranlib" : "true");
918 $target{ar} = $ENV{'AR'} || $target{ar} || "ar";
919 $target{nm} = $ENV{'NM'} || $target{nm} || "nm";
921 $ENV{'RC'} || $ENV{'WINDRES'} || $target{rc} || "windres";
923 # For cflags, lflags, plib_lflags, ex_libs and defines, add the debug_
924 # or release_ attributes.
925 # Do it in such a way that no spurious space is appended (hence the grep).
926 $config{defines} = [];
927 $config{cflags} = "";
928 $config{ex_libs} = "";
929 $config{shared_ldflag} = "";
931 # Make sure build_scheme is consistent.
932 $target{build_scheme} = [ $target{build_scheme} ]
933 if ref($target{build_scheme}) ne "ARRAY";
935 my ($builder, $builder_platform, @builder_opts) =
936 @{$target{build_scheme}};
938 push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release";
940 if ($target =~ /^mingw/ && `$target{cc} --target-help 2>&1` =~ m/-mno-cygwin/m)
942 $config{cflags} .= " -mno-cygwin";
943 $config{shared_ldflag} .= " -mno-cygwin";
946 if ($target =~ /linux.*-mips/ && !$disabled{asm} && $user_cflags !~ /-m(ips|arch=)/) {
947 # minimally required architecture flags for assembly modules
948 $config{cflags}="-mips2 $config{cflags}" if ($target =~ /mips32/);
949 $config{cflags}="-mips3 $config{cflags}" if ($target =~ /mips64/);
952 my $no_shared_warn=0;
953 my $no_user_cflags=0;
954 my $no_user_defines=0;
956 # The DSO code currently always implements all functions so that no
957 # applications will have to worry about that from a compilation point
958 # of view. However, the "method"s may return zero unless that platform
959 # has support compiled in for them. Currently each method is enabled
960 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
961 # string entry into using the following logic;
962 if (!$disabled{dso} && $target{dso_scheme} ne "")
964 $target{dso_scheme} =~ tr/[a-z]/[A-Z]/;
965 if ($target{dso_scheme} eq "DLFCN")
967 unshift @{$config{defines}}, "DSO_DLFCN", "HAVE_DLFCN_H";
969 elsif ($target{dso_scheme} eq "DLFCN_NO_H")
971 unshift @{$config{defines}}, "DSO_DLFCN";
975 unshift @{$config{defines}}, "DSO_$target{dso_scheme}";
979 $config{ex_libs}="$libs$config{ex_libs}" if ($libs ne "");
985 @{$config{defines}} = grep !/^[BL]_ENDIAN$/, @{$config{defines}};
986 @{$target{defines}} = grep !/^[BL]_ENDIAN$/, @{$target{defines}};
990 # If threads aren't disabled, check how possible they are
991 unless ($disabled{threads}) {
993 # Enabled by default, disable it forcibly if unavailable
994 if ($target{thread_scheme} eq "(unknown)") {
995 $disabled{threads} = "unavailable";
998 # The user chose to enable threads explicitly, let's see
999 # if there's a chance that's possible
1000 if ($target{thread_scheme} eq "(unknown)") {
1001 # If the user asked for "threads" and we don't have internal
1002 # knowledge how to do it, [s]he is expected to provide any
1003 # system-dependent compiler options that are necessary. We
1004 # can't truly check that the given options are correct, but
1005 # we expect the user to know what [s]He is doing.
1006 if ($no_user_cflags && $no_user_defines) {
1007 die "You asked for multi-threading support, but didn't\n"
1008 ,"provide any system-specific compiler options\n";
1014 # If threads still aren't disabled, add a C macro to ensure the source
1015 # code knows about it. Any other flag is taken care of by the configs.
1016 unless($disabled{threads}) {
1017 foreach (("defines", "openssl_thread_defines")) {
1018 push @{$config{$_}}, "OPENSSL_THREADS";
1022 # With "deprecated" disable all deprecated features.
1023 if (defined($disabled{"deprecated"})) {
1024 $config{api} = $maxapi;
1027 if ($target{shared_target} eq "")
1030 if ((!$disabled{shared} || !$disabled{"dynamic-engine"})
1032 $disabled{shared} = "no-shared-target";
1033 $disabled{pic} = $disabled{shared} = $disabled{"dynamic-engine"} =
1037 if ($disabled{"dynamic-engine"}) {
1038 push @{$config{defines}}, "OPENSSL_NO_DYNAMIC_ENGINE";
1039 $config{dynamic_engines} = 0;
1041 push @{$config{defines}}, "OPENSSL_NO_STATIC_ENGINE";
1042 $config{dynamic_engines} = 1;
1045 unless ($disabled{fuzz}) {
1046 push @{$config{dirs}}, "fuzz";
1047 $config{cflags} .= "-fsanitize-coverage=edge,indirect-calls ";
1050 unless ($disabled{asan}) {
1051 $config{cflags} .= "-fsanitize=address ";
1054 unless ($disabled{ubsan}) {
1055 # -DPEDANTIC or -fnosanitize=aligmnent may also be required on some
1057 $config{cflags} .= "-fsanitize=undefined -fno-sanitize-recover=all ";
1060 unless ($disabled{fuzz} && $disabled{asan} && $disabled{ubsan}) {
1061 $config{cflags} .= "-fno-omit-frame-pointer -g ";
1067 # This saves the build files from having to check
1070 $target{shared_cflag} = $target{shared_ldflag} =
1071 $target{shared_rcflag} = "";
1075 push @{$config{defines}}, "OPENSSL_PIC";
1078 if ($target{sys_id} ne "")
1080 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
1083 unless ($disabled{asm}) {
1084 $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386");
1085 $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m}));
1087 # bn-586 is the only one implementing bn_*_part_words
1088 push @{$config{defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/);
1089 push @{$config{defines}}, "OPENSSL_IA32_SSE2" if (!$no_sse2 && $target{bn_asm_src} =~ /86/);
1091 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/);
1092 push @{$config{defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/);
1093 push @{$config{defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/);
1095 if ($config{fips}) {
1096 push @{$config{openssl_other_defines}}, "OPENSSL_FIPS";
1099 if ($target{sha1_asm_src}) {
1100 push @{$config{defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/);
1101 push @{$config{defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/);
1102 push @{$config{defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/);
1104 if ($target{md5_asm_src}) {
1105 push @{$config{defines}}, "MD5_ASM";
1107 $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC
1108 if ($target{rmd160_asm_src}) {
1109 push @{$config{defines}}, "RMD160_ASM";
1111 if ($target{aes_asm_src}) {
1112 push @{$config{defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);;
1113 # aes-ctr.fake is not a real file, only indication that assembler
1114 # module implements AES_ctr32_encrypt...
1115 push @{$config{defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//);
1116 # aes-xts.fake indicates presence of AES_xts_[en|de]crypt...
1117 push @{$config{defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//);
1118 $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($no_sse2);
1119 push @{$config{defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/);
1120 push @{$config{defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/);
1122 if ($target{wp_asm_src} =~ /mmx/) {
1123 if ($config{processor} eq "386") {
1124 $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src};
1125 } elsif (!$disabled{"whirlpool"}) {
1126 push @{$config{defines}}, "WHIRLPOOL_ASM";
1129 if ($target{modes_asm_src} =~ /ghash-/) {
1130 push @{$config{defines}}, "GHASH_ASM";
1132 if ($target{ec_asm_src} =~ /ecp_nistz256/) {
1133 push @{$config{defines}}, "ECP_NISTZ256_ASM";
1135 if ($target{poly1305_asm_src} ne "") {
1136 push @{$config{defines}}, "POLY1305_ASM";
1140 my $ecc = $target{cc};
1141 if ($^O ne "VMS" && !$disabled{makedepend}) {
1142 # Is the compiler gcc or clang? $ecc is used below to see if
1143 # error-checking can be turned on.
1144 my $ccpcc = "$config{cross_compile_prefix}$target{cc}";
1145 open(PIPE, "$ccpcc --version 2>&1 |");
1148 # Find the version number and save the major.
1149 m|(?:.*)\b(\d+)\.\d+\.\d+\b(?:.*)|;
1150 my $compiler_major = $1;
1151 # We know that GNU C version 3 and up as well as all clang
1152 # versions support dependency generation
1153 $config{makedepprog} = $ccpcc
1154 if (/clang/ || (/gcc/ && $compiler_major > 3));
1155 $ecc = "clang" if /clang/;
1156 $ecc = "gcc" if /gcc/;
1157 last if ($config{makedepprog} || !$lines--);
1161 $config{makedepprog} = which('makedepend') unless $config{makedepprog};
1162 $disabled{makedepend} = "unavailable" unless $config{makedepprog};
1167 # Deal with bn_ops ###################################################
1170 $config{export_var_as_fn} =0;
1171 my $def_int="unsigned int";
1172 $config{rc4_int} =$def_int;
1173 ($config{b64l},$config{b64},$config{b32})=(0,0,1);
1176 foreach (sort split(/\s+/,$target{bn_ops})) {
1177 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/;
1178 $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN';
1179 $config{bn_ll}=1 if $_ eq 'BN_LLONG';
1180 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR';
1181 ($config{b64l},$config{b64},$config{b32})
1182 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT';
1183 ($config{b64l},$config{b64},$config{b32})
1184 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG';
1185 ($config{b64l},$config{b64},$config{b32})
1186 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT';
1188 die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n"
1192 # Hack cflags for better warnings (dev option) #######################
1194 # "Stringify" the C flags string. This permits it to be made part of a string
1195 # and works as well on command lines.
1196 $config{cflags} =~ s/([\\\"])/\\$1/g;
1198 if (defined($config{api})) {
1199 $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ];
1200 my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}});
1201 push @{$config{defines}}, $apiflag;
1204 if ($strict_warnings)
1207 die "ERROR --strict-warnings requires gcc or clang"
1208 unless $ecc eq 'gcc' || $ecc eq 'clang';
1209 foreach $wopt (split /\s+/, $gcc_devteam_warn)
1211 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1213 if ($ecc eq "clang")
1215 foreach $wopt (split /\s+/, $clang_devteam_warn)
1217 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1222 unless ($disabled{"crypto-mdebug-backtrace"})
1224 foreach my $wopt (split /\s+/, $memleak_devteam_backtrace)
1226 $config{cflags} .= " $wopt" unless ($config{cflags} =~ /(?:^|\s)$wopt(?:\s|$)/)
1228 if ($target =~ /^BSD-/)
1230 $config{ex_libs} .= " -lexecinfo";
1234 if ($user_cflags ne "") { $config{cflags}="$config{cflags}$user_cflags"; }
1235 else { $no_user_cflags=1; }
1236 if (@user_defines) { $config{defines}=[ @{$config{defines}}, @user_defines ]; }
1237 else { $no_user_defines=1; }
1239 # ALL MODIFICATIONS TO %config and %target MUST BE DONE FROM HERE ON
1241 unless ($disabled{afalgeng}) {
1242 $config{afalgeng}="";
1243 if ($target =~ m/^linux/) {
1244 my $minver = 4*10000 + 1*100 + 0;
1245 if ($config{cross_compile_prefix} eq "") {
1246 my $verstr = `uname -r`;
1247 my ($ma, $mi1, $mi2) = split("\\.", $verstr);
1248 ($mi2) = $mi2 =~ /(\d+)/;
1249 my $ver = $ma*10000 + $mi1*100 + $mi2;
1250 if ($ver < $minver) {
1251 $disabled{afalgeng} = "too-old-kernel";
1253 push @{$config{engdirs}}, "afalg";
1256 $disabled{afalgeng} = "cross-compiling";
1259 $disabled{afalgeng} = "not-linux";
1263 push @{$config{openssl_other_defines}}, "OPENSSL_NO_AFALGENG" if ($disabled{afalgeng});
1265 # If we use the unified build, collect information from build.info files
1266 my %unified_info = ();
1268 my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO});
1269 if ($builder eq "unified") {
1270 # Store the name of the template file we will build the build file from
1271 # in %config. This may be useful for the build file itself.
1272 my $build_file_template;
1274 for my $filename (( $builder_platform."-".$target{build_file}.".tmpl",
1275 $target{build_file}.".tmpl" )) {
1276 if (defined $ENV{$local_config_envname}) {
1278 # VMS environment variables are logical names,
1279 # which can be used as is
1280 $build_file_template = $local_config_envname . ':' . $filename;
1282 $build_file_template = catfile($ENV{$local_config_envname},
1287 last if -f $build_file_template;
1289 $build_file_template = catfile($srcdir, "Configurations", $filename);
1291 last if -f $build_file_template;
1293 $config{build_file_template} = $build_file_template;
1295 use lib catdir(dirname(__FILE__),"util");
1296 use with_fallback qw(Text::Template);
1301 my $relativeto = shift || ".";
1303 $dir = catdir($base,$dir) unless isabsolute($dir);
1305 # Make sure the directories we're building in exists
1308 my $res = abs2rel(absolutedir($dir), rel2abs($relativeto));
1309 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n";
1316 my $relativeto = shift || ".";
1318 $file = catfile($base,$file) unless isabsolute($file);
1320 my $d = dirname($file);
1321 my $f = basename($file);
1323 # Make sure the directories we're building in exists
1326 my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto));
1327 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n";
1331 my @build_infos = ( [ ".", "build.info" ] );
1332 foreach (@{$config{dirs}}) {
1333 push @build_infos, [ $_, "build.info" ]
1334 if (-f catfile($srcdir, $_, "build.info"));
1336 foreach (@{$config{sdirs}}) {
1337 push @build_infos, [ catdir("crypto", $_), "build.info" ]
1338 if (-f catfile($srcdir, "crypto", $_, "build.info"));
1340 foreach (@{$config{engdirs}}) {
1341 push @build_infos, [ catdir("engines", $_), "build.info" ]
1342 if (-f catfile($srcdir, "engines", $_, "build.info"));
1345 $config{build_infos} = [ ];
1347 foreach (@build_infos) {
1348 my $sourced = catdir($srcdir, $_->[0]);
1349 my $buildd = catdir($blddir, $_->[0]);
1354 # The basic things we're trying to build
1361 my @intermediates = ();
1366 my %shared_sources = ();
1370 my %sharednames = ();
1373 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f);
1374 my $template = Text::Template->new(TYPE => 'FILE',
1375 SOURCE => catfile($sourced, $f));
1376 die "Something went wrong with $sourced/$f: $!\n" unless $template;
1379 $template->fill_in(HASH => { config => \%config,
1381 disabled => \%disabled,
1382 builddir => abs2rel($buildd, $blddir),
1383 sourcedir => abs2rel($sourced, $blddir),
1384 buildtop => abs2rel($blddir, $blddir),
1385 sourcetop => abs2rel($srcdir, $blddir) },
1386 DELIMITERS => [ "{-", "-}" ]);
1388 # The top item of this stack has the following values
1389 # -2 positive already run and we found ELSE (following ELSIF should fail)
1390 # -1 positive already run (skip until ENDIF)
1391 # 0 negatives so far (if we're at a condition, check it)
1392 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
1393 # 2 positive ELSE (following ELSIF should fail)
1395 collect_information(
1396 collect_from_array([ @text ],
1397 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
1398 $l1 =~ s/\\$//; $l1.$l2 }),
1399 # Info we're looking for
1400 qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
1402 if (! @skip || $skip[$#skip] > 0) {
1408 qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
1409 => sub { die "ELSIF out of scope" if ! @skip;
1410 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
1411 $skip[$#skip] = -1 if $skip[$#skip] != 0;
1412 $skip[$#skip] = !! $1
1413 if $skip[$#skip] == 0; },
1415 => sub { die "ELSE out of scope" if ! @skip;
1416 $skip[$#skip] = -2 if $skip[$#skip] != 0;
1417 $skip[$#skip] = 2 if $skip[$#skip] == 0; },
1419 => sub { die "ENDIF out of scope" if ! @skip;
1421 qr/^\s*PROGRAMS\s*=\s*(.*)\s*$/
1422 => sub { push @programs, tokenize($1)
1423 if !@skip || $skip[$#skip] > 0 },
1424 qr/^\s*LIBS\s*=\s*(.*)\s*$/
1425 => sub { push @libraries, tokenize($1)
1426 if !@skip || $skip[$#skip] > 0 },
1427 qr/^\s*ENGINES\s*=\s*(.*)\s*$/
1428 => sub { push @engines, tokenize($1)
1429 if !@skip || $skip[$#skip] > 0 },
1430 qr/^\s*SCRIPTS\s*=\s*(.*)\s*$/
1431 => sub { push @scripts, tokenize($1)
1432 if !@skip || $skip[$#skip] > 0 },
1433 qr/^\s*EXTRA\s*=\s*(.*)\s*$/
1434 => sub { push @extra, tokenize($1)
1435 if !@skip || $skip[$#skip] > 0 },
1436 qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/
1437 => sub { push @overrides, tokenize($1)
1438 if !@skip || $skip[$#skip] > 0 },
1440 qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
1441 => sub { push @{$ordinals{$1}}, tokenize($2)
1442 if !@skip || $skip[$#skip] > 0 },
1443 qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1444 => sub { push @{$sources{$1}}, tokenize($2)
1445 if !@skip || $skip[$#skip] > 0 },
1446 qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1447 => sub { push @{$shared_sources{$1}}, tokenize($2)
1448 if !@skip || $skip[$#skip] > 0 },
1449 qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1450 => sub { push @{$includes{$1}}, tokenize($2)
1451 if !@skip || $skip[$#skip] > 0 },
1452 qr/^\s*DEPEND\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1453 => sub { push @{$depends{$1}}, tokenize($2)
1454 if !@skip || $skip[$#skip] > 0 },
1455 qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1456 => sub { push @{$generate{$1}}, $2
1457 if !@skip || $skip[$#skip] > 0 },
1458 qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1459 => sub { push @{$renames{$1}}, tokenize($2)
1460 if !@skip || $skip[$#skip] > 0 },
1461 qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
1462 => sub { push @{$sharednames{$1}}, tokenize($2)
1463 if !@skip || $skip[$#skip] > 0 },
1464 qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/
1466 my $lineiterator = shift;
1467 my $target_kind = $1;
1468 while (defined $lineiterator->()) {
1470 if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) {
1471 die "ENDRAW doesn't match BEGINRAW"
1472 if $1 ne $target_kind;
1475 next if @skip && $skip[$#skip] <= 0;
1477 if ($target_kind eq $target{build_file}
1478 || $target_kind eq $target{build_file}."(".$builder_platform.")");
1481 qr/^(?:#.*|\s*)$/ => sub { },
1482 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
1484 if ($buildinfo_debug) {
1485 print STDERR "DEBUG: Parsing ",join(" ", @_),"\n";
1486 print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1490 if ($buildinfo_debug) {
1491 print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n";
1495 die "runaway IF?" if (@skip);
1497 foreach (keys %renames) {
1498 die "$_ renamed to more than one thing: "
1499 ,join(" ", @{$renames{$_}}),"\n"
1500 if scalar @{$renames{$_}} > 1;
1501 my $dest = cleanfile($buildd, $_, $blddir);
1502 my $to = cleanfile($buildd, $renames{$_}->[0], $blddir);
1503 die "$dest renamed to more than one thing: "
1504 ,$unified_info{rename}->{$dest}, $to
1505 unless !defined($unified_info{rename}->{$dest})
1506 or $unified_info{rename}->{$dest} eq $to;
1507 $unified_info{rename}->{$dest} = $to;
1510 foreach (@programs) {
1511 my $program = cleanfile($buildd, $_, $blddir);
1512 if ($unified_info{rename}->{$program}) {
1513 $program = $unified_info{rename}->{$program};
1515 $unified_info{programs}->{$program} = 1;
1518 foreach (@libraries) {
1519 my $library = cleanfile($buildd, $_, $blddir);
1520 if ($unified_info{rename}->{$library}) {
1521 $library = $unified_info{rename}->{$library};
1523 $unified_info{libraries}->{$library} = 1;
1526 die <<"EOF" if scalar @engines and !$config{dynamic_engines};
1527 ENGINES can only be used if configured with 'dynamic-engine'.
1528 This is usually a fault in a build.info file.
1530 foreach (@engines) {
1531 my $library = cleanfile($buildd, $_, $blddir);
1532 if ($unified_info{rename}->{$library}) {
1533 $library = $unified_info{rename}->{$library};
1535 $unified_info{engines}->{$library} = 1;
1538 foreach (@scripts) {
1539 my $script = cleanfile($buildd, $_, $blddir);
1540 if ($unified_info{rename}->{$script}) {
1541 $script = $unified_info{rename}->{$script};
1543 $unified_info{scripts}->{$script} = 1;
1547 my $extra = cleanfile($buildd, $_, $blddir);
1548 $unified_info{extra}->{$extra} = 1;
1551 foreach (@overrides) {
1552 my $override = cleanfile($buildd, $_, $blddir);
1553 $unified_info{overrides}->{$override} = 1;
1556 push @{$unified_info{rawlines}}, @rawlines;
1558 unless ($disabled{shared}) {
1559 # Check sharednames.
1560 foreach (keys %sharednames) {
1561 my $dest = cleanfile($buildd, $_, $blddir);
1562 if ($unified_info{rename}->{$dest}) {
1563 $dest = $unified_info{rename}->{$dest};
1565 die "shared_name for $dest with multiple values: "
1566 ,join(" ", @{$sharednames{$_}}),"\n"
1567 if scalar @{$sharednames{$_}} > 1;
1568 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir);
1569 die "shared_name found for a library $dest that isn't defined\n"
1570 unless $unified_info{libraries}->{$dest};
1571 die "shared_name for $dest with multiple values: "
1572 ,$unified_info{sharednames}->{$dest}, ", ", $to
1573 unless !defined($unified_info{sharednames}->{$dest})
1574 or $unified_info{sharednames}->{$dest} eq $to;
1575 $unified_info{sharednames}->{$dest} = $to;
1578 # Additionally, we set up sharednames for libraries that don't
1579 # have any, as themselves.
1580 foreach (keys %{$unified_info{libraries}}) {
1581 if (!defined $unified_info{sharednames}->{$_}) {
1582 $unified_info{sharednames}->{$_} = $_
1587 foreach (keys %ordinals) {
1589 my $ddest = cleanfile($buildd, $_, $blddir);
1590 if ($unified_info{rename}->{$ddest}) {
1591 $ddest = $unified_info{rename}->{$ddest};
1593 foreach (@{$ordinals{$dest}}) {
1594 my %known_ordinals =
1597 cleanfile($sourced, catfile("util", "libcrypto.num"), $blddir),
1599 cleanfile($sourced, catfile("util", "libssl.num"), $blddir)
1601 my $o = $known_ordinals{$_};
1602 die "Ordinals for $ddest defined more than once\n"
1603 if $unified_info{ordinals}->{$ddest};
1604 $unified_info{ordinals}->{$ddest} = [ $_, $o ];
1608 foreach (keys %sources) {
1610 my $ddest = cleanfile($buildd, $_, $blddir);
1611 if ($unified_info{rename}->{$ddest}) {
1612 $ddest = $unified_info{rename}->{$ddest};
1614 foreach (@{$sources{$dest}}) {
1615 my $s = cleanfile($sourced, $_, $blddir);
1617 # If it isn't in the source tree, we assume it's generated
1620 $s = cleanfile($buildd, $_, $blddir);
1622 # We recognise C and asm files
1623 if ($s =~ /\.[csS]\b$/) {
1624 (my $o = $_) =~ s/\.[csS]\b$/.o/;
1625 $o = cleanfile($buildd, $o, $blddir);
1626 $unified_info{sources}->{$ddest}->{$o} = 1;
1627 $unified_info{sources}->{$o}->{$s} = 1;
1629 $unified_info{sources}->{$ddest}->{$s} = 1;
1634 foreach (keys %shared_sources) {
1636 my $ddest = cleanfile($buildd, $_, $blddir);
1637 if ($unified_info{rename}->{$ddest}) {
1638 $ddest = $unified_info{rename}->{$ddest};
1640 foreach (@{$shared_sources{$dest}}) {
1641 my $s = cleanfile($sourced, $_, $blddir);
1643 # If it isn't in the source tree, we assume it's generated
1646 $s = cleanfile($buildd, $_, $blddir);
1648 # We recognise C and asm files
1649 if ($s =~ /\.[csS]\b$/) {
1650 (my $o = $_) =~ s/\.[csS]\b$/.o/;
1651 $o = cleanfile($buildd, $o, $blddir);
1652 $unified_info{shared_sources}->{$ddest}->{$o} = 1;
1653 $unified_info{sources}->{$o}->{$s} = 1;
1655 die "unrecognised source file type for shared library: $s\n";
1660 foreach (keys %generate) {
1662 my $ddest = cleanfile($buildd, $_, $blddir);
1663 if ($unified_info{rename}->{$ddest}) {
1664 $ddest = $unified_info{rename}->{$ddest};
1666 die "more than one generator for $dest: "
1667 ,join(" ", @{$generate{$_}}),"\n"
1668 if scalar @{$generate{$_}} > 1;
1669 my @generator = split /\s+/, $generate{$dest}->[0];
1670 $generator[0] = cleanfile($sourced, $generator[0], $blddir),
1671 $unified_info{generate}->{$ddest} = [ @generator ];
1674 foreach (keys %depends) {
1676 my $ddest = cleanfile($sourced, $_, $blddir);
1678 # If the destination doesn't exist in source, it can only be
1679 # a generated file in the build tree.
1681 $ddest = cleanfile($buildd, $_, $blddir);
1682 if ($unified_info{rename}->{$ddest}) {
1683 $ddest = $unified_info{rename}->{$ddest};
1686 foreach (@{$depends{$dest}}) {
1687 my $d = cleanfile($sourced, $_, $blddir);
1689 # If we know it's generated, or assume it is because we can't
1690 # find it in the source tree, we set file we depend on to be
1691 # in the build tree rather than the source tree, and assume
1692 # and that there are lines to build it in a BEGINRAW..ENDRAW
1693 # section or in the Makefile template.
1695 || (grep { $d eq $_ }
1696 map { cleanfile($srcdir, $_, $blddir) }
1697 (@generated_headers, @generated_by_make_headers))) {
1698 $d = cleanfile($buildd, $_, $blddir);
1700 # Take note if the file to depend on is being renamed
1701 if ($unified_info{rename}->{$d}) {
1702 $d = $unified_info{rename}->{$d};
1704 $unified_info{depends}->{$ddest}->{$d} = 1;
1705 # If we depend on a header file or a perl module, let's make
1706 # sure it can get included
1707 if ($d =~ /\.(h|pm)$/) {
1708 my $i = dirname($d);
1709 push @{$unified_info{includes}->{$ddest}}, $i
1710 unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1715 foreach (keys %includes) {
1717 my $ddest = cleanfile($sourced, $_, $blddir);
1719 # If the destination doesn't exist in source, it can only be
1720 # a generated file in the build tree.
1722 $ddest = cleanfile($buildd, $_, $blddir);
1723 if ($unified_info{rename}->{$ddest}) {
1724 $ddest = $unified_info{rename}->{$ddest};
1727 foreach (@{$includes{$dest}}) {
1728 my $i = cleandir($sourced, $_, $blddir);
1729 push @{$unified_info{includes}->{$ddest}}, $i
1730 unless grep { $_ eq $i } @{$unified_info{includes}->{$ddest}};
1735 ### Make unified_info a bit more efficient
1736 # One level structures
1737 foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) {
1738 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ];
1740 # Two level structures
1741 foreach my $l1 (("sources", "shared_sources", "ldadd", "depends")) {
1742 foreach my $l2 (sort keys %{$unified_info{$l1}}) {
1743 $unified_info{$l1}->{$l2} =
1744 [ sort keys %{$unified_info{$l1}->{$l2}} ];
1749 # For the schemes that need it, we provide the old *_obj configs
1750 # from the *_asm_obj ones
1751 foreach (grep /_(asm|aux)_src$/, keys %target) {
1753 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/;
1754 ($target{$obj} = $target{$src}) =~ s/\.[csS]\b/.o/g;
1757 # Write down our configuration where it fits #########################
1759 open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n";
1767 #use vars qw(\@ISA \@EXPORT);
1768 our \@ISA = qw(Exporter);
1769 our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables);
1772 print OUT "our %config = (\n";
1773 foreach (sort keys %config) {
1774 if (ref($config{$_}) eq "ARRAY") {
1775 print OUT " ", $_, " => [ ", join(", ",
1776 map { quotify("perl", $_) }
1777 @{$config{$_}}), " ],\n";
1779 print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n"
1786 print OUT "our %target = (\n";
1787 foreach (sort keys %target) {
1788 if (ref($target{$_}) eq "ARRAY") {
1789 print OUT " ", $_, " => [ ", join(", ",
1790 map { quotify("perl", $_) }
1791 @{$target{$_}}), " ],\n";
1793 print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n"
1800 print OUT "our \%available_protocols = (\n";
1801 print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n";
1802 print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n";
1807 print OUT "our \@disablables = (\n";
1808 foreach (@disablables) {
1809 print OUT " ", quotify("perl", $_), ",\n";
1815 print OUT "our \%disabled = (\n";
1816 foreach (sort keys %disabled) {
1817 print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n";
1823 print OUT "our %withargs = (\n";
1824 foreach (sort keys %withargs) {
1825 if (ref($withargs{$_}) eq "ARRAY") {
1826 print OUT " ", $_, " => [ ", join(", ",
1827 map { quotify("perl", $_) }
1828 @{$withargs{$_}}), " ],\n";
1830 print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n"
1837 if ($builder eq "unified") {
1842 if (ref $_ eq "ARRAY") {
1843 print OUT " "x$indent, "[\n";
1845 $recurse->($indent + 4, $_);
1847 print OUT " "x$indent, "],\n";
1848 } elsif (ref $_ eq "HASH") {
1850 print OUT " "x$indent, "{\n";
1851 foreach (sort keys %h) {
1852 if (ref $h{$_} eq "") {
1853 print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n";
1855 print OUT " "x($indent + 4), quotify("perl", $_), " =>\n";
1856 $recurse->($indent + 8, $h{$_});
1859 print OUT " "x$indent, "},\n";
1861 print OUT " "x$indent, quotify("perl", $_), ",\n";
1865 print OUT "our %unified_info = (\n";
1866 foreach (sort keys %unified_info) {
1867 if (ref $unified_info{$_} eq "") {
1868 print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n";
1870 print OUT " "x4, quotify("perl", $_), " =>\n";
1871 $recurse->(8, $unified_info{$_});
1883 print "CC =$config{cross_compile_prefix}$target{cc}\n";
1884 print "CFLAG =$target{cflags} $config{cflags}\n";
1885 print "SHARED_CFLAG =$target{shared_cflag}\n";
1886 print "DEFINES =",join(" ", @{$target{defines}}, @{$config{defines}}),"\n";
1887 print "LFLAG =$target{lflags}\n";
1888 print "PLIB_LFLAG =$target{plib_lflags}\n";
1889 print "EX_LIBS =$target{ex_libs} $config{ex_libs}\n";
1890 print "APPS_OBJ =$target{apps_obj}\n";
1891 print "CPUID_OBJ =$target{cpuid_obj}\n";
1892 print "UPLINK_OBJ =$target{uplink_obj}\n";
1893 print "BN_ASM =$target{bn_obj}\n";
1894 print "EC_ASM =$target{ec_obj}\n";
1895 print "DES_ENC =$target{des_obj}\n";
1896 print "AES_ENC =$target{aes_obj}\n";
1897 print "BF_ENC =$target{bf_obj}\n";
1898 print "CAST_ENC =$target{cast_obj}\n";
1899 print "RC4_ENC =$target{rc4_obj}\n";
1900 print "RC5_ENC =$target{rc5_obj}\n";
1901 print "MD5_OBJ_ASM =$target{md5_obj}\n";
1902 print "SHA1_OBJ_ASM =$target{sha1_obj}\n";
1903 print "RMD160_OBJ_ASM=$target{rmd160_obj}\n";
1904 print "CMLL_ENC =$target{cmll_obj}\n";
1905 print "MODES_OBJ =$target{modes_obj}\n";
1906 print "PADLOCK_OBJ =$target{padlock_obj}\n";
1907 print "CHACHA_ENC =$target{chacha_obj}\n";
1908 print "POLY1305_OBJ =$target{poly1305_obj}\n";
1909 print "BLAKE2_OBJ =$target{blake2_obj}\n";
1910 print "PROCESSOR =$config{processor}\n";
1911 print "RANLIB =", $target{ranlib} eq '$(CROSS_COMPILE)ranlib' ?
1912 "$config{cross_compile_prefix}ranlib" :
1913 "$target{ranlib}", "\n";
1914 print "ARFLAGS =$target{arflags}\n";
1915 print "PERL =$config{perl}\n";
1917 print "SIXTY_FOUR_BIT_LONG mode\n" if $config{b64l};
1918 print "SIXTY_FOUR_BIT mode\n" if $config{b64};
1919 print "THIRTY_TWO_BIT mode\n" if $config{b32};
1920 print "BN_LLONG mode\n" if $config{bn_ll};
1921 print "RC4 uses $config{rc4_int}\n" if $config{rc4_int} ne $def_int;
1923 for (@generated_headers) {
1924 mkpath(catdir($blddir, dirname($_)));
1925 run_dofile(catfile($blddir, $_),
1926 catfile($srcdir, $_.".in"));
1930 ### When the old "unixmake" scheme goes away, so does this function
1932 sub build_Makefile {
1933 run_dofile("Makefile","Makefile.in");
1935 # Copy all Makefile.in to Makefile (except top-level)
1944 return if ($_ ne "Makefile.in" || $File::Find::dir eq ".");
1945 my $in = IO::File->new($_, "r") or
1946 die sprintf "Error reading Makefile.in in %s: !$\n",
1948 my $out = IO::File->new("Makefile", "w") or
1949 die sprintf "Error writing Makefile in %s: !$\n",
1951 print $out "# Generated from $_, do not edit\n";
1952 while (my $line = <$in>) { print $out $line }
1954 die sprintf "Error reading Makefile.in in %s: !$\n",
1957 die sprintf "Error writing Makefile in %s: !$\n",
1966 run_dofile(catfile($blddir, $target{build_file}),
1967 $config{build_file_template},
1968 catfile($srcdir, "Configurations", "common.tmpl"));
1976 $builders{$builder}->($builder_platform, @builder_opts);
1980 Configured for $target.
1983 print <<"EOF" if ($disabled{threads} eq "unavailable");
1985 The library could not be configured for supporting multi-threaded
1986 applications as the compiler options required on this system are not known.
1987 See file INSTALL for details if you need multi-threading.
1990 print <<"EOF" if ($no_shared_warn);
1992 The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this
1993 platform, so we will pretend you gave the option 'no-pic', which also disables
1994 'shared' and 'dynamic-engine'. If you know how to implement shared libraries
1995 or position independent code, please let us know (but please first make sure
1996 you have tried with a current version of OpenSSL).
1999 print <<"EOF" if (-f catfile($srcdir, "configdata.pm") && $srcdir ne $blddir);
2001 WARNING: there are indications that another build was made in the source
2002 directory. This build may have picked up artifacts from that build, the
2003 safest course of action is to clean the source directory and redo this
2009 ######################################################################
2011 # Helpers and utility functions
2014 # Configuration file reading #########################################
2016 # Note: All of the helper functions are for lazy evaluation. They all
2017 # return a CODE ref, which will return the intended value when evaluated.
2018 # Thus, whenever there's mention of a returned value, it's about that
2021 # Helper function to implement conditional inheritance depending on the
2022 # value of $disabled{asm}. Used in inherit_from values as follows:
2024 # inherit_from => [ "template", asm("asm_tmpl") ]
2029 $disabled{asm} ? () : @x;
2033 # Helper function to implement conditional value variants, with a default
2034 # plus additional values based on the value of $config{build_type}.
2035 # Arguments are given in hash table form:
2037 # picker(default => "Basic string: ",
2039 # release => "release")
2041 # When configuring with --debug, the resulting string will be
2042 # "Basic string: debug", and when not, it will be "Basic string: release"
2044 # This can be used to create variants of sets of flags according to the
2047 # cflags => picker(default => "-Wall",
2048 # debug => "-g -O0",
2053 return sub { add($opts{default} || (),
2054 $opts{$config{build_type}} || ())->(); }
2057 # Helper function to combine several values of different types into one.
2058 # This is useful if you want to combine a string with the result of a
2059 # lazy function, such as:
2061 # cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" })
2065 return sub { add(@stuff)->(); }
2068 # Helper function to implement conditional values depending on the value
2069 # of $disabled{threads}. Can be used as follows:
2071 # cflags => combine("-Wall", threads("-pthread"))
2075 return sub { add($disabled{threads} ? () : @flags)->(); }
2080 our $add_called = 0;
2081 # Helper function to implement adding values to already existing configuration
2082 # values. It handles elements that are ARRAYs, CODEs and scalars
2084 my $separator = shift;
2086 # If there's any ARRAY in the collection of values OR the separator
2087 # is undef, we will return an ARRAY of combined values, otherwise a
2088 # string of joined values with $separator as the separator.
2089 my $found_array = !defined($separator);
2094 while (ref($res) eq "CODE") {
2097 if (defined($res)) {
2098 if (ref($res) eq "ARRAY") {
2114 join($separator, grep { defined($_) && $_ ne "" } @values);
2118 my $separator = " ";
2119 if (ref($_[$#_]) eq "HASH") {
2121 $separator = $opts->{separator};
2124 sub { _add($separator, @x, @_) };
2127 my $separator = " ";
2128 if (ref($_[$#_]) eq "HASH") {
2130 $separator = $opts->{separator};
2133 sub { _add($separator, @_, @x) };
2136 # configuration reader, evaluates the input file as a perl script and expects
2137 # it to fill %targets with target configurations. Those are then added to
2141 open(CONFFILE, "< $fname")
2142 or die "Can't open configuration file '$fname'!\n";
2145 my $content = <CONFFILE>;
2150 local %table = %::table; # Protect %table from tampering
2156 # For each target, check that it's configured with a hash table.
2157 foreach (keys %targets) {
2158 if (ref($targets{$_}) ne "HASH") {
2159 if (ref($targets{$_}) eq "") {
2160 warn "Deprecated target configuration for $_, ignoring...\n";
2162 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n";
2164 delete $targets{$_};
2168 %table = (%table, %targets);
2172 # configuration resolver. Will only resolve all the lazy evaluation
2173 # codeblocks for the chosen target and all those it inherits from,
2175 sub resolve_config {
2177 my @breadcrumbs = @_;
2179 # my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS});
2181 if (grep { $_ eq $target } @breadcrumbs) {
2182 die "inherit_from loop! target backtrace:\n "
2183 ,$target,"\n ",join("\n ", @breadcrumbs),"\n";
2186 if (!defined($table{$target})) {
2187 warn "Warning! target $target doesn't exist!\n";
2190 # Recurse through all inheritances. They will be resolved on the
2191 # fly, so when this operation is done, they will all just be a
2192 # bunch of attributes with string values.
2193 # What we get here, though, are keys with references to lists of
2194 # the combined values of them all. We will deal with lists after
2195 # this stage is done.
2196 my %combined_inheritance = ();
2197 if ($table{$target}->{inherit_from}) {
2199 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}};
2200 foreach (@inherit_from) {
2201 my %inherited_config = resolve_config($_, $target, @breadcrumbs);
2203 # 'template' is a marker that's considered private to
2204 # the config that had it.
2205 delete $inherited_config{template};
2207 foreach (keys %inherited_config) {
2208 if (!$combined_inheritance{$_}) {
2209 $combined_inheritance{$_} = [];
2211 push @{$combined_inheritance{$_}}, $inherited_config{$_};
2216 # We won't need inherit_from in this target any more, since we've
2217 # resolved all the inheritances that lead to this
2218 delete $table{$target}->{inherit_from};
2220 # Now is the time to deal with those lists. Here's the place to
2221 # decide what shall be done with those lists, all based on the
2222 # values of the target we're currently dealing with.
2223 # - If a value is a coderef, it will be executed with the list of
2224 # inherited values as arguments.
2225 # - If the corresponding key doesn't have a value at all or is the
2226 # empty string, the inherited value list will be run through the
2227 # default combiner (below), and the result becomes this target's
2229 # - Otherwise, this target's value is assumed to be a string that
2230 # will simply override the inherited list of values.
2231 my $default_combiner = add();
2234 map { $_ => 1 } (keys %combined_inheritance,
2235 keys %{$table{$target}});
2237 sub process_values {
2239 my $inherited = shift; # Always a [ list ]
2245 while(ref($object) eq "CODE") {
2246 $object = $object->(@$inherited);
2248 if (!defined($object)) {
2251 elsif (ref($object) eq "ARRAY") {
2252 local $add_called; # To make sure recursive calls don't affect it
2253 return [ map { process_values($_, $inherited, $target, $entry) }
2255 } elsif (ref($object) eq "") {
2258 die "cannot handle reference type ",ref($object)
2259 ," found in target ",$target," -> ",$entry,"\n";
2263 foreach (sort keys %all_keys) {
2264 my $previous = $combined_inheritance{$_};
2266 # Current target doesn't have a value for the current key?
2267 # Assign it the default combiner, the rest of this loop body
2268 # will handle it just like any other coderef.
2269 if (!exists $table{$target}->{$_}) {
2270 $table{$target}->{$_} = $default_combiner;
2273 $table{$target}->{$_} = process_values($table{$target}->{$_},
2274 $combined_inheritance{$_},
2276 unless(defined($table{$target}->{$_})) {
2277 delete $table{$target}->{$_};
2279 # if ($extra_checks &&
2280 # $previous && !($add_called || $previous ~~ $table{$target}->{$_})) {
2281 # warn "$_ got replaced in $target\n";
2285 # Finally done, return the result.
2286 return %{$table{$target}};
2291 print STDERR $usage;
2292 print STDERR "\npick os/compiler from:\n";
2296 foreach $i (sort keys %table)
2298 next if $table{$i}->{template};
2299 next if $i =~ /^debug/;
2300 $k += length($i) + 1;
2306 print STDERR $i . " ";
2308 foreach $i (sort keys %table)
2310 next if $table{$i}->{template};
2311 next if $i !~ /^debug/;
2312 $k += length($i) + 1;
2318 print STDERR $i . " ";
2320 print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
2329 unlink $out || warn "Can't remove $out, $!"
2331 foreach (@templates) {
2332 die "Can't open $_, $!" unless -f $_;
2334 my $cmd = "$config{perl} \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\"";
2335 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n";
2338 rename("$out.new", $out) || die "Can't rename $out.new, $!";
2345 if (eval { require IPC::Cmd; 1; }) {
2347 return scalar IPC::Cmd::can_run($name);
2349 # if there is $directories component in splitpath,
2350 # then it's not something to test with $PATH...
2351 return $name if (File::Spec->splitpath($name))[1];
2353 foreach (File::Spec->path()) {
2354 my $fullpath = catfile($_, "$name$target{exe_extension}");
2355 if (-f $fullpath and -x $fullpath) {
2362 # Configuration printer ##############################################
2364 sub print_table_entry
2367 my %target = resolve_config($target);
2370 # Don't print the templates
2371 return if $target{template};
2408 "shared_extension_simple",
2409 "shared_import_extension",
2420 if ($type eq "TABLE") {
2422 print "*** $target\n";
2423 foreach (@sequence) {
2424 if (ref($target{$_}) eq "ARRAY") {
2425 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}});
2427 printf "\$%-12s = %s\n", $_, $target{$_};
2430 } elsif ($type eq "HASH") {
2432 length((sort { length($a) <=> length($b) } @sequence)[-1]);
2433 print " '$target' => {\n";
2434 foreach (@sequence) {
2436 if (ref($target{$_}) eq "ARRAY") {
2437 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n";
2439 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n";
2447 # Utility routines ###################################################
2449 # On VMS, if the given file is a logical name, File::Spec::Functions
2450 # will consider it an absolute path. There are cases when we want a
2451 # purely syntactic check without checking the environment.
2455 # On non-platforms, we just use file_name_is_absolute().
2456 return file_name_is_absolute($file) unless $^O eq "VMS";
2458 # If the file spec includes a device or a directpry spec,
2459 # file_name_is_absolute() is perfectly safe.
2460 return file_name_is_absolute($file) if $file =~ m|[:\[]|;
2462 # Here, we know the given file spec isn't absolute
2466 # Makes a directory absolute and cleans out /../ in paths like foo/../bar
2467 # On some platforms, this uses rel2abs(), while on others, realpath() is used.
2468 # realpath() requires that at least all path components except the last is an
2469 # existing directory. On VMS, the last component of the directory spec must
2474 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which
2475 # will return the volume name for the device, no matter what. Also,
2476 # it will return an incorrect directory spec if the argument is a
2477 # directory that doesn't exist.
2479 return rel2abs($dir);
2482 # We use realpath() on Unix, since no other will properly clean out
2484 use Cwd qw/realpath/;
2486 return realpath($dir);
2491 perl => sub { my $x = shift;
2492 $x =~ s/([\\\$\@"])/\\$1/g;
2493 return '"'.$x.'"'; },
2497 defined($processors{$for}) ? $processors{$for} : sub { shift; };
2499 return map { $processor->($_); } @_;
2502 # collect_from_file($filename, $line_concat_cond_re, $line_concat)
2503 # $filename is a file name to read from
2504 # $line_concat_cond_re is a regexp detecting a line continuation ending
2505 # $line_concat is a CODEref that takes care of concatenating two lines
2506 sub collect_from_file {
2507 my $filename = shift;
2508 my $line_concat_cond_re = shift;
2509 my $line_concat = shift;
2511 open my $fh, $filename || die "unable to read $filename: $!\n";
2513 my $saved_line = "";
2517 if (defined $line_concat) {
2518 $_ = $line_concat->($saved_line, $_);
2521 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2527 die "$filename ending with continuation line\n" if $_;
2533 # collect_from_array($array, $line_concat_cond_re, $line_concat)
2534 # $array is an ARRAYref of lines
2535 # $line_concat_cond_re is a regexp detecting a line continuation ending
2536 # $line_concat is a CODEref that takes care of concatenating two lines
2537 sub collect_from_array {
2539 my $line_concat_cond_re = shift;
2540 my $line_concat = shift;
2541 my @array = (@$array);
2544 my $saved_line = "";
2546 while (defined($_ = shift @array)) {
2548 if (defined $line_concat) {
2549 $_ = $line_concat->($saved_line, $_);
2552 if (defined $line_concat_cond_re && /$line_concat_cond_re/) {
2558 die "input text ending with continuation line\n" if $_;
2563 # collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...)
2564 # $lineiterator is a CODEref that delivers one line at a time.
2565 # All following arguments are regex/CODEref pairs, where the regexp detects a
2566 # line and the CODEref does something with the result of the regexp.
2567 sub collect_information {
2568 my $lineiterator = shift;
2569 my %collectors = @_;
2571 while(defined($_ = $lineiterator->())) {
2574 if ($collectors{"BEFORE"}) {
2575 $collectors{"BEFORE"}->($_);
2577 foreach my $re (keys %collectors) {
2578 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) {
2579 $collectors{$re}->($lineiterator);
2583 if ($collectors{"OTHERWISE"}) {
2584 $collectors{"OTHERWISE"}->($lineiterator, $_)
2585 unless $found || !defined $collectors{"OTHERWISE"};
2587 if ($collectors{"AFTER"}) {
2588 $collectors{"AFTER"}->($_);
2594 # $line is a line of text to split up into tokens
2595 # returns a list of tokens
2597 # Tokens are divided by spaces. If the tokens include spaces, they
2598 # have to be quoted with single or double quotes. Double quotes
2599 # inside a double quoted token must be escaped. Escaping is done
2601 # Basically, the same quoting rules apply for " and ' as in any
2604 my $line = my $debug_line = shift;
2607 while ($line =~ s|^\s+||, $line ne "") {
2609 while ($line ne "" && $line !~ m|^\s|) {
2610 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) {
2613 } elsif ($line =~ m/^'([^']*)'/) {
2616 } elsif ($line =~ m/^(\S+)/) {
2621 push @result, $token;
2624 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) {
2625 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n";
2626 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n";