1#! /usr/bin/env perl 2# -*- mode: perl; -*- 3# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. 4# 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 9 10## Configure -- OpenSSL source tree configuration script 11 12use 5.10.0; 13use strict; 14use Config; 15use FindBin; 16use lib "$FindBin::Bin/util/perl"; 17use File::Basename; 18use File::Spec::Functions qw/:DEFAULT abs2rel rel2abs/; 19use File::Path qw/mkpath/; 20use OpenSSL::Glob; 21 22# see INSTALL for instructions. 23 24my $orig_death_handler = $SIG{__DIE__}; 25$SIG{__DIE__} = \&death_handler; 26 27my $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-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n"; 28 29# Options: 30# 31# --config add the given configuration file, which will be read after 32# any "Configurations*" files that are found in the same 33# directory as this script. 34# --prefix prefix for the OpenSSL installation, which includes the 35# directories bin, lib, include, share/man, share/doc/openssl 36# This becomes the value of INSTALLTOP in Makefile 37# (Default: /usr/local) 38# --openssldir OpenSSL data area, such as openssl.cnf, certificates and keys. 39# If it's a relative directory, it will be added on the directory 40# given with --prefix. 41# This becomes the value of OPENSSLDIR in Makefile and in C. 42# (Default: PREFIX/ssl) 43# 44# --cross-compile-prefix Add specified prefix to binutils components. 45# 46# --api One of 0.9.8, 1.0.0 or 1.1.0. Do not compile support for 47# interfaces deprecated as of the specified OpenSSL version. 48# 49# no-hw-xxx do not compile support for specific crypto hardware. 50# Generic OpenSSL-style methods relating to this support 51# are always compiled but return NULL if the hardware 52# support isn't compiled. 53# no-hw do not compile support for any crypto hardware. 54# [no-]threads [don't] try to create a library that is suitable for 55# multithreaded applications (default is "threads" if we 56# know how to do it) 57# [no-]shared [don't] try to create shared libraries when supported. 58# [no-]pic [don't] try to build position independent code when supported. 59# If disabled, it also disables shared and dynamic-engine. 60# no-asm do not use assembler 61# no-egd do not compile support for the entropy-gathering daemon APIs 62# [no-]zlib [don't] compile support for zlib compression. 63# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared 64# library and will be loaded in run-time by the OpenSSL library. 65# sctp include SCTP support 66# enable-weak-ssl-ciphers 67# Enable weak ciphers that are disabled by default. 68# 386 generate 80386 code in assembly modules 69# no-sse2 disables IA-32 SSE2 code in assembly modules, the above 70# mentioned '386' option implies this one 71# no-<cipher> build without specified algorithm (rsa, idea, rc5, ...) 72# -<xxx> +<xxx> All options which are unknown to the 'Configure' script are 73# /<xxx> passed through to the compiler. Unix-style options beginning 74# with a '-' or '+' are recognized, as well as Windows-style 75# options beginning with a '/'. If the option contains arguments 76# separated by spaces, then the URL-style notation %20 can be 77# used for the space character in order to avoid having to quote 78# the option. For example, -opt%20arg gets expanded to -opt arg. 79# In fact, any ASCII character can be encoded as %xx using its 80# hexadecimal encoding. 81# -static while -static is also a pass-through compiler option (and 82# as such is limited to environments where it's actually 83# meaningful), it triggers a number configuration options, 84# namely no-pic, no-shared and no-threads. It is 85# argued that the only reason to produce statically linked 86# binaries (and in context it means executables linked with 87# -static flag, and not just executables linked with static 88# libcrypto.a) is to eliminate dependency on specific run-time, 89# a.k.a. libc version. The mentioned config options are meant 90# to achieve just that. Unfortunately on Linux it's impossible 91# to eliminate the dependency completely for openssl executable 92# because of getaddrinfo and gethostbyname calls, which can 93# invoke dynamically loadable library facility anyway to meet 94# the lookup requests. For this reason on Linux statically 95# linked openssl executable has rather debugging value than 96# production quality. 97# 98# BN_LLONG use the type 'long long' in crypto/bn/bn.h 99# RC4_CHAR use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h 100# Following are set automatically by this script 101# 102# MD5_ASM use some extra md5 assembler, 103# SHA1_ASM use some extra sha1 assembler, must define L_ENDIAN for x86 104# RMD160_ASM use some extra ripemd160 assembler, 105# SHA256_ASM sha256_block is implemented in assembler 106# SHA512_ASM sha512_block is implemented in assembler 107# AES_ASM AES_[en|de]crypt is implemented in assembler 108 109# Minimum warning options... any contributions to OpenSSL should at least 110# get past these. Note that we only use these with C compilers, not with 111# C++ compilers. 112 113# DEBUG_UNUSED enables __owur (warn unused result) checks. 114# -DPEDANTIC complements -pedantic and is meant to mask code that 115# is not strictly standard-compliant and/or implementation-specific, 116# e.g. inline assembly, disregards to alignment requirements, such 117# that -pedantic would complain about. Incidentally -DPEDANTIC has 118# to be used even in sanitized builds, because sanitizer too is 119# supposed to and does take notice of non-standard behaviour. Then 120# -pedantic with pre-C9x compiler would also complain about 'long 121# long' not being supported. As 64-bit algorithms are common now, 122# it grew impossible to resolve this without sizeable additional 123# code, so we just tell compiler to be pedantic about everything 124# but 'long long' type. 125 126my @gcc_devteam_warn = qw( 127 -DDEBUG_UNUSED 128 -DPEDANTIC -pedantic -Wno-long-long 129 -Wall 130 -Wextra 131 -Wno-unused-parameter 132 -Wno-missing-field-initializers 133 -Wswitch 134 -Wsign-compare 135 -Wshadow 136 -Wformat 137 -Wtype-limits 138 -Wundef 139 -Werror 140 -Wmissing-prototypes 141 -Wstrict-prototypes 142); 143 144# These are used in addition to $gcc_devteam_warn when the compiler is clang. 145# TODO(openssl-team): fix problems and investigate if (at least) the 146# following warnings can also be enabled: 147# -Wcast-align 148# -Wunreachable-code -- no, too ugly/compiler-specific 149# -Wlanguage-extension-token -- no, we use asm() 150# -Wunused-macros -- no, too tricky for BN and _XOPEN_SOURCE etc 151# -Wextended-offsetof -- no, needed in CMS ASN1 code 152my @clang_devteam_warn = qw( 153 -Wno-unknown-warning-option 154 -Wswitch-default 155 -Wno-parentheses-equality 156 -Wno-language-extension-token 157 -Wno-extended-offsetof 158 -Wconditional-uninitialized 159 -Wincompatible-pointer-types-discards-qualifiers 160 -Wmissing-variable-declarations 161); 162 163my @cl_devteam_warn = qw( 164 /WX 165); 166 167# This adds backtrace information to the memory leak info. Is only used 168# when crypto-mdebug-backtrace is enabled. 169my $memleak_devteam_backtrace = "-rdynamic"; 170 171my $strict_warnings = 0; 172 173# As for $BSDthreads. Idea is to maintain "collective" set of flags, 174# which would cover all BSD flavors. -pthread applies to them all, 175# but is treated differently. OpenBSD expands is as -D_POSIX_THREAD 176# -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r, 177# which has to be accompanied by explicit -D_THREAD_SAFE and 178# sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which 179# seems to be sufficient? 180our $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT"; 181 182# 183# API compatibility name to version number mapping. 184# 185my $maxapi = "1.1.0"; # API for "no-deprecated" builds 186my $apitable = { 187 "1.1.0" => "0x10100000L", 188 "1.0.0" => "0x10000000L", 189 "0.9.8" => "0x00908000L", 190}; 191 192our %table = (); 193our %config = (); 194our %withargs = (); 195our $now_printing; # set to current entry's name in print_table_entry 196 # (todo: right thing would be to encapsulate name 197 # into %target [class] and make print_table_entry 198 # a method) 199 200# Forward declarations ############################################### 201 202# read_config(filename) 203# 204# Reads a configuration file and populates %table with the contents 205# (which the configuration file places in %targets). 206sub read_config; 207 208# resolve_config(target) 209# 210# Resolves all the late evaluations, inheritances and so on for the 211# chosen target and any target it inherits from. 212sub resolve_config; 213 214 215# Information collection ############################################# 216 217# Unified build supports separate build dir 218my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax 219my $blddir = catdir(absolutedir(".")); # catdir ensures local syntax 220 221# File::Spec::Unix doesn't detect case insensitivity, so we make sure to 222# check if the source and build directory are really the same, and make 223# them so. This avoids all kinds of confusion later on. 224# We must check @File::Spec::ISA rather than using File::Spec->isa() to 225# know if File::Spec ended up loading File::Spec::Unix. 226$srcdir = $blddir 227 if (grep(/::Unix$/, @File::Spec::ISA) 228 && samedir($srcdir, $blddir)); 229 230my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl")); 231 232my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR'; 233 234$config{sourcedir} = abs2rel($srcdir, $blddir); 235$config{builddir} = abs2rel($blddir, $blddir); 236 237# Collect reconfiguration information if needed 238my @argvcopy=@ARGV; 239 240if (grep /^reconf(igure)?$/, @argvcopy) { 241 die "reconfiguring with other arguments present isn't supported" 242 if scalar @argvcopy > 1; 243 if (-f "./configdata.pm") { 244 my $file = "./configdata.pm"; 245 unless (my $return = do $file) { 246 die "couldn't parse $file: $@" if $@; 247 die "couldn't do $file: $!" unless defined $return; 248 die "couldn't run $file" unless $return; 249 } 250 251 @argvcopy = defined($configdata::config{perlargv}) ? 252 @{$configdata::config{perlargv}} : (); 253 die "Incorrect data to reconfigure, please do a normal configuration\n" 254 if (grep(/^reconf/,@argvcopy)); 255 $config{perlenv} = $configdata::config{perlenv} // {}; 256 } else { 257 die "Insufficient data to reconfigure, please do a normal configuration\n"; 258 } 259} 260 261$config{perlargv} = [ @argvcopy ]; 262 263# Collect version numbers 264$config{version} = "unknown"; 265$config{version_num} = "unknown"; 266$config{shlib_version_number} = "unknown"; 267$config{shlib_version_history} = "unknown"; 268 269collect_information( 270 collect_from_file(catfile($srcdir,'include/openssl/opensslv.h')), 271 qr/OPENSSL.VERSION.TEXT.*OpenSSL (\S+) / => sub { $config{version} = $1; }, 272 qr/OPENSSL.VERSION.NUMBER.*(0x\S+)/ => sub { $config{version_num}=$1 }, 273 qr/SHLIB_VERSION_NUMBER *"([^"]+)"/ => sub { $config{shlib_version_number}=$1 }, 274 qr/SHLIB_VERSION_HISTORY *"([^"]*)"/ => sub { $config{shlib_version_history}=$1 } 275 ); 276if ($config{shlib_version_history} ne "") { $config{shlib_version_history} .= ":"; } 277 278($config{major}, $config{minor}) 279 = ($config{version} =~ /^([0-9]+)\.([0-9\.]+)/); 280($config{shlib_major}, $config{shlib_minor}) 281 = ($config{shlib_version_number} =~ /^([0-9]+)\.([0-9\.]+)/); 282die "erroneous version information in opensslv.h: ", 283 "$config{major}, $config{minor}, $config{shlib_major}, $config{shlib_minor}\n" 284 if ($config{major} eq "" || $config{minor} eq "" 285 || $config{shlib_major} eq "" || $config{shlib_minor} eq ""); 286 287# Collect target configurations 288 289my $pattern = catfile(dirname($0), "Configurations", "*.conf"); 290foreach (sort glob($pattern)) { 291 &read_config($_); 292} 293 294if (defined env($local_config_envname)) { 295 if ($^O eq 'VMS') { 296 # VMS environment variables are logical names, 297 # which can be used as is 298 $pattern = $local_config_envname . ':' . '*.conf'; 299 } else { 300 $pattern = catfile(env($local_config_envname), '*.conf'); 301 } 302 303 foreach (sort glob($pattern)) { 304 &read_config($_); 305 } 306} 307 308# Save away perl command information 309$config{perl_cmd} = $^X; 310$config{perl_version} = $Config{version}; 311$config{perl_archname} = $Config{archname}; 312 313$config{prefix}=""; 314$config{openssldir}=""; 315$config{processor}=""; 316$config{libdir}=""; 317my $auto_threads=1; # enable threads automatically? true by default 318my $default_ranlib; 319 320# Top level directories to build 321$config{dirs} = [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ]; 322# crypto/ subdirectories to build 323$config{sdirs} = [ 324 "objects", 325 "md2", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "siphash", "sm3", 326 "des", "aes", "rc2", "rc4", "rc5", "idea", "aria", "bf", "cast", "camellia", "seed", "sm4", "chacha", "modes", 327 "bn", "ec", "rsa", "dsa", "dh", "sm2", "dso", "engine", 328 "buffer", "bio", "stack", "lhash", "rand", "err", 329 "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", 330 "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "store" 331 ]; 332# test/ subdirectories to build 333$config{tdirs} = [ "ossl_shim" ]; 334 335# Known TLS and DTLS protocols 336my @tls = qw(ssl3 tls1 tls1_1 tls1_2 tls1_3); 337my @dtls = qw(dtls1 dtls1_2); 338 339# Explicitly known options that are possible to disable. They can 340# be regexps, and will be used like this: /^no-${option}$/ 341# For developers: keep it sorted alphabetically 342 343my @disablables = ( 344 "afalgeng", 345 "aria", 346 "asan", 347 "asm", 348 "async", 349 "autoalginit", 350 "autoerrinit", 351 "autoload-config", 352 "bf", 353 "blake2", 354 "buildtest-c\\+\\+", 355 "camellia", 356 "capieng", 357 "cast", 358 "chacha", 359 "cmac", 360 "cms", 361 "comp", 362 "crypto-mdebug", 363 "crypto-mdebug-backtrace", 364 "ct", 365 "deprecated", 366 "des", 367 "devcryptoeng", 368 "dgram", 369 "dh", 370 "dsa", 371 "dso", 372 "dtls", 373 "dynamic-engine", 374 "ec", 375 "ec2m", 376 "ecdh", 377 "ecdsa", 378 "ec_nistp_64_gcc_128", 379 "egd", 380 "engine", 381 "err", 382 "external-tests", 383 "filenames", 384 "fuzz-libfuzzer", 385 "fuzz-afl", 386 "gost", 387 "heartbeats", 388 "hw(-.+)?", 389 "idea", 390 "ktls", 391 "makedepend", 392 "md2", 393 "md4", 394 "mdc2", 395 "msan", 396 "multiblock", 397 "nextprotoneg", 398 "pinshared", 399 "ocb", 400 "ocsp", 401 "pic", 402 "poly1305", 403 "posix-io", 404 "psk", 405 "rc2", 406 "rc4", 407 "rc5", 408 "rdrand", 409 "rfc3779", 410 "rmd160", 411 "scrypt", 412 "sctp", 413 "seed", 414 "shared", 415 "siphash", 416 "sm2", 417 "sm3", 418 "sm4", 419 "sock", 420 "srp", 421 "srtp", 422 "sse2", 423 "ssl", 424 "ssl-trace", 425 "static-engine", 426 "stdio", 427 "tests", 428 "threads", 429 "tls", 430 "ts", 431 "ubsan", 432 "ui-console", 433 "unit-test", 434 "whirlpool", 435 "weak-ssl-ciphers", 436 "zlib", 437 "zlib-dynamic", 438 ); 439foreach my $proto ((@tls, @dtls)) 440 { 441 push(@disablables, $proto); 442 push(@disablables, "$proto-method") unless $proto eq "tls1_3"; 443 } 444 445my %deprecated_disablables = ( 446 "ssl2" => undef, 447 "buf-freelists" => undef, 448 "ripemd" => "rmd160", 449 "ui" => "ui-console", 450 ); 451 452# All of the following are disabled by default: 453 454our %disabled = ( # "what" => "comment" 455 "asan" => "default", 456 "buildtest-c++" => "default", 457 "crypto-mdebug" => "default", 458 "crypto-mdebug-backtrace" => "default", 459 "devcryptoeng" => "default", 460 "ec_nistp_64_gcc_128" => "default", 461 "egd" => "default", 462 "external-tests" => "default", 463 "fuzz-libfuzzer" => "default", 464 "fuzz-afl" => "default", 465 "heartbeats" => "default", 466 "md2" => "default", 467 "msan" => "default", 468 "rc5" => "default", 469 "sctp" => "default", 470 "ssl-trace" => "default", 471 "ssl3" => "default", 472 "ssl3-method" => "default", 473 "ubsan" => "default", 474 "unit-test" => "default", 475 "weak-ssl-ciphers" => "default", 476 "zlib" => "default", 477 "zlib-dynamic" => "default", 478 "ktls" => "default", 479 ); 480 481# Note: => pair form used for aesthetics, not to truly make a hash table 482my @disable_cascades = ( 483 # "what" => [ "cascade", ... ] 484 sub { $config{processor} eq "386" } 485 => [ "sse2" ], 486 "ssl" => [ "ssl3" ], 487 "ssl3-method" => [ "ssl3" ], 488 "zlib" => [ "zlib-dynamic" ], 489 "des" => [ "mdc2" ], 490 "ec" => [ "ecdsa", "ecdh" ], 491 492 "dgram" => [ "dtls", "sctp" ], 493 "sock" => [ "dgram" ], 494 "dtls" => [ @dtls ], 495 sub { 0 == scalar grep { !$disabled{$_} } @dtls } 496 => [ "dtls" ], 497 498 "tls" => [ @tls ], 499 sub { 0 == scalar grep { !$disabled{$_} } @tls } 500 => [ "tls" ], 501 502 "crypto-mdebug" => [ "crypto-mdebug-backtrace" ], 503 504 # Without position independent code, there can be no shared libraries or DSOs 505 "pic" => [ "shared" ], 506 "shared" => [ "dynamic-engine" ], 507 "dso" => [ "dynamic-engine" ], 508 "engine" => [ "afalgeng", "devcryptoeng" ], 509 510 # no-autoalginit is only useful when building non-shared 511 "autoalginit" => [ "shared", "apps" ], 512 513 "stdio" => [ "apps", "capieng", "egd" ], 514 "apps" => [ "tests" ], 515 "tests" => [ "external-tests" ], 516 "comp" => [ "zlib" ], 517 "ec" => [ "tls1_3", "sm2" ], 518 "sm3" => [ "sm2" ], 519 sub { !$disabled{"unit-test"} } => [ "heartbeats" ], 520 521 sub { !$disabled{"msan"} } => [ "asm" ], 522 ); 523 524# Avoid protocol support holes. Also disable all versions below N, if version 525# N is disabled while N+1 is enabled. 526# 527my @list = (reverse @tls); 528while ((my $first, my $second) = (shift @list, shift @list)) { 529 last unless @list; 530 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} } 531 => [ @list ] ); 532 unshift @list, $second; 533} 534my @list = (reverse @dtls); 535while ((my $first, my $second) = (shift @list, shift @list)) { 536 last unless @list; 537 push @disable_cascades, ( sub { !$disabled{$first} && $disabled{$second} } 538 => [ @list ] ); 539 unshift @list, $second; 540} 541 542# Explicit "no-..." options will be collected in %disabled along with the defaults. 543# To remove something from %disabled, use "enable-foo". 544# For symmetry, "disable-foo" is a synonym for "no-foo". 545 546&usage if ($#ARGV < 0); 547 548# For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with 549# platform specific list separators. Users from those platforms should 550# recognise those separators from how you set up the PATH to find executables. 551# The default is the Unix like separator, :, but as an exception, we also 552# support the space as separator. 553my $list_separator_re = 554 { VMS => qr/(?<!\^),/, 555 MSWin32 => qr/(?<!\\);/ } -> {$^O} // qr/(?<!\\)[:\s]/; 556# All the "make variables" we support 557# Some get pre-populated for the sake of backward compatibility 558# (we supported those before the change to "make variable" support. 559my %user = ( 560 AR => env('AR'), 561 ARFLAGS => [], 562 AS => undef, 563 ASFLAGS => [], 564 CC => env('CC'), 565 CFLAGS => [ env('CFLAGS') || () ], 566 CXX => env('CXX'), 567 CXXFLAGS => [ env('CXXFLAGS') || () ], 568 CPP => undef, 569 CPPFLAGS => [ env('CPPFLAGS') || () ], # -D, -I, -Wp, 570 CPPDEFINES => [], # Alternative for -D 571 CPPINCLUDES => [], # Alternative for -I 572 CROSS_COMPILE => env('CROSS_COMPILE'), 573 HASHBANGPERL=> env('HASHBANGPERL') || env('PERL'), 574 LD => undef, 575 LDFLAGS => [ env('LDFLAGS') || () ], # -L, -Wl, 576 LDLIBS => [ env('LDLIBS') || () ], # -l 577 MT => undef, 578 MTFLAGS => [], 579 PERL => env('PERL') || ($^O ne "VMS" ? $^X : "perl"), 580 RANLIB => env('RANLIB'), 581 RC => env('RC') || env('WINDRES'), 582 RCFLAGS => [ env('RCFLAGS') || () ], 583 RM => undef, 584 ); 585# Info about what "make variables" may be prefixed with the cross compiler 586# prefix. This should NEVER mention any such variable with a list for value. 587my @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC ); 588# The same but for flags given as Configure options. These are *additional* 589# input, as opposed to the VAR=string option that override the corresponding 590# config target attributes 591my %useradd = ( 592 CPPDEFINES => [], 593 CPPINCLUDES => [], 594 CPPFLAGS => [], 595 CFLAGS => [], 596 CXXFLAGS => [], 597 LDFLAGS => [], 598 LDLIBS => [], 599 RCFLAGS => [], 600 ); 601 602my %user_synonyms = ( 603 HASHBANGPERL=> 'PERL', 604 RC => 'WINDRES', 605 ); 606 607# Some target attributes have been renamed, this is the translation table 608my %target_attr_translate =( 609 ar => 'AR', 610 as => 'AS', 611 cc => 'CC', 612 cxx => 'CXX', 613 cpp => 'CPP', 614 hashbangperl => 'HASHBANGPERL', 615 ld => 'LD', 616 mt => 'MT', 617 ranlib => 'RANLIB', 618 rc => 'RC', 619 rm => 'RM', 620 ); 621 622# Initialisers coming from 'config' scripts 623$config{defines} = [ split(/$list_separator_re/, env('__CNF_CPPDEFINES')) ]; 624$config{includes} = [ split(/$list_separator_re/, env('__CNF_CPPINCLUDES')) ]; 625$config{cppflags} = [ env('__CNF_CPPFLAGS') || () ]; 626$config{cflags} = [ env('__CNF_CFLAGS') || () ]; 627$config{cxxflags} = [ env('__CNF_CXXFLAGS') || () ]; 628$config{lflags} = [ env('__CNF_LDFLAGS') || () ]; 629$config{ex_libs} = [ env('__CNF_LDLIBS') || () ]; 630 631$config{openssl_api_defines}=[]; 632$config{openssl_algorithm_defines}=[]; 633$config{openssl_thread_defines}=[]; 634$config{openssl_sys_defines}=[]; 635$config{openssl_other_defines}=[]; 636$config{options}=""; 637$config{build_type} = "release"; 638my $target=""; 639 640my %cmdvars = (); # Stores FOO='blah' type arguments 641my %unsupported_options = (); 642my %deprecated_options = (); 643# If you change this, update apps/version.c 644my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom); 645my @seed_sources = (); 646while (@argvcopy) 647 { 648 $_ = shift @argvcopy; 649 650 # Support env variable assignments among the options 651 if (m|^(\w+)=(.+)?$|) 652 { 653 $cmdvars{$1} = $2; 654 # Every time a variable is given as a configuration argument, 655 # it acts as a reset if the variable. 656 if (exists $user{$1}) 657 { 658 $user{$1} = ref $user{$1} eq "ARRAY" ? [] : undef; 659 } 660 #if (exists $useradd{$1}) 661 # { 662 # $useradd{$1} = []; 663 # } 664 next; 665 } 666 667 # VMS is a case insensitive environment, and depending on settings 668 # out of our control, we may receive options uppercased. Let's 669 # downcase at least the part before any equal sign. 670 if ($^O eq "VMS") 671 { 672 s/^([^=]*)/lc($1)/e; 673 } 674 675 # some people just can't read the instructions, clang people have to... 676 s/^-no-(?!integrated-as)/no-/; 677 678 # rewrite some options in "enable-..." form 679 s /^-?-?shared$/enable-shared/; 680 s /^sctp$/enable-sctp/; 681 s /^threads$/enable-threads/; 682 s /^zlib$/enable-zlib/; 683 s /^zlib-dynamic$/enable-zlib-dynamic/; 684 685 if (/^(no|disable|enable)-(.+)$/) 686 { 687 my $word = $2; 688 if (!exists $deprecated_disablables{$word} 689 && !grep { $word =~ /^${_}$/ } @disablables) 690 { 691 $unsupported_options{$_} = 1; 692 next; 693 } 694 } 695 if (/^no-(.+)$/ || /^disable-(.+)$/) 696 { 697 foreach my $proto ((@tls, @dtls)) 698 { 699 if ($1 eq "$proto-method") 700 { 701 $disabled{"$proto"} = "option($proto-method)"; 702 last; 703 } 704 } 705 if ($1 eq "dtls") 706 { 707 foreach my $proto (@dtls) 708 { 709 $disabled{$proto} = "option(dtls)"; 710 } 711 $disabled{"dtls"} = "option(dtls)"; 712 } 713 elsif ($1 eq "ssl") 714 { 715 # Last one of its kind 716 $disabled{"ssl3"} = "option(ssl)"; 717 } 718 elsif ($1 eq "tls") 719 { 720 # XXX: Tests will fail if all SSL/TLS 721 # protocols are disabled. 722 foreach my $proto (@tls) 723 { 724 $disabled{$proto} = "option(tls)"; 725 } 726 } 727 elsif ($1 eq "static-engine") 728 { 729 delete $disabled{"dynamic-engine"}; 730 } 731 elsif ($1 eq "dynamic-engine") 732 { 733 $disabled{"dynamic-engine"} = "option"; 734 } 735 elsif (exists $deprecated_disablables{$1}) 736 { 737 if ($deprecated_disablables{$1} ne "") 738 { 739 $deprecated_options{$_} = 1; 740 if (defined $deprecated_disablables{$1}) 741 { 742 $disabled{$deprecated_disablables{$1}} = "option"; 743 } 744 } 745 } 746 else 747 { 748 $disabled{$1} = "option"; 749 } 750 # No longer an automatic choice 751 $auto_threads = 0 if ($1 eq "threads"); 752 } 753 elsif (/^enable-(.+)$/) 754 { 755 if ($1 eq "static-engine") 756 { 757 $disabled{"dynamic-engine"} = "option"; 758 } 759 elsif ($1 eq "dynamic-engine") 760 { 761 delete $disabled{"dynamic-engine"}; 762 } 763 elsif ($1 eq "zlib-dynamic") 764 { 765 delete $disabled{"zlib"}; 766 } 767 my $algo = $1; 768 delete $disabled{$algo}; 769 770 # No longer an automatic choice 771 $auto_threads = 0 if ($1 eq "threads"); 772 } 773 elsif (/^--strict-warnings$/) 774 { 775 # Pretend that our strict flags is a C flag, and replace it 776 # with the proper flags later on 777 push @{$useradd{CFLAGS}}, '--ossl-strict-warnings'; 778 $strict_warnings=1; 779 } 780 elsif (/^--debug$/) 781 { 782 $config{build_type} = "debug"; 783 } 784 elsif (/^--release$/) 785 { 786 $config{build_type} = "release"; 787 } 788 elsif (/^386$/) 789 { $config{processor}=386; } 790 elsif (/^fips$/) 791 { 792 die "FIPS mode not supported\n"; 793 } 794 elsif (/^rsaref$/) 795 { 796 # No RSAref support any more since it's not needed. 797 # The check for the option is there so scripts aren't 798 # broken 799 } 800 elsif (/^nofipscanistercheck$/) 801 { 802 die "FIPS mode not supported\n"; 803 } 804 elsif (m|^[-+/]|) 805 { 806 if (/^--prefix=(.*)$/) 807 { 808 $config{prefix}=$1; 809 die "Directory given with --prefix MUST be absolute\n" 810 unless file_name_is_absolute($config{prefix}); 811 } 812 elsif (/^--api=(.*)$/) 813 { 814 $config{api}=$1; 815 } 816 elsif (/^--libdir=(.*)$/) 817 { 818 $config{libdir}=$1; 819 } 820 elsif (/^--openssldir=(.*)$/) 821 { 822 $config{openssldir}=$1; 823 } 824 elsif (/^--with-zlib-lib=(.*)$/) 825 { 826 $withargs{zlib_lib}=$1; 827 } 828 elsif (/^--with-zlib-include=(.*)$/) 829 { 830 $withargs{zlib_include}=$1; 831 } 832 elsif (/^--with-fuzzer-lib=(.*)$/) 833 { 834 $withargs{fuzzer_lib}=$1; 835 } 836 elsif (/^--with-fuzzer-include=(.*)$/) 837 { 838 $withargs{fuzzer_include}=$1; 839 } 840 elsif (/^--with-rand-seed=(.*)$/) 841 { 842 foreach my $x (split(m|,|, $1)) 843 { 844 die "Unknown --with-rand-seed choice $x\n" 845 if ! grep { $x eq $_ } @known_seed_sources; 846 push @seed_sources, $x; 847 } 848 } 849 elsif (/^--cross-compile-prefix=(.*)$/) 850 { 851 $user{CROSS_COMPILE}=$1; 852 } 853 elsif (/^--config=(.*)$/) 854 { 855 read_config $1; 856 } 857 elsif (/^-l(.*)$/) 858 { 859 push @{$useradd{LDLIBS}}, $_; 860 } 861 elsif (/^-framework$/) 862 { 863 push @{$useradd{LDLIBS}}, $_, shift(@argvcopy); 864 } 865 elsif (/^-L(.*)$/ or /^-Wl,/) 866 { 867 push @{$useradd{LDFLAGS}}, $_; 868 } 869 elsif (/^-rpath$/ or /^-R$/) 870 # -rpath is the OSF1 rpath flag 871 # -R is the old Solaris rpath flag 872 { 873 my $rpath = shift(@argvcopy) || ""; 874 $rpath .= " " if $rpath ne ""; 875 push @{$useradd{LDFLAGS}}, $_, $rpath; 876 } 877 elsif (/^-static$/) 878 { 879 push @{$useradd{LDFLAGS}}, $_; 880 } 881 elsif (m|^[-/]D(.*)$|) 882 { 883 push @{$useradd{CPPDEFINES}}, $1; 884 } 885 elsif (m|^[-/]I(.*)$|) 886 { 887 push @{$useradd{CPPINCLUDES}}, $1; 888 } 889 elsif (/^-Wp,$/) 890 { 891 push @{$useradd{CPPFLAGS}}, $1; 892 } 893 else # common if (/^[-+]/), just pass down... 894 { 895 # Treat %xx as an ASCII code (e.g. replace %20 by a space character). 896 # This provides a simple way to pass options with arguments separated 897 # by spaces without quoting (e.g. -opt%20arg translates to -opt arg). 898 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei; 899 push @{$useradd{CFLAGS}}, $_; 900 push @{$useradd{CXXFLAGS}}, $_; 901 } 902 } 903 elsif (m|^/|) 904 { 905 # Treat %xx as an ASCII code (e.g. replace %20 by a space character). 906 # This provides a simple way to pass options with arguments separated 907 # by spaces without quoting (e.g. /opt%20arg translates to /opt arg). 908 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei; 909 push @{$useradd{CFLAGS}}, $_; 910 push @{$useradd{CXXFLAGS}}, $_; 911 } 912 else 913 { 914 die "target already defined - $target (offending arg: $_)\n" if ($target ne ""); 915 $target=$_; 916 } 917 unless ($_ eq $target || /^no-/ || /^disable-/) 918 { 919 # "no-..." follows later after implied deactivations 920 # have been derived. (Don't take this too seriously, 921 # we really only write OPTIONS to the Makefile out of 922 # nostalgia.) 923 924 if ($config{options} eq "") 925 { $config{options} = $_; } 926 else 927 { $config{options} .= " ".$_; } 928 } 929 } 930 931if (defined($config{api}) && !exists $apitable->{$config{api}}) { 932 die "***** Unsupported api compatibility level: $config{api}\n", 933} 934 935if (keys %deprecated_options) 936 { 937 warn "***** Deprecated options: ", 938 join(", ", keys %deprecated_options), "\n"; 939 } 940if (keys %unsupported_options) 941 { 942 die "***** Unsupported options: ", 943 join(", ", keys %unsupported_options), "\n"; 944 } 945 946# If any %useradd entry has been set, we must check that the "make 947# variables" haven't been set. We start by checking of any %useradd entry 948# is set. 949if (grep { scalar @$_ > 0 } values %useradd) { 950 # Hash of env / make variables names. The possible values are: 951 # 1 - "make vars" 952 # 2 - %useradd entry set 953 # 3 - both set 954 my %detected_vars = 955 map { my $v = 0; 956 $v += 1 if $cmdvars{$_}; 957 $v += 2 if @{$useradd{$_}}; 958 $_ => $v } 959 keys %useradd; 960 961 # If any of the corresponding "make variables" is set, we error 962 if (grep { $_ & 1 } values %detected_vars) { 963 my $names = join(', ', grep { $detected_vars{$_} > 0 } 964 sort keys %detected_vars); 965 die <<"_____"; 966***** Mixing make variables and additional compiler/linker flags as 967***** configure command line option is not permitted. 968***** Affected make variables: $names 969_____ 970 } 971} 972 973# Check through all supported command line variables to see if any of them 974# were set, and canonicalise the values we got. If no compiler or linker 975# flag or anything else that affects %useradd was set, we also check the 976# environment for values. 977my $anyuseradd = 978 grep { defined $_ && (ref $_ ne 'ARRAY' || @$_) } values %useradd; 979foreach (keys %user) { 980 my $value = $cmdvars{$_}; 981 $value //= env($_) unless $anyuseradd; 982 $value //= 983 defined $user_synonyms{$_} ? $cmdvars{$user_synonyms{$_}} : undef; 984 $value //= defined $user_synonyms{$_} ? env($user_synonyms{$_}) : undef 985 unless $anyuseradd; 986 987 if (defined $value) { 988 if (ref $user{$_} eq 'ARRAY') { 989 if ($_ eq 'CPPDEFINES' || $_ eq 'CPPINCLUDES') { 990 $user{$_} = [ split /$list_separator_re/, $value ]; 991 } else { 992 $user{$_} = [ $value ]; 993 } 994 } elsif (!defined $user{$_}) { 995 $user{$_} = $value; 996 } 997 } 998} 999 1000if (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ()) 1001 && !$disabled{shared} 1002 && !($disabled{asan} && $disabled{msan} && $disabled{ubsan})) { 1003 die "***** Cannot simultaneously use -rpath, shared libraries, and\n", 1004 "***** any of asan, msan or ubsan\n"; 1005} 1006 1007sub disable { 1008 my $disable_type = shift; 1009 1010 for (@_) { 1011 $disabled{$_} = $disable_type; 1012 } 1013 1014 my @tocheckfor = (@_ ? @_ : keys %disabled); 1015 while (@tocheckfor) { 1016 my %new_tocheckfor = (); 1017 my @cascade_copy = (@disable_cascades); 1018 while (@cascade_copy) { 1019 my ($test, $descendents) = 1020 (shift @cascade_copy, shift @cascade_copy); 1021 if (ref($test) eq "CODE" ? $test->() : defined($disabled{$test})) { 1022 foreach (grep { !defined($disabled{$_}) } @$descendents) { 1023 $new_tocheckfor{$_} = 1; $disabled{$_} = "cascade"; 1024 } 1025 } 1026 } 1027 @tocheckfor = (keys %new_tocheckfor); 1028 } 1029} 1030disable(); # First cascade run 1031 1032our $die = sub { die @_; }; 1033if ($target eq "TABLE") { 1034 local $die = sub { warn @_; }; 1035 foreach (sort keys %table) { 1036 print_table_entry($_, "TABLE"); 1037 } 1038 exit 0; 1039} 1040 1041if ($target eq "LIST") { 1042 foreach (sort keys %table) { 1043 print $_,"\n" unless $table{$_}->{template}; 1044 } 1045 exit 0; 1046} 1047 1048if ($target eq "HASH") { 1049 local $die = sub { warn @_; }; 1050 print "%table = (\n"; 1051 foreach (sort keys %table) { 1052 print_table_entry($_, "HASH"); 1053 } 1054 exit 0; 1055} 1056 1057print "Configuring OpenSSL version $config{version} ($config{version_num}) "; 1058print "for $target\n"; 1059 1060if (scalar(@seed_sources) == 0) { 1061 print "Using os-specific seed configuration\n"; 1062 push @seed_sources, 'os'; 1063} 1064if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) { 1065 delete $disabled{'egd'}; 1066} 1067if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) { 1068 die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1; 1069 warn <<_____ if scalar(@seed_sources) == 1; 1070 1071============================== WARNING =============================== 1072You have selected the --with-rand-seed=none option, which effectively 1073disables automatic reseeding of the OpenSSL random generator. 1074All operations depending on the random generator such as creating keys 1075will not work unless the random generator is seeded manually by the 1076application. 1077 1078Please read the 'Note on random number generation' section in the 1079INSTALL instructions and the RAND_DRBG(7) manual page for more details. 1080============================== WARNING =============================== 1081 1082_____ 1083} 1084push @{$config{openssl_other_defines}}, 1085 map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" } 1086 @seed_sources; 1087 1088# Backward compatibility? 1089if ($target =~ m/^CygWin32(-.*)$/) { 1090 $target = "Cygwin".$1; 1091} 1092 1093# Support for legacy targets having a name starting with 'debug-' 1094my ($d, $t) = $target =~ m/^(debug-)?(.*)$/; 1095if ($d) { 1096 $config{build_type} = "debug"; 1097 1098 # If we do not find debug-foo in the table, the target is set to foo. 1099 if (!$table{$target}) { 1100 $target = $t; 1101 } 1102} 1103 1104&usage if !$table{$target} || $table{$target}->{template}; 1105 1106$config{target} = $target; 1107my %target = resolve_config($target); 1108 1109foreach (keys %target_attr_translate) { 1110 $target{$target_attr_translate{$_}} = $target{$_} 1111 if $target{$_}; 1112 delete $target{$_}; 1113} 1114 1115%target = ( %{$table{DEFAULTS}}, %target ); 1116 1117my %conf_files = map { $_ => 1 } (@{$target{_conf_fname_int}}); 1118$config{conf_files} = [ sort keys %conf_files ]; 1119 1120# Using sub disable within these loops may prove fragile, so we run 1121# a cascade afterwards 1122foreach my $feature (@{$target{disable}}) { 1123 if (exists $deprecated_disablables{$feature}) { 1124 warn "***** config $target disables deprecated feature $feature\n"; 1125 } elsif (!grep { $feature eq $_ } @disablables) { 1126 die "***** config $target disables unknown feature $feature\n"; 1127 } 1128 $disabled{$feature} = 'config'; 1129} 1130foreach my $feature (@{$target{enable}}) { 1131 if ("default" eq ($disabled{$feature} // "")) { 1132 if (exists $deprecated_disablables{$feature}) { 1133 warn "***** config $target enables deprecated feature $feature\n"; 1134 } elsif (!grep { $feature eq $_ } @disablables) { 1135 die "***** config $target enables unknown feature $feature\n"; 1136 } 1137 delete $disabled{$feature}; 1138 } 1139} 1140disable(); # Run a cascade now 1141 1142$target{CXXFLAGS}//=$target{CFLAGS} if $target{CXX}; 1143$target{cxxflags}//=$target{cflags} if $target{CXX}; 1144$target{exe_extension}=""; 1145$target{exe_extension}=".exe" if ($config{target} eq "DJGPP" 1146 || $config{target} =~ /^(?:Cygwin|mingw)/); 1147$target{exe_extension}=".pm" if ($config{target} =~ /vos/); 1148 1149($target{shared_extension_simple}=$target{shared_extension}) 1150 =~ s|\.\$\(SHLIB_VERSION_NUMBER\)|| 1151 unless defined($target{shared_extension_simple}); 1152$target{dso_extension}//=$target{shared_extension_simple}; 1153($target{shared_import_extension}=$target{shared_extension_simple}.".a") 1154 if ($config{target} =~ /^(?:Cygwin|mingw)/); 1155 1156# Fill %config with values from %user, and in case those are undefined or 1157# empty, use values from %target (acting as a default). 1158foreach (keys %user) { 1159 my $ref_type = ref $user{$_}; 1160 1161 # Temporary function. Takes an intended ref type (empty string or "ARRAY") 1162 # and a value that's to be coerced into that type. 1163 my $mkvalue = sub { 1164 my $type = shift; 1165 my $value = shift; 1166 my $undef_p = shift; 1167 1168 die "Too many arguments for \$mkvalue" if @_; 1169 1170 while (ref $value eq 'CODE') { 1171 $value = $value->(); 1172 } 1173 1174 if ($type eq 'ARRAY') { 1175 return undef unless defined $value; 1176 return undef if ref $value ne 'ARRAY' && !$value; 1177 return undef if ref $value eq 'ARRAY' && !@$value; 1178 return [ $value ] unless ref $value eq 'ARRAY'; 1179 } 1180 return undef unless $value; 1181 return $value; 1182 }; 1183 1184 $config{$_} = 1185 $mkvalue->($ref_type, $user{$_}) 1186 || $mkvalue->($ref_type, $target{$_}); 1187 delete $config{$_} unless defined $config{$_}; 1188} 1189 1190# Finish up %config by appending things the user gave us on the command line 1191# apart from "make variables" 1192foreach (keys %useradd) { 1193 # The must all be lists, so we assert that here 1194 die "internal error: \$useradd{$_} isn't an ARRAY\n" 1195 unless ref $useradd{$_} eq 'ARRAY'; 1196 1197 if (defined $config{$_}) { 1198 push @{$config{$_}}, @{$useradd{$_}}; 1199 } else { 1200 $config{$_} = [ @{$useradd{$_}} ]; 1201 } 1202} 1203# At this point, we can forget everything about %user and %useradd, 1204# because it's now all been merged into the corresponding $config entry 1205 1206if (grep { $_ eq '-static' } @{$config{LDFLAGS}}) { 1207 disable('static', 'pic', 'threads'); 1208} 1209 1210# Allow overriding the build file name 1211$config{build_file} = env('BUILDFILE') || $target{build_file} || "Makefile"; 1212 1213# Make sure build_scheme is consistent. 1214$target{build_scheme} = [ $target{build_scheme} ] 1215 if ref($target{build_scheme}) ne "ARRAY"; 1216 1217my ($builder, $builder_platform, @builder_opts) = 1218 @{$target{build_scheme}}; 1219 1220foreach my $checker (($builder_platform."-".$config{build_file}."-checker.pm", 1221 $builder_platform."-checker.pm")) { 1222 my $checker_path = catfile($srcdir, "Configurations", $checker); 1223 if (-f $checker_path) { 1224 my $fn = $ENV{CONFIGURE_CHECKER_WARN} 1225 ? sub { warn $@; } : sub { die $@; }; 1226 if (! do $checker_path) { 1227 if ($@) { 1228 $fn->($@); 1229 } elsif ($!) { 1230 $fn->($!); 1231 } else { 1232 $fn->("The detected tools didn't match the platform\n"); 1233 } 1234 } 1235 last; 1236 } 1237} 1238 1239push @{$config{defines}}, "NDEBUG" if $config{build_type} eq "release"; 1240 1241if ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m) 1242 { 1243 push @{$config{cflags}}, "-mno-cygwin"; 1244 push @{$config{cxxflags}}, "-mno-cygwin" if $config{CXX}; 1245 push @{$config{shared_ldflag}}, "-mno-cygwin"; 1246 } 1247 1248if ($target =~ /linux.*-mips/ && !$disabled{asm} 1249 && !grep { $_ !~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) { 1250 # minimally required architecture flags for assembly modules 1251 my $value; 1252 $value = '-mips2' if ($target =~ /mips32/); 1253 $value = '-mips3' if ($target =~ /mips64/); 1254 unshift @{$config{cflags}}, $value; 1255 unshift @{$config{cxxflags}}, $value if $config{CXX}; 1256} 1257 1258# If threads aren't disabled, check how possible they are 1259unless ($disabled{threads}) { 1260 if ($auto_threads) { 1261 # Enabled by default, disable it forcibly if unavailable 1262 if ($target{thread_scheme} eq "(unknown)") { 1263 disable("unavailable", 'threads'); 1264 } 1265 } else { 1266 # The user chose to enable threads explicitly, let's see 1267 # if there's a chance that's possible 1268 if ($target{thread_scheme} eq "(unknown)") { 1269 # If the user asked for "threads" and we don't have internal 1270 # knowledge how to do it, [s]he is expected to provide any 1271 # system-dependent compiler options that are necessary. We 1272 # can't truly check that the given options are correct, but 1273 # we expect the user to know what [s]He is doing. 1274 if (!@{$config{CFLAGS}} && !@{$config{CPPDEFINES}}) { 1275 die "You asked for multi-threading support, but didn't\n" 1276 ,"provide any system-specific compiler options\n"; 1277 } 1278 } 1279 } 1280} 1281 1282# If threads still aren't disabled, add a C macro to ensure the source 1283# code knows about it. Any other flag is taken care of by the configs. 1284unless($disabled{threads}) { 1285 push @{$config{openssl_thread_defines}}, "OPENSSL_THREADS"; 1286} 1287 1288# With "deprecated" disable all deprecated features. 1289if (defined($disabled{"deprecated"})) { 1290 $config{api} = $maxapi; 1291} 1292 1293my $no_shared_warn=0; 1294if ($target{shared_target} eq "") 1295 { 1296 $no_shared_warn = 1 1297 if (!$disabled{shared} || !$disabled{"dynamic-engine"}); 1298 disable('no-shared-target', 'pic'); 1299 } 1300 1301if ($disabled{"dynamic-engine"}) { 1302 $config{dynamic_engines} = 0; 1303} else { 1304 $config{dynamic_engines} = 1; 1305} 1306 1307unless ($disabled{asan}) { 1308 push @{$config{cflags}}, "-fsanitize=address"; 1309 push @{$config{cxxflags}}, "-fsanitize=address" if $config{CXX}; 1310} 1311 1312unless ($disabled{ubsan}) { 1313 # -DPEDANTIC or -fnosanitize=alignment may also be required on some 1314 # platforms. 1315 push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all"; 1316 push @{$config{cxxflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all" if $config{CXX}; 1317} 1318 1319unless ($disabled{msan}) { 1320 push @{$config{cflags}}, "-fsanitize=memory"; 1321 push @{$config{cxxflags}}, "-fsanitize=memory" if $config{CXX}; 1322} 1323 1324unless ($disabled{"fuzz-libfuzzer"} && $disabled{"fuzz-afl"} 1325 && $disabled{asan} && $disabled{ubsan} && $disabled{msan}) { 1326 push @{$config{cflags}}, "-fno-omit-frame-pointer", "-g"; 1327 push @{$config{cxxflags}}, "-fno-omit-frame-pointer", "-g" if $config{CXX}; 1328} 1329# 1330# Platform fix-ups 1331# 1332 1333# This saves the build files from having to check 1334if ($disabled{pic}) 1335 { 1336 foreach (qw(shared_cflag shared_cxxflag shared_cppflag 1337 shared_defines shared_includes shared_ldflag 1338 module_cflags module_cxxflags module_cppflags 1339 module_defines module_includes module_lflags)) 1340 { 1341 delete $config{$_}; 1342 $target{$_} = ""; 1343 } 1344 } 1345else 1346 { 1347 push @{$config{lib_defines}}, "OPENSSL_PIC"; 1348 } 1349 1350if ($target{sys_id} ne "") 1351 { 1352 push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}"; 1353 } 1354 1355unless ($disabled{asm}) { 1356 $target{cpuid_asm_src}=$table{DEFAULTS}->{cpuid_asm_src} if ($config{processor} eq "386"); 1357 push @{$config{lib_defines}}, "OPENSSL_CPUID_OBJ" if ($target{cpuid_asm_src} ne "mem_clr.c"); 1358 1359 $target{bn_asm_src} =~ s/\w+-gf2m.c// if (defined($disabled{ec2m})); 1360 1361 # bn-586 is the only one implementing bn_*_part_words 1362 push @{$config{lib_defines}}, "OPENSSL_BN_ASM_PART_WORDS" if ($target{bn_asm_src} =~ /bn-586/); 1363 push @{$config{lib_defines}}, "OPENSSL_IA32_SSE2" if (!$disabled{sse2} && $target{bn_asm_src} =~ /86/); 1364 1365 push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT" if ($target{bn_asm_src} =~ /-mont/); 1366 push @{$config{lib_defines}}, "OPENSSL_BN_ASM_MONT5" if ($target{bn_asm_src} =~ /-mont5/); 1367 push @{$config{lib_defines}}, "OPENSSL_BN_ASM_GF2m" if ($target{bn_asm_src} =~ /-gf2m/); 1368 push @{$config{lib_defines}}, "BN_DIV3W" if ($target{bn_asm_src} =~ /-div3w/); 1369 1370 if ($target{sha1_asm_src}) { 1371 push @{$config{lib_defines}}, "SHA1_ASM" if ($target{sha1_asm_src} =~ /sx86/ || $target{sha1_asm_src} =~ /sha1/); 1372 push @{$config{lib_defines}}, "SHA256_ASM" if ($target{sha1_asm_src} =~ /sha256/); 1373 push @{$config{lib_defines}}, "SHA512_ASM" if ($target{sha1_asm_src} =~ /sha512/); 1374 } 1375 if ($target{keccak1600_asm_src} ne $table{DEFAULTS}->{keccak1600_asm_src}) { 1376 push @{$config{lib_defines}}, "KECCAK1600_ASM"; 1377 } 1378 if ($target{rc4_asm_src} ne $table{DEFAULTS}->{rc4_asm_src}) { 1379 push @{$config{lib_defines}}, "RC4_ASM"; 1380 } 1381 if ($target{md5_asm_src}) { 1382 push @{$config{lib_defines}}, "MD5_ASM"; 1383 } 1384 $target{cast_asm_src}=$table{DEFAULTS}->{cast_asm_src} unless $disabled{pic}; # CAST assembler is not PIC 1385 if ($target{rmd160_asm_src}) { 1386 push @{$config{lib_defines}}, "RMD160_ASM"; 1387 } 1388 if ($target{aes_asm_src}) { 1389 push @{$config{lib_defines}}, "AES_ASM" if ($target{aes_asm_src} =~ m/\baes-/);; 1390 push @{$config{lib_defines}}, "AESNI_ASM" if ($target{aes_asm_src} =~ m/\baesni-/);; 1391 # aes-ctr.fake is not a real file, only indication that assembler 1392 # module implements AES_ctr32_encrypt... 1393 push @{$config{lib_defines}}, "AES_CTR_ASM" if ($target{aes_asm_src} =~ s/\s*aes-ctr\.fake//); 1394 # aes-xts.fake indicates presence of AES_xts_[en|de]crypt... 1395 push @{$config{lib_defines}}, "AES_XTS_ASM" if ($target{aes_asm_src} =~ s/\s*aes-xts\.fake//); 1396 $target{aes_asm_src} =~ s/\s*(vpaes|aesni)-x86\.s//g if ($disabled{sse2}); 1397 push @{$config{lib_defines}}, "VPAES_ASM" if ($target{aes_asm_src} =~ m/vpaes/); 1398 push @{$config{lib_defines}}, "BSAES_ASM" if ($target{aes_asm_src} =~ m/bsaes/); 1399 } 1400 if ($target{wp_asm_src} =~ /mmx/) { 1401 if ($config{processor} eq "386") { 1402 $target{wp_asm_src}=$table{DEFAULTS}->{wp_asm_src}; 1403 } elsif (!$disabled{"whirlpool"}) { 1404 push @{$config{lib_defines}}, "WHIRLPOOL_ASM"; 1405 } 1406 } 1407 if ($target{modes_asm_src} =~ /ghash-/) { 1408 push @{$config{lib_defines}}, "GHASH_ASM"; 1409 } 1410 if ($target{ec_asm_src} =~ /ecp_nistz256/) { 1411 push @{$config{lib_defines}}, "ECP_NISTZ256_ASM"; 1412 } 1413 if ($target{ec_asm_src} =~ /x25519/) { 1414 push @{$config{lib_defines}}, "X25519_ASM"; 1415 } 1416 if ($target{padlock_asm_src} ne $table{DEFAULTS}->{padlock_asm_src}) { 1417 push @{$config{dso_defines}}, "PADLOCK_ASM"; 1418 } 1419 if ($target{poly1305_asm_src} ne "") { 1420 push @{$config{lib_defines}}, "POLY1305_ASM"; 1421 } 1422} 1423 1424my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC}); 1425my %predefined_CXX = $config{CXX} 1426 ? compiler_predefined($config{CROSS_COMPILE}.$config{CXX}) 1427 : (); 1428 1429# Check for makedepend capabilities. 1430if (!$disabled{makedepend}) { 1431 if ($config{target} =~ /^(VC|vms)-/) { 1432 # For VC- and vms- targets, there's nothing more to do here. The 1433 # functionality is hard coded in the corresponding build files for 1434 # cl (Windows) and CC/DECC (VMS). 1435 } elsif (($predefined_C{__GNUC__} // -1) >= 3 1436 && !($predefined_C{__APPLE_CC__} && !$predefined_C{__clang__})) { 1437 # We know that GNU C version 3 and up as well as all clang 1438 # versions support dependency generation, but Xcode did not 1439 # handle $cc -M before clang support (but claims __GNUC__ = 3) 1440 $config{makedepprog} = "\$(CROSS_COMPILE)$config{CC}"; 1441 } else { 1442 # In all other cases, we look for 'makedepend', and disable the 1443 # capability if not found. 1444 $config{makedepprog} = which('makedepend'); 1445 disable('unavailable', 'makedepend') unless $config{makedepprog}; 1446 } 1447} 1448 1449if (!$disabled{asm} && !$predefined_C{__MACH__} && $^O ne 'VMS') { 1450 # probe for -Wa,--noexecstack option... 1451 if ($predefined_C{__clang__}) { 1452 # clang has builtin assembler, which doesn't recognize --help, 1453 # but it apparently recognizes the option in question on all 1454 # supported platforms even when it's meaningless. In other words 1455 # probe would fail, but probed option always accepted... 1456 push @{$config{cflags}}, "-Wa,--noexecstack", "-Qunused-arguments"; 1457 } else { 1458 my $cc = $config{CROSS_COMPILE}.$config{CC}; 1459 open(PIPE, "$cc -Wa,--help -c -o null.$$.o -x assembler /dev/null 2>&1 |"); 1460 while(<PIPE>) { 1461 if (m/--noexecstack/) { 1462 push @{$config{cflags}}, "-Wa,--noexecstack"; 1463 last; 1464 } 1465 } 1466 close(PIPE); 1467 unlink("null.$$.o"); 1468 } 1469} 1470 1471# Deal with bn_ops ################################################### 1472 1473$config{bn_ll} =0; 1474$config{export_var_as_fn} =0; 1475my $def_int="unsigned int"; 1476$config{rc4_int} =$def_int; 1477($config{b64l},$config{b64},$config{b32})=(0,0,1); 1478 1479my $count = 0; 1480foreach (sort split(/\s+/,$target{bn_ops})) { 1481 $count++ if /SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT/; 1482 $config{export_var_as_fn}=1 if $_ eq 'EXPORT_VAR_AS_FN'; 1483 $config{bn_ll}=1 if $_ eq 'BN_LLONG'; 1484 $config{rc4_int}="unsigned char" if $_ eq 'RC4_CHAR'; 1485 ($config{b64l},$config{b64},$config{b32}) 1486 =(0,1,0) if $_ eq 'SIXTY_FOUR_BIT'; 1487 ($config{b64l},$config{b64},$config{b32}) 1488 =(1,0,0) if $_ eq 'SIXTY_FOUR_BIT_LONG'; 1489 ($config{b64l},$config{b64},$config{b32}) 1490 =(0,0,1) if $_ eq 'THIRTY_TWO_BIT'; 1491} 1492die "Exactly one of SIXTY_FOUR_BIT|SIXTY_FOUR_BIT_LONG|THIRTY_TWO_BIT can be set in bn_ops\n" 1493 if $count > 1; 1494 1495 1496# Hack cflags for better warnings (dev option) ####################### 1497 1498# "Stringify" the C and C++ flags string. This permits it to be made part of 1499# a string and works as well on command lines. 1500$config{cflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } 1501 @{$config{cflags}} ]; 1502$config{cxxflags} = [ map { (my $x = $_) =~ s/([\\\"])/\\$1/g; $x } 1503 @{$config{cxxflags}} ] if $config{CXX}; 1504 1505if (defined($config{api})) { 1506 $config{openssl_api_defines} = [ "OPENSSL_MIN_API=".$apitable->{$config{api}} ]; 1507 my $apiflag = sprintf("OPENSSL_API_COMPAT=%s", $apitable->{$config{api}}); 1508 push @{$config{defines}}, $apiflag; 1509} 1510 1511my @strict_warnings_collection=(); 1512if ($strict_warnings) 1513 { 1514 my $wopt; 1515 my $gccver = $predefined_C{__GNUC__} // -1; 1516 1517 if ($gccver >= 4) 1518 { 1519 push @strict_warnings_collection, @gcc_devteam_warn; 1520 push @strict_warnings_collection, @clang_devteam_warn 1521 if (defined($predefined_C{__clang__})); 1522 } 1523 elsif ($config{target} =~ /^VC-/) 1524 { 1525 push @strict_warnings_collection, @cl_devteam_warn; 1526 } 1527 else 1528 { 1529 warn "WARNING --strict-warnings requires gcc[>=4] or gcc-alike, or MSVC" 1530 } 1531 } 1532 1533$config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings' 1534 ? @strict_warnings_collection 1535 : ( $_ ) } 1536 @{$config{CFLAGS}} ]; 1537 1538unless ($disabled{"crypto-mdebug-backtrace"}) 1539 { 1540 foreach my $wopt (split /\s+/, $memleak_devteam_backtrace) 1541 { 1542 push @{$config{cflags}}, $wopt 1543 unless grep { $_ eq $wopt } @{$config{cflags}}; 1544 } 1545 if ($target =~ /^BSD-/) 1546 { 1547 push @{$config{ex_libs}}, "-lexecinfo"; 1548 } 1549 } 1550 1551unless ($disabled{afalgeng}) { 1552 $config{afalgeng}=""; 1553 if (grep { $_ eq 'afalgeng' } @{$target{enable}}) { 1554 my $minver = 4*10000 + 1*100 + 0; 1555 if ($config{CROSS_COMPILE} eq "") { 1556 my $verstr = `uname -r`; 1557 my ($ma, $mi1, $mi2) = split("\\.", $verstr); 1558 ($mi2) = $mi2 =~ /(\d+)/; 1559 my $ver = $ma*10000 + $mi1*100 + $mi2; 1560 if ($ver < $minver) { 1561 disable('too-old-kernel', 'afalgeng'); 1562 } else { 1563 push @{$config{engdirs}}, "afalg"; 1564 } 1565 } else { 1566 disable('cross-compiling', 'afalgeng'); 1567 } 1568 } else { 1569 disable('not-linux', 'afalgeng'); 1570 } 1571} 1572 1573unless ($disabled{devcryptoeng}) { 1574 if ($target =~ m/^BSD/) { 1575 my $maxver = 5*100 + 7; 1576 my $sysstr = `uname -s`; 1577 my $verstr = `uname -r`; 1578 $sysstr =~ s|\R$||; 1579 $verstr =~ s|\R$||; 1580 my ($ma, $mi, @rest) = split m|\.|, $verstr; 1581 my $ver = $ma*100 + $mi; 1582 if ($sysstr eq 'OpenBSD' && $ver >= $maxver) { 1583 disable('too-new-kernel', 'devcryptoeng'); 1584 } 1585 } 1586} 1587 1588unless ($disabled{ktls}) { 1589 $config{ktls}=""; 1590 if ($target =~ m/^linux/) { 1591 my $usr = "/usr/$config{cross_compile_prefix}"; 1592 chop($usr); 1593 if ($config{cross_compile_prefix} eq "") { 1594 $usr = "/usr"; 1595 } 1596 my $minver = (4 << 16) + (13 << 8) + 0; 1597 my @verstr = split(" ",`cat $usr/include/linux/version.h | grep LINUX_VERSION_CODE`); 1598 1599 if ($verstr[2] < $minver) { 1600 disable('too-old-kernel', 'ktls'); 1601 } 1602 } elsif ($target =~ m/^BSD/) { 1603 my $cc = $config{CROSS_COMPILE}.$config{CC}; 1604 system("printf '#include <sys/types.h>\n#include <sys/ktls.h>' | $cc -E - >/dev/null 2>&1"); 1605 if ($? != 0) { 1606 disable('too-old-freebsd', 'ktls'); 1607 } 1608 } else { 1609 disable('not-linux-or-freebsd', 'ktls'); 1610 } 1611} 1612 1613push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls}); 1614 1615# Get the extra flags used when building shared libraries and modules. We 1616# do this late because some of them depend on %disabled. 1617 1618# Make the flags to build DSOs the same as for shared libraries unless they 1619# are already defined 1620$target{module_cflags} = $target{shared_cflag} unless defined $target{module_cflags}; 1621$target{module_cxxflags} = $target{shared_cxxflag} unless defined $target{module_cxxflags}; 1622$target{module_ldflags} = $target{shared_ldflag} unless defined $target{module_ldflags}; 1623{ 1624 my $shared_info_pl = 1625 catfile(dirname($0), "Configurations", "shared-info.pl"); 1626 my %shared_info = read_eval_file($shared_info_pl); 1627 push @{$target{_conf_fname_int}}, $shared_info_pl; 1628 my $si = $target{shared_target}; 1629 while (ref $si ne "HASH") { 1630 last if ! defined $si; 1631 if (ref $si eq "CODE") { 1632 $si = $si->(); 1633 } else { 1634 $si = $shared_info{$si}; 1635 } 1636 } 1637 1638 # Some of the 'shared_target' values don't have any entries in 1639 # %shared_info. That's perfectly fine, AS LONG AS the build file 1640 # template knows how to handle this. That is currently the case for 1641 # Windows and VMS. 1642 if (defined $si) { 1643 # Just as above, copy certain shared_* attributes to the corresponding 1644 # module_ attribute unless the latter is already defined 1645 $si->{module_cflags} = $si->{shared_cflag} unless defined $si->{module_cflags}; 1646 $si->{module_cxxflags} = $si->{shared_cxxflag} unless defined $si->{module_cxxflags}; 1647 $si->{module_ldflags} = $si->{shared_ldflag} unless defined $si->{module_ldflags}; 1648 foreach (sort keys %$si) { 1649 $target{$_} = defined $target{$_} 1650 ? add($si->{$_})->($target{$_}) 1651 : $si->{$_}; 1652 } 1653 } 1654} 1655 1656# ALL MODIFICATIONS TO %disabled, %config and %target MUST BE DONE FROM HERE ON 1657 1658my %disabled_info = (); # For configdata.pm 1659foreach my $what (sort keys %disabled) { 1660 $config{options} .= " no-$what"; 1661 1662 if (!grep { $what eq $_ } ( 'buildtest-c++', 'threads', 'shared', 'pic', 1663 'dynamic-engine', 'makedepend', 1664 'zlib-dynamic', 'zlib', 'sse2' )) { 1665 (my $WHAT = uc $what) =~ s|-|_|g; 1666 1667 # Fix up C macro end names 1668 $WHAT = "RMD160" if $what eq "ripemd"; 1669 1670 # fix-up crypto/directory name(s) 1671 $what = "ripemd" if $what eq "rmd160"; 1672 $what = "whrlpool" if $what eq "whirlpool"; 1673 1674 my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; 1675 1676 if ((grep { $what eq $_ } @{$config{sdirs}}) 1677 && $what ne 'async' && $what ne 'err' && $what ne 'dso') { 1678 @{$config{sdirs}} = grep { $what ne $_} @{$config{sdirs}}; 1679 $disabled_info{$what}->{skipped} = [ catdir('crypto', $what) ]; 1680 1681 if ($what ne 'engine') { 1682 push @{$config{openssl_algorithm_defines}}, $macro; 1683 } else { 1684 @{$config{dirs}} = grep !/^engines$/, @{$config{dirs}}; 1685 push @{$disabled_info{engine}->{skipped}}, catdir('engines'); 1686 push @{$config{openssl_other_defines}}, $macro; 1687 } 1688 } else { 1689 push @{$config{openssl_other_defines}}, $macro; 1690 } 1691 1692 } 1693} 1694 1695if ($disabled{"dynamic-engine"}) { 1696 push @{$config{openssl_other_defines}}, "OPENSSL_NO_DYNAMIC_ENGINE"; 1697} else { 1698 push @{$config{openssl_other_defines}}, "OPENSSL_NO_STATIC_ENGINE"; 1699} 1700 1701# If we use the unified build, collect information from build.info files 1702my %unified_info = (); 1703 1704my $buildinfo_debug = defined($ENV{CONFIGURE_DEBUG_BUILDINFO}); 1705if ($builder eq "unified") { 1706 use with_fallback qw(Text::Template); 1707 1708 sub cleandir { 1709 my $base = shift; 1710 my $dir = shift; 1711 my $relativeto = shift || "."; 1712 1713 $dir = catdir($base,$dir) unless isabsolute($dir); 1714 1715 # Make sure the directories we're building in exists 1716 mkpath($dir); 1717 1718 my $res = abs2rel(absolutedir($dir), rel2abs($relativeto)); 1719 #print STDERR "DEBUG[cleandir]: $dir , $base => $res\n"; 1720 return $res; 1721 } 1722 1723 sub cleanfile { 1724 my $base = shift; 1725 my $file = shift; 1726 my $relativeto = shift || "."; 1727 1728 $file = catfile($base,$file) unless isabsolute($file); 1729 1730 my $d = dirname($file); 1731 my $f = basename($file); 1732 1733 # Make sure the directories we're building in exists 1734 mkpath($d); 1735 1736 my $res = abs2rel(catfile(absolutedir($d), $f), rel2abs($relativeto)); 1737 #print STDERR "DEBUG[cleanfile]: $d , $f => $res\n"; 1738 return $res; 1739 } 1740 1741 # Store the name of the template file we will build the build file from 1742 # in %config. This may be useful for the build file itself. 1743 my @build_file_template_names = 1744 ( $builder_platform."-".$config{build_file}.".tmpl", 1745 $config{build_file}.".tmpl" ); 1746 my @build_file_templates = (); 1747 1748 # First, look in the user provided directory, if given 1749 if (defined env($local_config_envname)) { 1750 @build_file_templates = 1751 map { 1752 if ($^O eq 'VMS') { 1753 # VMS environment variables are logical names, 1754 # which can be used as is 1755 $local_config_envname . ':' . $_; 1756 } else { 1757 catfile(env($local_config_envname), $_); 1758 } 1759 } 1760 @build_file_template_names; 1761 } 1762 # Then, look in our standard directory 1763 push @build_file_templates, 1764 ( map { cleanfile($srcdir, catfile("Configurations", $_), $blddir) } 1765 @build_file_template_names ); 1766 1767 my $build_file_template; 1768 for $_ (@build_file_templates) { 1769 $build_file_template = $_; 1770 last if -f $build_file_template; 1771 1772 $build_file_template = undef; 1773 } 1774 if (!defined $build_file_template) { 1775 die "*** Couldn't find any of:\n", join("\n", @build_file_templates), "\n"; 1776 } 1777 $config{build_file_templates} 1778 = [ cleanfile($srcdir, catfile("Configurations", "common0.tmpl"), 1779 $blddir), 1780 $build_file_template, 1781 cleanfile($srcdir, catfile("Configurations", "common.tmpl"), 1782 $blddir) ]; 1783 1784 my @build_infos = ( [ ".", "build.info" ] ); 1785 foreach (@{$config{dirs}}) { 1786 push @build_infos, [ $_, "build.info" ] 1787 if (-f catfile($srcdir, $_, "build.info")); 1788 } 1789 foreach (@{$config{sdirs}}) { 1790 push @build_infos, [ catdir("crypto", $_), "build.info" ] 1791 if (-f catfile($srcdir, "crypto", $_, "build.info")); 1792 } 1793 foreach (@{$config{engdirs}}) { 1794 push @build_infos, [ catdir("engines", $_), "build.info" ] 1795 if (-f catfile($srcdir, "engines", $_, "build.info")); 1796 } 1797 foreach (@{$config{tdirs}}) { 1798 push @build_infos, [ catdir("test", $_), "build.info" ] 1799 if (-f catfile($srcdir, "test", $_, "build.info")); 1800 } 1801 1802 $config{build_infos} = [ ]; 1803 1804 my %ordinals = (); 1805 foreach (@build_infos) { 1806 my $sourced = catdir($srcdir, $_->[0]); 1807 my $buildd = catdir($blddir, $_->[0]); 1808 1809 mkpath($buildd); 1810 1811 my $f = $_->[1]; 1812 # The basic things we're trying to build 1813 my @programs = (); 1814 my @programs_install = (); 1815 my @libraries = (); 1816 my @libraries_install = (); 1817 my @engines = (); 1818 my @engines_install = (); 1819 my @scripts = (); 1820 my @scripts_install = (); 1821 my @extra = (); 1822 my @overrides = (); 1823 my @intermediates = (); 1824 my @rawlines = (); 1825 1826 my %sources = (); 1827 my %shared_sources = (); 1828 my %includes = (); 1829 my %depends = (); 1830 my %renames = (); 1831 my %sharednames = (); 1832 my %generate = (); 1833 1834 # We want to detect configdata.pm in the source tree, so we 1835 # don't use it if the build tree is different. 1836 my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir); 1837 1838 push @{$config{build_infos}}, catfile(abs2rel($sourced, $blddir), $f); 1839 my $template = 1840 Text::Template->new(TYPE => 'FILE', 1841 SOURCE => catfile($sourced, $f), 1842 PREPEND => qq{use lib "$FindBin::Bin/util/perl";}); 1843 die "Something went wrong with $sourced/$f: $!\n" unless $template; 1844 my @text = 1845 split /^/m, 1846 $template->fill_in(HASH => { config => \%config, 1847 target => \%target, 1848 disabled => \%disabled, 1849 withargs => \%withargs, 1850 builddir => abs2rel($buildd, $blddir), 1851 sourcedir => abs2rel($sourced, $blddir), 1852 buildtop => abs2rel($blddir, $blddir), 1853 sourcetop => abs2rel($srcdir, $blddir) }, 1854 DELIMITERS => [ "{-", "-}" ]); 1855 1856 # The top item of this stack has the following values 1857 # -2 positive already run and we found ELSE (following ELSIF should fail) 1858 # -1 positive already run (skip until ENDIF) 1859 # 0 negatives so far (if we're at a condition, check it) 1860 # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF) 1861 # 2 positive ELSE (following ELSIF should fail) 1862 my @skip = (); 1863 collect_information( 1864 collect_from_array([ @text ], 1865 qr/\\$/ => sub { my $l1 = shift; my $l2 = shift; 1866 $l1 =~ s/\\$//; $l1.$l2 }), 1867 # Info we're looking for 1868 qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/ 1869 => sub { 1870 if (! @skip || $skip[$#skip] > 0) { 1871 push @skip, !! $1; 1872 } else { 1873 push @skip, -1; 1874 } 1875 }, 1876 qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/ 1877 => sub { die "ELSIF out of scope" if ! @skip; 1878 die "ELSIF following ELSE" if abs($skip[$#skip]) == 2; 1879 $skip[$#skip] = -1 if $skip[$#skip] != 0; 1880 $skip[$#skip] = !! $1 1881 if $skip[$#skip] == 0; }, 1882 qr/^\s*ELSE\s*$/ 1883 => sub { die "ELSE out of scope" if ! @skip; 1884 $skip[$#skip] = -2 if $skip[$#skip] != 0; 1885 $skip[$#skip] = 2 if $skip[$#skip] == 0; }, 1886 qr/^\s*ENDIF\s*$/ 1887 => sub { die "ENDIF out of scope" if ! @skip; 1888 pop @skip; }, 1889 qr/^\s*PROGRAMS(_NO_INST)?\s*=\s*(.*)\s*$/ 1890 => sub { 1891 if (!@skip || $skip[$#skip] > 0) { 1892 my $install = $1; 1893 my @x = tokenize($2); 1894 push @programs, @x; 1895 push @programs_install, @x unless $install; 1896 } 1897 }, 1898 qr/^\s*LIBS(_NO_INST)?\s*=\s*(.*)\s*$/ 1899 => sub { 1900 if (!@skip || $skip[$#skip] > 0) { 1901 my $install = $1; 1902 my @x = tokenize($2); 1903 push @libraries, @x; 1904 push @libraries_install, @x unless $install; 1905 } 1906 }, 1907 qr/^\s*ENGINES(_NO_INST)?\s*=\s*(.*)\s*$/ 1908 => sub { 1909 if (!@skip || $skip[$#skip] > 0) { 1910 my $install = $1; 1911 my @x = tokenize($2); 1912 push @engines, @x; 1913 push @engines_install, @x unless $install; 1914 } 1915 }, 1916 qr/^\s*SCRIPTS(_NO_INST)?\s*=\s*(.*)\s*$/ 1917 => sub { 1918 if (!@skip || $skip[$#skip] > 0) { 1919 my $install = $1; 1920 my @x = tokenize($2); 1921 push @scripts, @x; 1922 push @scripts_install, @x unless $install; 1923 } 1924 }, 1925 qr/^\s*EXTRA\s*=\s*(.*)\s*$/ 1926 => sub { push @extra, tokenize($1) 1927 if !@skip || $skip[$#skip] > 0 }, 1928 qr/^\s*OVERRIDES\s*=\s*(.*)\s*$/ 1929 => sub { push @overrides, tokenize($1) 1930 if !@skip || $skip[$#skip] > 0 }, 1931 1932 qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/, 1933 => sub { push @{$ordinals{$1}}, tokenize($2) 1934 if !@skip || $skip[$#skip] > 0 }, 1935 qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ 1936 => sub { push @{$sources{$1}}, tokenize($2) 1937 if !@skip || $skip[$#skip] > 0 }, 1938 qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ 1939 => sub { push @{$shared_sources{$1}}, tokenize($2) 1940 if !@skip || $skip[$#skip] > 0 }, 1941 qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ 1942 => sub { push @{$includes{$1}}, tokenize($2) 1943 if !@skip || $skip[$#skip] > 0 }, 1944 qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/ 1945 => sub { push @{$depends{$1}}, tokenize($2) 1946 if !@skip || $skip[$#skip] > 0 }, 1947 qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ 1948 => sub { push @{$generate{$1}}, $2 1949 if !@skip || $skip[$#skip] > 0 }, 1950 qr/^\s*RENAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ 1951 => sub { push @{$renames{$1}}, tokenize($2) 1952 if !@skip || $skip[$#skip] > 0 }, 1953 qr/^\s*SHARED_NAME\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/ 1954 => sub { push @{$sharednames{$1}}, tokenize($2) 1955 if !@skip || $skip[$#skip] > 0 }, 1956 qr/^\s*BEGINRAW\[((?:\\.|[^\\\]])+)\]\s*$/ 1957 => sub { 1958 my $lineiterator = shift; 1959 my $target_kind = $1; 1960 while (defined $lineiterator->()) { 1961 s|\R$||; 1962 if (/^\s*ENDRAW\[((?:\\.|[^\\\]])+)\]\s*$/) { 1963 die "ENDRAW doesn't match BEGINRAW" 1964 if $1 ne $target_kind; 1965 last; 1966 } 1967 next if @skip && $skip[$#skip] <= 0; 1968 push @rawlines, $_ 1969 if ($target_kind eq $config{build_file} 1970 || $target_kind eq $config{build_file}."(".$builder_platform.")"); 1971 } 1972 }, 1973 qr/^\s*(?:#.*)?$/ => sub { }, 1974 "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" }, 1975 "BEFORE" => sub { 1976 if ($buildinfo_debug) { 1977 print STDERR "DEBUG: Parsing ",join(" ", @_),"\n"; 1978 print STDERR "DEBUG: ... before parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n"; 1979 } 1980 }, 1981 "AFTER" => sub { 1982 if ($buildinfo_debug) { 1983 print STDERR "DEBUG: .... after parsing, skip stack is ",join(" ", map { int($_) } @skip),"\n"; 1984 } 1985 }, 1986 ); 1987 die "runaway IF?" if (@skip); 1988 1989 foreach (keys %renames) { 1990 die "$_ renamed to more than one thing: " 1991 ,join(" ", @{$renames{$_}}),"\n" 1992 if scalar @{$renames{$_}} > 1; 1993 my $dest = cleanfile($buildd, $_, $blddir); 1994 my $to = cleanfile($buildd, $renames{$_}->[0], $blddir); 1995 die "$dest renamed to more than one thing: " 1996 ,$unified_info{rename}->{$dest}, $to 1997 unless !defined($unified_info{rename}->{$dest}) 1998 or $unified_info{rename}->{$dest} eq $to; 1999 $unified_info{rename}->{$dest} = $to; 2000 } 2001 2002 foreach (@programs) { 2003 my $program = cleanfile($buildd, $_, $blddir); 2004 if ($unified_info{rename}->{$program}) { 2005 $program = $unified_info{rename}->{$program}; 2006 } 2007 $unified_info{programs}->{$program} = 1; 2008 } 2009 2010 foreach (@programs_install) { 2011 my $program = cleanfile($buildd, $_, $blddir); 2012 if ($unified_info{rename}->{$program}) { 2013 $program = $unified_info{rename}->{$program}; 2014 } 2015 $unified_info{install}->{programs}->{$program} = 1; 2016 } 2017 2018 foreach (@libraries) { 2019 my $library = cleanfile($buildd, $_, $blddir); 2020 if ($unified_info{rename}->{$library}) { 2021 $library = $unified_info{rename}->{$library}; 2022 } 2023 $unified_info{libraries}->{$library} = 1; 2024 } 2025 2026 foreach (@libraries_install) { 2027 my $library = cleanfile($buildd, $_, $blddir); 2028 if ($unified_info{rename}->{$library}) { 2029 $library = $unified_info{rename}->{$library}; 2030 } 2031 $unified_info{install}->{libraries}->{$library} = 1; 2032 } 2033 2034 die <<"EOF" if scalar @engines and !$config{dynamic_engines}; 2035ENGINES can only be used if configured with 'dynamic-engine'. 2036This is usually a fault in a build.info file. 2037EOF 2038 foreach (@engines) { 2039 my $library = cleanfile($buildd, $_, $blddir); 2040 if ($unified_info{rename}->{$library}) { 2041 $library = $unified_info{rename}->{$library}; 2042 } 2043 $unified_info{engines}->{$library} = 1; 2044 } 2045 2046 foreach (@engines_install) { 2047 my $library = cleanfile($buildd, $_, $blddir); 2048 if ($unified_info{rename}->{$library}) { 2049 $library = $unified_info{rename}->{$library}; 2050 } 2051 $unified_info{install}->{engines}->{$library} = 1; 2052 } 2053 2054 foreach (@scripts) { 2055 my $script = cleanfile($buildd, $_, $blddir); 2056 if ($unified_info{rename}->{$script}) { 2057 $script = $unified_info{rename}->{$script}; 2058 } 2059 $unified_info{scripts}->{$script} = 1; 2060 } 2061 2062 foreach (@scripts_install) { 2063 my $script = cleanfile($buildd, $_, $blddir); 2064 if ($unified_info{rename}->{$script}) { 2065 $script = $unified_info{rename}->{$script}; 2066 } 2067 $unified_info{install}->{scripts}->{$script} = 1; 2068 } 2069 2070 foreach (@extra) { 2071 my $extra = cleanfile($buildd, $_, $blddir); 2072 $unified_info{extra}->{$extra} = 1; 2073 } 2074 2075 foreach (@overrides) { 2076 my $override = cleanfile($buildd, $_, $blddir); 2077 $unified_info{overrides}->{$override} = 1; 2078 } 2079 2080 push @{$unified_info{rawlines}}, @rawlines; 2081 2082 unless ($disabled{shared}) { 2083 # Check sharednames. 2084 foreach (keys %sharednames) { 2085 my $dest = cleanfile($buildd, $_, $blddir); 2086 if ($unified_info{rename}->{$dest}) { 2087 $dest = $unified_info{rename}->{$dest}; 2088 } 2089 die "shared_name for $dest with multiple values: " 2090 ,join(" ", @{$sharednames{$_}}),"\n" 2091 if scalar @{$sharednames{$_}} > 1; 2092 my $to = cleanfile($buildd, $sharednames{$_}->[0], $blddir); 2093 die "shared_name found for a library $dest that isn't defined\n" 2094 unless $unified_info{libraries}->{$dest}; 2095 die "shared_name for $dest with multiple values: " 2096 ,$unified_info{sharednames}->{$dest}, ", ", $to 2097 unless !defined($unified_info{sharednames}->{$dest}) 2098 or $unified_info{sharednames}->{$dest} eq $to; 2099 $unified_info{sharednames}->{$dest} = $to; 2100 } 2101 2102 # Additionally, we set up sharednames for libraries that don't 2103 # have any, as themselves. Only for libraries that aren't 2104 # explicitly static. 2105 foreach (grep !/\.a$/, keys %{$unified_info{libraries}}) { 2106 if (!defined $unified_info{sharednames}->{$_}) { 2107 $unified_info{sharednames}->{$_} = $_ 2108 } 2109 } 2110 2111 # Check that we haven't defined any library as both shared and 2112 # explicitly static. That is forbidden. 2113 my @doubles = (); 2114 foreach (grep /\.a$/, keys %{$unified_info{libraries}}) { 2115 (my $l = $_) =~ s/\.a$//; 2116 push @doubles, $l if defined $unified_info{sharednames}->{$l}; 2117 } 2118 die "these libraries are both explicitly static and shared:\n ", 2119 join(" ", @doubles), "\n" 2120 if @doubles; 2121 } 2122 2123 foreach (keys %sources) { 2124 my $dest = $_; 2125 my $ddest = cleanfile($buildd, $_, $blddir); 2126 if ($unified_info{rename}->{$ddest}) { 2127 $ddest = $unified_info{rename}->{$ddest}; 2128 } 2129 foreach (@{$sources{$dest}}) { 2130 my $s = cleanfile($sourced, $_, $blddir); 2131 2132 # If it isn't in the source tree, we assume it's generated 2133 # in the build tree 2134 if ($s eq $src_configdata || ! -f $s || $generate{$_}) { 2135 $s = cleanfile($buildd, $_, $blddir); 2136 } 2137 # We recognise C++, C and asm files 2138 if ($s =~ /\.(cc|cpp|c|s|S)$/) { 2139 my $o = $_; 2140 $o =~ s/\.[csS]$/.o/; # C and assembler 2141 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ 2142 $o = cleanfile($buildd, $o, $blddir); 2143 $unified_info{sources}->{$ddest}->{$o} = 1; 2144 $unified_info{sources}->{$o}->{$s} = 1; 2145 } elsif ($s =~ /\.rc$/) { 2146 # We also recognise resource files 2147 my $o = $_; 2148 $o =~ s/\.rc$/.res/; # Resource configuration 2149 my $o = cleanfile($buildd, $o, $blddir); 2150 $unified_info{sources}->{$ddest}->{$o} = 1; 2151 $unified_info{sources}->{$o}->{$s} = 1; 2152 } else { 2153 $unified_info{sources}->{$ddest}->{$s} = 1; 2154 } 2155 } 2156 } 2157 2158 foreach (keys %shared_sources) { 2159 my $dest = $_; 2160 my $ddest = cleanfile($buildd, $_, $blddir); 2161 if ($unified_info{rename}->{$ddest}) { 2162 $ddest = $unified_info{rename}->{$ddest}; 2163 } 2164 foreach (@{$shared_sources{$dest}}) { 2165 my $s = cleanfile($sourced, $_, $blddir); 2166 2167 # If it isn't in the source tree, we assume it's generated 2168 # in the build tree 2169 if ($s eq $src_configdata || ! -f $s || $generate{$_}) { 2170 $s = cleanfile($buildd, $_, $blddir); 2171 } 2172 2173 if ($s =~ /\.(cc|cpp|c|s|S)$/) { 2174 # We recognise C++, C and asm files 2175 my $o = $_; 2176 $o =~ s/\.[csS]$/.o/; # C and assembler 2177 $o =~ s/\.(cc|cpp)$/_cc.o/; # C++ 2178 $o = cleanfile($buildd, $o, $blddir); 2179 $unified_info{shared_sources}->{$ddest}->{$o} = 1; 2180 $unified_info{sources}->{$o}->{$s} = 1; 2181 } elsif ($s =~ /\.rc$/) { 2182 # We also recognise resource files 2183 my $o = $_; 2184 $o =~ s/\.rc$/.res/; # Resource configuration 2185 my $o = cleanfile($buildd, $o, $blddir); 2186 $unified_info{shared_sources}->{$ddest}->{$o} = 1; 2187 $unified_info{sources}->{$o}->{$s} = 1; 2188 } elsif ($s =~ /\.(def|map|opt)$/) { 2189 # We also recognise .def / .map / .opt files 2190 # We know they are generated files 2191 my $def = cleanfile($buildd, $s, $blddir); 2192 $unified_info{shared_sources}->{$ddest}->{$def} = 1; 2193 } else { 2194 die "unrecognised source file type for shared library: $s\n"; 2195 } 2196 } 2197 } 2198 2199 foreach (keys %generate) { 2200 my $dest = $_; 2201 my $ddest = cleanfile($buildd, $_, $blddir); 2202 if ($unified_info{rename}->{$ddest}) { 2203 $ddest = $unified_info{rename}->{$ddest}; 2204 } 2205 die "more than one generator for $dest: " 2206 ,join(" ", @{$generate{$_}}),"\n" 2207 if scalar @{$generate{$_}} > 1; 2208 my @generator = split /\s+/, $generate{$dest}->[0]; 2209 $generator[0] = cleanfile($sourced, $generator[0], $blddir), 2210 $unified_info{generate}->{$ddest} = [ @generator ]; 2211 } 2212 2213 foreach (keys %depends) { 2214 my $dest = $_; 2215 my $ddest = $dest eq "" ? "" : cleanfile($sourced, $_, $blddir); 2216 2217 # If the destination doesn't exist in source, it can only be 2218 # a generated file in the build tree. 2219 if ($ddest ne "" && ($ddest eq $src_configdata || ! -f $ddest)) { 2220 $ddest = cleanfile($buildd, $_, $blddir); 2221 if ($unified_info{rename}->{$ddest}) { 2222 $ddest = $unified_info{rename}->{$ddest}; 2223 } 2224 } 2225 foreach (@{$depends{$dest}}) { 2226 my $d = cleanfile($sourced, $_, $blddir); 2227 2228 # If we know it's generated, or assume it is because we can't 2229 # find it in the source tree, we set file we depend on to be 2230 # in the build tree rather than the source tree, and assume 2231 # and that there are lines to build it in a BEGINRAW..ENDRAW 2232 # section or in the Makefile template. 2233 if ($d eq $src_configdata 2234 || ! -f $d 2235 || (grep { $d eq $_ } 2236 map { cleanfile($srcdir, $_, $blddir) } 2237 grep { /\.h$/ } keys %{$unified_info{generate}})) { 2238 $d = cleanfile($buildd, $_, $blddir); 2239 } 2240 # Take note if the file to depend on is being renamed 2241 # Take extra care with files ending with .a, they should 2242 # be treated without that extension, and the extension 2243 # should be added back after treatment. 2244 $d =~ /(\.a)?$/; 2245 my $e = $1 // ""; 2246 $d = $`; 2247 if ($unified_info{rename}->{$d}) { 2248 $d = $unified_info{rename}->{$d}; 2249 } 2250 $d .= $e; 2251 $unified_info{depends}->{$ddest}->{$d} = 1; 2252 } 2253 } 2254 2255 foreach (keys %includes) { 2256 my $dest = $_; 2257 my $ddest = cleanfile($sourced, $_, $blddir); 2258 2259 # If the destination doesn't exist in source, it can only be 2260 # a generated file in the build tree. 2261 if ($ddest eq $src_configdata || ! -f $ddest) { 2262 $ddest = cleanfile($buildd, $_, $blddir); 2263 if ($unified_info{rename}->{$ddest}) { 2264 $ddest = $unified_info{rename}->{$ddest}; 2265 } 2266 } 2267 foreach (@{$includes{$dest}}) { 2268 my $is = cleandir($sourced, $_, $blddir); 2269 my $ib = cleandir($buildd, $_, $blddir); 2270 push @{$unified_info{includes}->{$ddest}->{source}}, $is 2271 unless grep { $_ eq $is } @{$unified_info{includes}->{$ddest}->{source}}; 2272 push @{$unified_info{includes}->{$ddest}->{build}}, $ib 2273 unless grep { $_ eq $ib } @{$unified_info{includes}->{$ddest}->{build}}; 2274 } 2275 } 2276 } 2277 2278 my $ordinals_text = join(', ', sort keys %ordinals); 2279 warn <<"EOF" if $ordinals_text; 2280 2281WARNING: ORDINALS were specified for $ordinals_text 2282They are ignored and should be replaced with a combination of GENERATE, 2283DEPEND and SHARED_SOURCE. 2284EOF 2285 2286 # Massage the result 2287 2288 # If the user configured no-shared, we allow no shared sources 2289 if ($disabled{shared}) { 2290 foreach (keys %{$unified_info{shared_sources}}) { 2291 foreach (keys %{$unified_info{shared_sources}->{$_}}) { 2292 delete $unified_info{sources}->{$_}; 2293 } 2294 } 2295 $unified_info{shared_sources} = {}; 2296 } 2297 2298 # If we depend on a header file or a perl module, add an inclusion of 2299 # its directory to allow smoothe inclusion 2300 foreach my $dest (keys %{$unified_info{depends}}) { 2301 next if $dest eq ""; 2302 foreach my $d (keys %{$unified_info{depends}->{$dest}}) { 2303 next unless $d =~ /\.(h|pm)$/; 2304 my $i = dirname($d); 2305 my $spot = 2306 $d eq "configdata.pm" || defined($unified_info{generate}->{$d}) 2307 ? 'build' : 'source'; 2308 push @{$unified_info{includes}->{$dest}->{$spot}}, $i 2309 unless grep { $_ eq $i } @{$unified_info{includes}->{$dest}->{$spot}}; 2310 } 2311 } 2312 2313 # Trickle down includes placed on libraries, engines and programs to 2314 # their sources (i.e. object files) 2315 foreach my $dest (keys %{$unified_info{engines}}, 2316 keys %{$unified_info{libraries}}, 2317 keys %{$unified_info{programs}}) { 2318 foreach my $k (("source", "build")) { 2319 next unless defined($unified_info{includes}->{$dest}->{$k}); 2320 my @incs = reverse @{$unified_info{includes}->{$dest}->{$k}}; 2321 foreach my $obj (grep /\.o$/, 2322 (keys %{$unified_info{sources}->{$dest} // {}}, 2323 keys %{$unified_info{shared_sources}->{$dest} // {}})) { 2324 foreach my $inc (@incs) { 2325 unshift @{$unified_info{includes}->{$obj}->{$k}}, $inc 2326 unless grep { $_ eq $inc } @{$unified_info{includes}->{$obj}->{$k}}; 2327 } 2328 } 2329 } 2330 delete $unified_info{includes}->{$dest}; 2331 } 2332 2333 ### Make unified_info a bit more efficient 2334 # One level structures 2335 foreach (("programs", "libraries", "engines", "scripts", "extra", "overrides")) { 2336 $unified_info{$_} = [ sort keys %{$unified_info{$_}} ]; 2337 } 2338 # Two level structures 2339 foreach my $l1 (("install", "sources", "shared_sources", "ldadd", "depends")) { 2340 foreach my $l2 (sort keys %{$unified_info{$l1}}) { 2341 $unified_info{$l1}->{$l2} = 2342 [ sort keys %{$unified_info{$l1}->{$l2}} ]; 2343 } 2344 } 2345 # Includes 2346 foreach my $dest (sort keys %{$unified_info{includes}}) { 2347 if (defined($unified_info{includes}->{$dest}->{build})) { 2348 my @source_includes = (); 2349 @source_includes = ( @{$unified_info{includes}->{$dest}->{source}} ) 2350 if defined($unified_info{includes}->{$dest}->{source}); 2351 $unified_info{includes}->{$dest} = 2352 [ @{$unified_info{includes}->{$dest}->{build}} ]; 2353 foreach my $inc (@source_includes) { 2354 push @{$unified_info{includes}->{$dest}}, $inc 2355 unless grep { $_ eq $inc } @{$unified_info{includes}->{$dest}}; 2356 } 2357 } else { 2358 $unified_info{includes}->{$dest} = 2359 [ @{$unified_info{includes}->{$dest}->{source}} ]; 2360 } 2361 } 2362 2363 # For convenience collect information regarding directories where 2364 # files are generated, those generated files and the end product 2365 # they end up in where applicable. Then, add build rules for those 2366 # directories 2367 my %loopinfo = ( "lib" => [ @{$unified_info{libraries}} ], 2368 "dso" => [ @{$unified_info{engines}} ], 2369 "bin" => [ @{$unified_info{programs}} ], 2370 "script" => [ @{$unified_info{scripts}} ] ); 2371 foreach my $type (keys %loopinfo) { 2372 foreach my $product (@{$loopinfo{$type}}) { 2373 my %dirs = (); 2374 my $pd = dirname($product); 2375 2376 foreach (@{$unified_info{sources}->{$product} // []}, 2377 @{$unified_info{shared_sources}->{$product} // []}) { 2378 my $d = dirname($_); 2379 2380 # We don't want to create targets for source directories 2381 # when building out of source 2382 next if ($config{sourcedir} ne $config{builddir} 2383 && $d =~ m|^\Q$config{sourcedir}\E|); 2384 # We already have a "test" target, and the current directory 2385 # is just silly to make a target for 2386 next if $d eq "test" || $d eq "."; 2387 2388 $dirs{$d} = 1; 2389 push @{$unified_info{dirinfo}->{$d}->{deps}}, $_ 2390 if $d ne $pd; 2391 } 2392 foreach (keys %dirs) { 2393 push @{$unified_info{dirinfo}->{$_}->{products}->{$type}}, 2394 $product; 2395 } 2396 } 2397 } 2398} 2399 2400# For the schemes that need it, we provide the old *_obj configs 2401# from the *_asm_obj ones 2402foreach (grep /_(asm|aux)_src$/, keys %target) { 2403 my $src = $_; 2404 (my $obj = $_) =~ s/_(asm|aux)_src$/_obj/; 2405 $target{$obj} = $target{$src}; 2406 $target{$obj} =~ s/\.[csS]\b/.o/g; # C and assembler 2407 $target{$obj} =~ s/\.(cc|cpp)\b/_cc.o/g; # C++ 2408} 2409 2410# Write down our configuration where it fits ######################### 2411 2412print "Creating configdata.pm\n"; 2413open(OUT,">configdata.pm") || die "unable to create configdata.pm: $!\n"; 2414print OUT <<"EOF"; 2415#! $config{HASHBANGPERL} 2416 2417package configdata; 2418 2419use strict; 2420use warnings; 2421 2422use Exporter; 2423#use vars qw(\@ISA \@EXPORT); 2424our \@ISA = qw(Exporter); 2425our \@EXPORT = qw(\%config \%target \%disabled \%withargs \%unified_info \@disablables); 2426 2427EOF 2428print OUT "our %config = (\n"; 2429foreach (sort keys %config) { 2430 if (ref($config{$_}) eq "ARRAY") { 2431 print OUT " ", $_, " => [ ", join(", ", 2432 map { quotify("perl", $_) } 2433 @{$config{$_}}), " ],\n"; 2434 } elsif (ref($config{$_}) eq "HASH") { 2435 print OUT " ", $_, " => {"; 2436 if (scalar keys %{$config{$_}} > 0) { 2437 print OUT "\n"; 2438 foreach my $key (sort keys %{$config{$_}}) { 2439 print OUT " ", 2440 join(" => ", 2441 quotify("perl", $key), 2442 defined $config{$_}->{$key} 2443 ? quotify("perl", $config{$_}->{$key}) 2444 : "undef"); 2445 print OUT ",\n"; 2446 } 2447 print OUT " "; 2448 } 2449 print OUT "},\n"; 2450 } else { 2451 print OUT " ", $_, " => ", quotify("perl", $config{$_}), ",\n" 2452 } 2453} 2454print OUT <<"EOF"; 2455); 2456 2457EOF 2458print OUT "our %target = (\n"; 2459foreach (sort keys %target) { 2460 if (ref($target{$_}) eq "ARRAY") { 2461 print OUT " ", $_, " => [ ", join(", ", 2462 map { quotify("perl", $_) } 2463 @{$target{$_}}), " ],\n"; 2464 } else { 2465 print OUT " ", $_, " => ", quotify("perl", $target{$_}), ",\n" 2466 } 2467} 2468print OUT <<"EOF"; 2469); 2470 2471EOF 2472print OUT "our \%available_protocols = (\n"; 2473print OUT " tls => [ ", join(", ", map { quotify("perl", $_) } @tls), " ],\n"; 2474print OUT " dtls => [ ", join(", ", map { quotify("perl", $_) } @dtls), " ],\n"; 2475print OUT <<"EOF"; 2476); 2477 2478EOF 2479print OUT "our \@disablables = (\n"; 2480foreach (@disablables) { 2481 print OUT " ", quotify("perl", $_), ",\n"; 2482} 2483print OUT <<"EOF"; 2484); 2485 2486EOF 2487print OUT "our \%disabled = (\n"; 2488foreach (sort keys %disabled) { 2489 print OUT " ", quotify("perl", $_), " => ", quotify("perl", $disabled{$_}), ",\n"; 2490} 2491print OUT <<"EOF"; 2492); 2493 2494EOF 2495print OUT "our %withargs = (\n"; 2496foreach (sort keys %withargs) { 2497 if (ref($withargs{$_}) eq "ARRAY") { 2498 print OUT " ", $_, " => [ ", join(", ", 2499 map { quotify("perl", $_) } 2500 @{$withargs{$_}}), " ],\n"; 2501 } else { 2502 print OUT " ", $_, " => ", quotify("perl", $withargs{$_}), ",\n" 2503 } 2504} 2505print OUT <<"EOF"; 2506); 2507 2508EOF 2509if ($builder eq "unified") { 2510 my $recurse; 2511 $recurse = sub { 2512 my $indent = shift; 2513 foreach (@_) { 2514 if (ref $_ eq "ARRAY") { 2515 print OUT " "x$indent, "[\n"; 2516 foreach (@$_) { 2517 $recurse->($indent + 4, $_); 2518 } 2519 print OUT " "x$indent, "],\n"; 2520 } elsif (ref $_ eq "HASH") { 2521 my %h = %$_; 2522 print OUT " "x$indent, "{\n"; 2523 foreach (sort keys %h) { 2524 if (ref $h{$_} eq "") { 2525 print OUT " "x($indent + 4), quotify("perl", $_), " => ", quotify("perl", $h{$_}), ",\n"; 2526 } else { 2527 print OUT " "x($indent + 4), quotify("perl", $_), " =>\n"; 2528 $recurse->($indent + 8, $h{$_}); 2529 } 2530 } 2531 print OUT " "x$indent, "},\n"; 2532 } else { 2533 print OUT " "x$indent, quotify("perl", $_), ",\n"; 2534 } 2535 } 2536 }; 2537 print OUT "our %unified_info = (\n"; 2538 foreach (sort keys %unified_info) { 2539 if (ref $unified_info{$_} eq "") { 2540 print OUT " "x4, quotify("perl", $_), " => ", quotify("perl", $unified_info{$_}), ",\n"; 2541 } else { 2542 print OUT " "x4, quotify("perl", $_), " =>\n"; 2543 $recurse->(8, $unified_info{$_}); 2544 } 2545 } 2546 print OUT <<"EOF"; 2547); 2548 2549EOF 2550} 2551print OUT 2552 "# The following data is only used when this files is use as a script\n"; 2553print OUT "my \@makevars = (\n"; 2554foreach (sort keys %user) { 2555 print OUT " '",$_,"',\n"; 2556} 2557print OUT ");\n"; 2558print OUT "my \%disabled_info = (\n"; 2559foreach my $what (sort keys %disabled_info) { 2560 print OUT " '$what' => {\n"; 2561 foreach my $info (sort keys %{$disabled_info{$what}}) { 2562 if (ref $disabled_info{$what}->{$info} eq 'ARRAY') { 2563 print OUT " $info => [ ", 2564 join(', ', map { "'$_'" } @{$disabled_info{$what}->{$info}}), 2565 " ],\n"; 2566 } else { 2567 print OUT " $info => '", $disabled_info{$what}->{$info}, 2568 "',\n"; 2569 } 2570 } 2571 print OUT " },\n"; 2572} 2573print OUT ");\n"; 2574print OUT 'my @user_crossable = qw( ', join (' ', @user_crossable), " );\n"; 2575print OUT << 'EOF'; 2576# If run directly, we can give some answers, and even reconfigure 2577unless (caller) { 2578 use Getopt::Long; 2579 use File::Spec::Functions; 2580 use File::Basename; 2581 use Pod::Usage; 2582 2583 my $here = dirname($0); 2584 2585 my $dump = undef; 2586 my $cmdline = undef; 2587 my $options = undef; 2588 my $target = undef; 2589 my $envvars = undef; 2590 my $makevars = undef; 2591 my $buildparams = undef; 2592 my $reconf = undef; 2593 my $verbose = undef; 2594 my $help = undef; 2595 my $man = undef; 2596 GetOptions('dump|d' => \$dump, 2597 'command-line|c' => \$cmdline, 2598 'options|o' => \$options, 2599 'target|t' => \$target, 2600 'environment|e' => \$envvars, 2601 'make-variables|m' => \$makevars, 2602 'build-parameters|b' => \$buildparams, 2603 'reconfigure|reconf|r' => \$reconf, 2604 'verbose|v' => \$verbose, 2605 'help' => \$help, 2606 'man' => \$man) 2607 or die "Errors in command line arguments\n"; 2608 2609 unless ($dump || $cmdline || $options || $target || $envvars || $makevars 2610 || $buildparams || $reconf || $verbose || $help || $man) { 2611 print STDERR <<"_____"; 2612You must give at least one option. 2613For more information, do '$0 --help' 2614_____ 2615 exit(2); 2616 } 2617 2618 if ($help) { 2619 pod2usage(-exitval => 0, 2620 -verbose => 1); 2621 } 2622 if ($man) { 2623 pod2usage(-exitval => 0, 2624 -verbose => 2); 2625 } 2626 if ($dump || $cmdline) { 2627 print "\nCommand line (with current working directory = $here):\n\n"; 2628 print ' ',join(' ', 2629 $config{PERL}, 2630 catfile($config{sourcedir}, 'Configure'), 2631 @{$config{perlargv}}), "\n"; 2632 print "\nPerl information:\n\n"; 2633 print ' ',$config{perl_cmd},"\n"; 2634 print ' ',$config{perl_version},' for ',$config{perl_archname},"\n"; 2635 } 2636 if ($dump || $options) { 2637 my $longest = 0; 2638 my $longest2 = 0; 2639 foreach my $what (@disablables) { 2640 $longest = length($what) if $longest < length($what); 2641 $longest2 = length($disabled{$what}) 2642 if $disabled{$what} && $longest2 < length($disabled{$what}); 2643 } 2644 print "\nEnabled features:\n\n"; 2645 foreach my $what (@disablables) { 2646 print " $what\n" 2647 unless grep { $_ =~ /^${what}$/ } keys %disabled; 2648 } 2649 print "\nDisabled features:\n\n"; 2650 foreach my $what (@disablables) { 2651 my @what2 = grep { $_ =~ /^${what}$/ } keys %disabled; 2652 my $what3 = $what2[0]; 2653 if ($what3) { 2654 print " $what3", ' ' x ($longest - length($what3) + 1), 2655 "[$disabled{$what3}]", ' ' x ($longest2 - length($disabled{$what3}) + 1); 2656 print $disabled_info{$what3}->{macro} 2657 if $disabled_info{$what3}->{macro}; 2658 print ' (skip ', 2659 join(', ', @{$disabled_info{$what3}->{skipped}}), 2660 ')' 2661 if $disabled_info{$what3}->{skipped}; 2662 print "\n"; 2663 } 2664 } 2665 } 2666 if ($dump || $target) { 2667 print "\nConfig target attributes:\n\n"; 2668 foreach (sort keys %target) { 2669 next if $_ =~ m|^_| || $_ eq 'template'; 2670 my $quotify = sub { 2671 map { (my $x = $_) =~ s|([\\\$\@"])|\\$1|g; "\"$x\""} @_; 2672 }; 2673 print ' ', $_, ' => '; 2674 if (ref($target{$_}) eq "ARRAY") { 2675 print '[ ', join(', ', $quotify->(@{$target{$_}})), " ],\n"; 2676 } else { 2677 print $quotify->($target{$_}), ",\n" 2678 } 2679 } 2680 } 2681 if ($dump || $envvars) { 2682 print "\nRecorded environment:\n\n"; 2683 foreach (sort keys %{$config{perlenv}}) { 2684 print ' ',$_,' = ',($config{perlenv}->{$_} || ''),"\n"; 2685 } 2686 } 2687 if ($dump || $makevars) { 2688 print "\nMakevars:\n\n"; 2689 foreach my $var (@makevars) { 2690 my $prefix = ''; 2691 $prefix = $config{CROSS_COMPILE} 2692 if grep { $var eq $_ } @user_crossable; 2693 $prefix //= ''; 2694 print ' ',$var,' ' x (16 - length $var),'= ', 2695 (ref $config{$var} eq 'ARRAY' 2696 ? join(' ', @{$config{$var}}) 2697 : $prefix.$config{$var}), 2698 "\n" 2699 if defined $config{$var}; 2700 } 2701 2702 my @buildfile = ($config{builddir}, $config{build_file}); 2703 unshift @buildfile, $here 2704 unless file_name_is_absolute($config{builddir}); 2705 my $buildfile = canonpath(catdir(@buildfile)); 2706 print <<"_____"; 2707 2708NOTE: These variables only represent the configuration view. The build file 2709template may have processed these variables further, please have a look at the 2710build file for more exact data: 2711 $buildfile 2712_____ 2713 } 2714 if ($dump || $buildparams) { 2715 my @buildfile = ($config{builddir}, $config{build_file}); 2716 unshift @buildfile, $here 2717 unless file_name_is_absolute($config{builddir}); 2718 print "\nbuild file:\n\n"; 2719 print " ", canonpath(catfile(@buildfile)),"\n"; 2720 2721 print "\nbuild file templates:\n\n"; 2722 foreach (@{$config{build_file_templates}}) { 2723 my @tmpl = ($_); 2724 unshift @tmpl, $here 2725 unless file_name_is_absolute($config{sourcedir}); 2726 print ' ',canonpath(catfile(@tmpl)),"\n"; 2727 } 2728 } 2729 if ($reconf) { 2730 if ($verbose) { 2731 print 'Reconfiguring with: ', join(' ',@{$config{perlargv}}), "\n"; 2732 foreach (sort keys %{$config{perlenv}}) { 2733 print ' ',$_,' = ',($config{perlenv}->{$_} || ""),"\n"; 2734 } 2735 } 2736 2737 chdir $here; 2738 exec $^X,catfile($config{sourcedir}, 'Configure'),'reconf'; 2739 } 2740} 2741 27421; 2743 2744__END__ 2745 2746=head1 NAME 2747 2748configdata.pm - configuration data for OpenSSL builds 2749 2750=head1 SYNOPSIS 2751 2752Interactive: 2753 2754 perl configdata.pm [options] 2755 2756As data bank module: 2757 2758 use configdata; 2759 2760=head1 DESCRIPTION 2761 2762This module can be used in two modes, interactively and as a module containing 2763all the data recorded by OpenSSL's Configure script. 2764 2765When used interactively, simply run it as any perl script, with at least one 2766option, and you will get the information you ask for. See L</OPTIONS> below. 2767 2768When loaded as a module, you get a few databanks with useful information to 2769perform build related tasks. The databanks are: 2770 2771 %config Configured things. 2772 %target The OpenSSL config target with all inheritances 2773 resolved. 2774 %disabled The features that are disabled. 2775 @disablables The list of features that can be disabled. 2776 %withargs All data given through --with-THING options. 2777 %unified_info All information that was computed from the build.info 2778 files. 2779 2780=head1 OPTIONS 2781 2782=over 4 2783 2784=item B<--help> 2785 2786Print a brief help message and exit. 2787 2788=item B<--man> 2789 2790Print the manual page and exit. 2791 2792=item B<--dump> | B<-d> 2793 2794Print all relevant configuration data. This is equivalent to B<--command-line> 2795B<--options> B<--target> B<--environment> B<--make-variables> 2796B<--build-parameters>. 2797 2798=item B<--command-line> | B<-c> 2799 2800Print the current configuration command line. 2801 2802=item B<--options> | B<-o> 2803 2804Print the features, both enabled and disabled, and display defined macro and 2805skipped directories where applicable. 2806 2807=item B<--target> | B<-t> 2808 2809Print the config attributes for this config target. 2810 2811=item B<--environment> | B<-e> 2812 2813Print the environment variables and their values at the time of configuration. 2814 2815=item B<--make-variables> | B<-m> 2816 2817Print the main make variables generated in the current configuration 2818 2819=item B<--build-parameters> | B<-b> 2820 2821Print the build parameters, i.e. build file and build file templates. 2822 2823=item B<--reconfigure> | B<--reconf> | B<-r> 2824 2825Redo the configuration. 2826 2827=item B<--verbose> | B<-v> 2828 2829Verbose output. 2830 2831=back 2832 2833=cut 2834 2835EOF 2836close(OUT); 2837if ($builder_platform eq 'unix') { 2838 my $mode = (0755 & ~umask); 2839 chmod $mode, 'configdata.pm' 2840 or warn sprintf("WARNING: Couldn't change mode for 'configdata.pm' to 0%03o: %s\n",$mode,$!); 2841} 2842 2843my %builders = ( 2844 unified => sub { 2845 print 'Creating ',$config{build_file},"\n"; 2846 run_dofile(catfile($blddir, $config{build_file}), 2847 @{$config{build_file_templates}}); 2848 }, 2849 ); 2850 2851$builders{$builder}->($builder_platform, @builder_opts); 2852 2853$SIG{__DIE__} = $orig_death_handler; 2854 2855print <<"EOF" if ($disabled{threads} eq "unavailable"); 2856 2857The library could not be configured for supporting multi-threaded 2858applications as the compiler options required on this system are not known. 2859See file INSTALL for details if you need multi-threading. 2860EOF 2861 2862print <<"EOF" if ($no_shared_warn); 2863 2864The options 'shared', 'pic' and 'dynamic-engine' aren't supported on this 2865platform, so we will pretend you gave the option 'no-pic', which also disables 2866'shared' and 'dynamic-engine'. If you know how to implement shared libraries 2867or position independent code, please let us know (but please first make sure 2868you have tried with a current version of OpenSSL). 2869EOF 2870 2871print <<"EOF"; 2872 2873********************************************************************** 2874*** *** 2875*** OpenSSL has been successfully configured *** 2876*** *** 2877*** If you encounter a problem while building, please open an *** 2878*** issue on GitHub <https://github.com/openssl/openssl/issues> *** 2879*** and include the output from the following command: *** 2880*** *** 2881*** perl configdata.pm --dump *** 2882*** *** 2883*** (If you are new to OpenSSL, you might want to consult the *** 2884*** 'Troubleshooting' section in the INSTALL file first) *** 2885*** *** 2886********************************************************************** 2887EOF 2888 2889exit(0); 2890 2891###################################################################### 2892# 2893# Helpers and utility functions 2894# 2895 2896# Death handler, to print a helpful message in case of failure ####### 2897# 2898sub death_handler { 2899 die @_ if $^S; # To prevent the added message in eval blocks 2900 my $build_file = $config{build_file} // "build file"; 2901 my @message = ( <<"_____", @_ ); 2902 2903Failure! $build_file wasn't produced. 2904Please read INSTALL and associated NOTES files. You may also have to look over 2905your available compiler tool chain or change your configuration. 2906 2907_____ 2908 2909 # Dying is terminal, so it's ok to reset the signal handler here. 2910 $SIG{__DIE__} = $orig_death_handler; 2911 die @message; 2912} 2913 2914# Configuration file reading ######################################### 2915 2916# Note: All of the helper functions are for lazy evaluation. They all 2917# return a CODE ref, which will return the intended value when evaluated. 2918# Thus, whenever there's mention of a returned value, it's about that 2919# intended value. 2920 2921# Helper function to implement conditional inheritance depending on the 2922# value of $disabled{asm}. Used in inherit_from values as follows: 2923# 2924# inherit_from => [ "template", asm("asm_tmpl") ] 2925# 2926sub asm { 2927 my @x = @_; 2928 sub { 2929 $disabled{asm} ? () : @x; 2930 } 2931} 2932 2933# Helper function to implement conditional value variants, with a default 2934# plus additional values based on the value of $config{build_type}. 2935# Arguments are given in hash table form: 2936# 2937# picker(default => "Basic string: ", 2938# debug => "debug", 2939# release => "release") 2940# 2941# When configuring with --debug, the resulting string will be 2942# "Basic string: debug", and when not, it will be "Basic string: release" 2943# 2944# This can be used to create variants of sets of flags according to the 2945# build type: 2946# 2947# cflags => picker(default => "-Wall", 2948# debug => "-g -O0", 2949# release => "-O3") 2950# 2951sub picker { 2952 my %opts = @_; 2953 return sub { add($opts{default} || (), 2954 $opts{$config{build_type}} || ())->(); } 2955} 2956 2957# Helper function to combine several values of different types into one. 2958# This is useful if you want to combine a string with the result of a 2959# lazy function, such as: 2960# 2961# cflags => combine("-Wall", sub { $disabled{zlib} ? () : "-DZLIB" }) 2962# 2963sub combine { 2964 my @stuff = @_; 2965 return sub { add(@stuff)->(); } 2966} 2967 2968# Helper function to implement conditional values depending on the value 2969# of $disabled{threads}. Can be used as follows: 2970# 2971# cflags => combine("-Wall", threads("-pthread")) 2972# 2973sub threads { 2974 my @flags = @_; 2975 return sub { add($disabled{threads} ? () : @flags)->(); } 2976} 2977 2978sub shared { 2979 my @flags = @_; 2980 return sub { add($disabled{shared} ? () : @flags)->(); } 2981} 2982 2983our $add_called = 0; 2984# Helper function to implement adding values to already existing configuration 2985# values. It handles elements that are ARRAYs, CODEs and scalars 2986sub _add { 2987 my $separator = shift; 2988 2989 # If there's any ARRAY in the collection of values OR the separator 2990 # is undef, we will return an ARRAY of combined values, otherwise a 2991 # string of joined values with $separator as the separator. 2992 my $found_array = !defined($separator); 2993 2994 my @values = 2995 map { 2996 my $res = $_; 2997 while (ref($res) eq "CODE") { 2998 $res = $res->(); 2999 } 3000 if (defined($res)) { 3001 if (ref($res) eq "ARRAY") { 3002 $found_array = 1; 3003 @$res; 3004 } else { 3005 $res; 3006 } 3007 } else { 3008 (); 3009 } 3010 } (@_); 3011 3012 $add_called = 1; 3013 3014 if ($found_array) { 3015 [ @values ]; 3016 } else { 3017 join($separator, grep { defined($_) && $_ ne "" } @values); 3018 } 3019} 3020sub add_before { 3021 my $separator = " "; 3022 if (ref($_[$#_]) eq "HASH") { 3023 my $opts = pop; 3024 $separator = $opts->{separator}; 3025 } 3026 my @x = @_; 3027 sub { _add($separator, @x, @_) }; 3028} 3029sub add { 3030 my $separator = " "; 3031 if (ref($_[$#_]) eq "HASH") { 3032 my $opts = pop; 3033 $separator = $opts->{separator}; 3034 } 3035 my @x = @_; 3036 sub { _add($separator, @_, @x) }; 3037} 3038 3039sub read_eval_file { 3040 my $fname = shift; 3041 my $content; 3042 my @result; 3043 3044 open F, "< $fname" or die "Can't open '$fname': $!\n"; 3045 { 3046 undef local $/; 3047 $content = <F>; 3048 } 3049 close F; 3050 { 3051 local $@; 3052 3053 @result = ( eval $content ); 3054 warn $@ if $@; 3055 } 3056 return wantarray ? @result : $result[0]; 3057} 3058 3059# configuration reader, evaluates the input file as a perl script and expects 3060# it to fill %targets with target configurations. Those are then added to 3061# %table. 3062sub read_config { 3063 my $fname = shift; 3064 my %targets; 3065 3066 { 3067 # Protect certain tables from tampering 3068 local %table = (); 3069 3070 %targets = read_eval_file($fname); 3071 } 3072 my %preexisting = (); 3073 foreach (sort keys %targets) { 3074 $preexisting{$_} = 1 if $table{$_}; 3075 } 3076 die <<"EOF", 3077The following config targets from $fname 3078shadow pre-existing config targets with the same name: 3079EOF 3080 map { " $_\n" } sort keys %preexisting 3081 if %preexisting; 3082 3083 3084 # For each target, check that it's configured with a hash table. 3085 foreach (keys %targets) { 3086 if (ref($targets{$_}) ne "HASH") { 3087 if (ref($targets{$_}) eq "") { 3088 warn "Deprecated target configuration for $_, ignoring...\n"; 3089 } else { 3090 warn "Misconfigured target configuration for $_ (should be a hash table), ignoring...\n"; 3091 } 3092 delete $targets{$_}; 3093 } else { 3094 $targets{$_}->{_conf_fname_int} = add([ $fname ]); 3095 } 3096 } 3097 3098 %table = (%table, %targets); 3099 3100} 3101 3102# configuration resolver. Will only resolve all the lazy evaluation 3103# codeblocks for the chosen target and all those it inherits from, 3104# recursively 3105sub resolve_config { 3106 my $target = shift; 3107 my @breadcrumbs = @_; 3108 3109# my $extra_checks = defined($ENV{CONFIGURE_EXTRA_CHECKS}); 3110 3111 if (grep { $_ eq $target } @breadcrumbs) { 3112 die "inherit_from loop! target backtrace:\n " 3113 ,$target,"\n ",join("\n ", @breadcrumbs),"\n"; 3114 } 3115 3116 if (!defined($table{$target})) { 3117 warn "Warning! target $target doesn't exist!\n"; 3118 return (); 3119 } 3120 # Recurse through all inheritances. They will be resolved on the 3121 # fly, so when this operation is done, they will all just be a 3122 # bunch of attributes with string values. 3123 # What we get here, though, are keys with references to lists of 3124 # the combined values of them all. We will deal with lists after 3125 # this stage is done. 3126 my %combined_inheritance = (); 3127 if ($table{$target}->{inherit_from}) { 3128 my @inherit_from = 3129 map { ref($_) eq "CODE" ? $_->() : $_ } @{$table{$target}->{inherit_from}}; 3130 foreach (@inherit_from) { 3131 my %inherited_config = resolve_config($_, $target, @breadcrumbs); 3132 3133 # 'template' is a marker that's considered private to 3134 # the config that had it. 3135 delete $inherited_config{template}; 3136 3137 foreach (keys %inherited_config) { 3138 if (!$combined_inheritance{$_}) { 3139 $combined_inheritance{$_} = []; 3140 } 3141 push @{$combined_inheritance{$_}}, $inherited_config{$_}; 3142 } 3143 } 3144 } 3145 3146 # We won't need inherit_from in this target any more, since we've 3147 # resolved all the inheritances that lead to this 3148 delete $table{$target}->{inherit_from}; 3149 3150 # Now is the time to deal with those lists. Here's the place to 3151 # decide what shall be done with those lists, all based on the 3152 # values of the target we're currently dealing with. 3153 # - If a value is a coderef, it will be executed with the list of 3154 # inherited values as arguments. 3155 # - If the corresponding key doesn't have a value at all or is the 3156 # empty string, the inherited value list will be run through the 3157 # default combiner (below), and the result becomes this target's 3158 # value. 3159 # - Otherwise, this target's value is assumed to be a string that 3160 # will simply override the inherited list of values. 3161 my $default_combiner = add(); 3162 3163 my %all_keys = 3164 map { $_ => 1 } (keys %combined_inheritance, 3165 keys %{$table{$target}}); 3166 3167 sub process_values { 3168 my $object = shift; 3169 my $inherited = shift; # Always a [ list ] 3170 my $target = shift; 3171 my $entry = shift; 3172 3173 $add_called = 0; 3174 3175 while(ref($object) eq "CODE") { 3176 $object = $object->(@$inherited); 3177 } 3178 if (!defined($object)) { 3179 return (); 3180 } 3181 elsif (ref($object) eq "ARRAY") { 3182 local $add_called; # To make sure recursive calls don't affect it 3183 return [ map { process_values($_, $inherited, $target, $entry) } 3184 @$object ]; 3185 } elsif (ref($object) eq "") { 3186 return $object; 3187 } else { 3188 die "cannot handle reference type ",ref($object) 3189 ," found in target ",$target," -> ",$entry,"\n"; 3190 } 3191 } 3192 3193 foreach my $key (sort keys %all_keys) { 3194 my $previous = $combined_inheritance{$key}; 3195 3196 # Current target doesn't have a value for the current key? 3197 # Assign it the default combiner, the rest of this loop body 3198 # will handle it just like any other coderef. 3199 if (!exists $table{$target}->{$key}) { 3200 $table{$target}->{$key} = $default_combiner; 3201 } 3202 3203 $table{$target}->{$key} = process_values($table{$target}->{$key}, 3204 $combined_inheritance{$key}, 3205 $target, $key); 3206 unless(defined($table{$target}->{$key})) { 3207 delete $table{$target}->{$key}; 3208 } 3209# if ($extra_checks && 3210# $previous && !($add_called || $previous ~~ $table{$target}->{$key})) { 3211# warn "$key got replaced in $target\n"; 3212# } 3213 } 3214 3215 # Finally done, return the result. 3216 return %{$table{$target}}; 3217} 3218 3219sub usage 3220 { 3221 print STDERR $usage; 3222 print STDERR "\npick os/compiler from:\n"; 3223 my $j=0; 3224 my $i; 3225 my $k=0; 3226 foreach $i (sort keys %table) 3227 { 3228 next if $table{$i}->{template}; 3229 next if $i =~ /^debug/; 3230 $k += length($i) + 1; 3231 if ($k > 78) 3232 { 3233 print STDERR "\n"; 3234 $k=length($i); 3235 } 3236 print STDERR $i . " "; 3237 } 3238 foreach $i (sort keys %table) 3239 { 3240 next if $table{$i}->{template}; 3241 next if $i !~ /^debug/; 3242 $k += length($i) + 1; 3243 if ($k > 78) 3244 { 3245 print STDERR "\n"; 3246 $k=length($i); 3247 } 3248 print STDERR $i . " "; 3249 } 3250 print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n"; 3251 exit(1); 3252 } 3253 3254sub run_dofile 3255{ 3256 my $out = shift; 3257 my @templates = @_; 3258 3259 unlink $out || warn "Can't remove $out, $!" 3260 if -f $out; 3261 foreach (@templates) { 3262 die "Can't open $_, $!" unless -f $_; 3263 } 3264 my $perlcmd = (quotify("maybeshell", $config{PERL}))[0]; 3265 my $cmd = "$perlcmd \"-I.\" \"-Mconfigdata\" \"$dofile\" -o\"Configure\" \"".join("\" \"",@templates)."\" > \"$out.new\""; 3266 #print STDERR "DEBUG[run_dofile]: \$cmd = $cmd\n"; 3267 system($cmd); 3268 exit 1 if $? != 0; 3269 rename("$out.new", $out) || die "Can't rename $out.new, $!"; 3270} 3271 3272sub compiler_predefined { 3273 state %predefined; 3274 my $cc = shift; 3275 3276 return () if $^O eq 'VMS'; 3277 3278 die 'compiler_predefined called without a compiler command' 3279 unless $cc; 3280 3281 if (! $predefined{$cc}) { 3282 3283 $predefined{$cc} = {}; 3284 3285 # collect compiler pre-defines from gcc or gcc-alike... 3286 open(PIPE, "$cc -dM -E -x c /dev/null 2>&1 |"); 3287 while (my $l = <PIPE>) { 3288 $l =~ m/^#define\s+(\w+(?:\(\w+\))?)(?:\s+(.+))?/ or last; 3289 $predefined{$cc}->{$1} = $2 // ''; 3290 } 3291 close(PIPE); 3292 } 3293 3294 return %{$predefined{$cc}}; 3295} 3296 3297sub which 3298{ 3299 my ($name)=@_; 3300 3301 if (eval { require IPC::Cmd; 1; }) { 3302 IPC::Cmd->import(); 3303 return scalar IPC::Cmd::can_run($name); 3304 } else { 3305 # if there is $directories component in splitpath, 3306 # then it's not something to test with $PATH... 3307 return $name if (File::Spec->splitpath($name))[1]; 3308 3309 foreach (File::Spec->path()) { 3310 my $fullpath = catfile($_, "$name$target{exe_extension}"); 3311 if (-f $fullpath and -x $fullpath) { 3312 return $fullpath; 3313 } 3314 } 3315 } 3316} 3317 3318sub env 3319{ 3320 my $name = shift; 3321 my %opts = @_; 3322 3323 unless ($opts{cacheonly}) { 3324 # Note that if $ENV{$name} doesn't exist or is undefined, 3325 # $config{perlenv}->{$name} will be created with the value 3326 # undef. This is intentional. 3327 3328 $config{perlenv}->{$name} = $ENV{$name} 3329 if ! exists $config{perlenv}->{$name}; 3330 } 3331 return $config{perlenv}->{$name}; 3332} 3333 3334# Configuration printer ############################################## 3335 3336sub print_table_entry 3337{ 3338 local $now_printing = shift; 3339 my %target = resolve_config($now_printing); 3340 my $type = shift; 3341 3342 # Don't print the templates 3343 return if $target{template}; 3344 3345 my @sequence = ( 3346 "sys_id", 3347 "cpp", 3348 "cppflags", 3349 "defines", 3350 "includes", 3351 "cc", 3352 "cflags", 3353 "unistd", 3354 "ld", 3355 "lflags", 3356 "loutflag", 3357 "ex_libs", 3358 "bn_ops", 3359 "apps_aux_src", 3360 "cpuid_asm_src", 3361 "uplink_aux_src", 3362 "bn_asm_src", 3363 "ec_asm_src", 3364 "des_asm_src", 3365 "aes_asm_src", 3366 "bf_asm_src", 3367 "md5_asm_src", 3368 "cast_asm_src", 3369 "sha1_asm_src", 3370 "rc4_asm_src", 3371 "rmd160_asm_src", 3372 "rc5_asm_src", 3373 "wp_asm_src", 3374 "cmll_asm_src", 3375 "modes_asm_src", 3376 "padlock_asm_src", 3377 "chacha_asm_src", 3378 "poly1035_asm_src", 3379 "thread_scheme", 3380 "perlasm_scheme", 3381 "dso_scheme", 3382 "shared_target", 3383 "shared_cflag", 3384 "shared_defines", 3385 "shared_ldflag", 3386 "shared_rcflag", 3387 "shared_extension", 3388 "dso_extension", 3389 "obj_extension", 3390 "exe_extension", 3391 "ranlib", 3392 "ar", 3393 "arflags", 3394 "aroutflag", 3395 "rc", 3396 "rcflags", 3397 "rcoutflag", 3398 "mt", 3399 "mtflags", 3400 "mtinflag", 3401 "mtoutflag", 3402 "multilib", 3403 "build_scheme", 3404 ); 3405 3406 if ($type eq "TABLE") { 3407 print "\n"; 3408 print "*** $now_printing\n"; 3409 foreach (@sequence) { 3410 if (ref($target{$_}) eq "ARRAY") { 3411 printf "\$%-12s = %s\n", $_, join(" ", @{$target{$_}}); 3412 } else { 3413 printf "\$%-12s = %s\n", $_, $target{$_}; 3414 } 3415 } 3416 } elsif ($type eq "HASH") { 3417 my $largest = 3418 length((sort { length($a) <=> length($b) } @sequence)[-1]); 3419 print " '$now_printing' => {\n"; 3420 foreach (@sequence) { 3421 if ($target{$_}) { 3422 if (ref($target{$_}) eq "ARRAY") { 3423 print " '",$_,"'"," " x ($largest - length($_))," => [ ",join(", ", map { "'$_'" } @{$target{$_}})," ],\n"; 3424 } else { 3425 print " '",$_,"'"," " x ($largest - length($_))," => '",$target{$_},"',\n"; 3426 } 3427 } 3428 } 3429 print " },\n"; 3430 } 3431} 3432 3433# Utility routines ################################################### 3434 3435# On VMS, if the given file is a logical name, File::Spec::Functions 3436# will consider it an absolute path. There are cases when we want a 3437# purely syntactic check without checking the environment. 3438sub isabsolute { 3439 my $file = shift; 3440 3441 # On non-platforms, we just use file_name_is_absolute(). 3442 return file_name_is_absolute($file) unless $^O eq "VMS"; 3443 3444 # If the file spec includes a device or a directory spec, 3445 # file_name_is_absolute() is perfectly safe. 3446 return file_name_is_absolute($file) if $file =~ m|[:\[]|; 3447 3448 # Here, we know the given file spec isn't absolute 3449 return 0; 3450} 3451 3452# Makes a directory absolute and cleans out /../ in paths like foo/../bar 3453# On some platforms, this uses rel2abs(), while on others, realpath() is used. 3454# realpath() requires that at least all path components except the last is an 3455# existing directory. On VMS, the last component of the directory spec must 3456# exist. 3457sub absolutedir { 3458 my $dir = shift; 3459 3460 # realpath() is quite buggy on VMS. It uses LIB$FID_TO_NAME, which 3461 # will return the volume name for the device, no matter what. Also, 3462 # it will return an incorrect directory spec if the argument is a 3463 # directory that doesn't exist. 3464 if ($^O eq "VMS") { 3465 return rel2abs($dir); 3466 } 3467 3468 # We use realpath() on Unix, since no other will properly clean out 3469 # a directory spec. 3470 use Cwd qw/realpath/; 3471 3472 return realpath($dir); 3473} 3474 3475# Check if all paths are one and the same, using stat. They must both exist 3476# We need this for the cases when File::Spec doesn't detect case insensitivity 3477# (File::Spec::Unix assumes case sensitivity) 3478sub samedir { 3479 die "samedir expects two arguments\n" unless scalar @_ == 2; 3480 3481 my @stat0 = stat($_[0]); # First argument 3482 my @stat1 = stat($_[1]); # Second argument 3483 3484 die "Couldn't stat $_[0]" unless @stat0; 3485 die "Couldn't stat $_[1]" unless @stat1; 3486 3487 # Compare device number 3488 return 0 unless ($stat0[0] == $stat1[0]); 3489 # Compare "inode". The perl manual recommends comparing as 3490 # string rather than as number. 3491 return 0 unless ($stat0[1] eq $stat1[1]); 3492 3493 return 1; # All the same 3494} 3495 3496sub quotify { 3497 my %processors = ( 3498 perl => sub { my $x = shift; 3499 $x =~ s/([\\\$\@"])/\\$1/g; 3500 return '"'.$x.'"'; }, 3501 maybeshell => sub { my $x = shift; 3502 (my $y = $x) =~ s/([\\\"])/\\$1/g; 3503 if ($x ne $y || $x =~ m|\s|) { 3504 return '"'.$y.'"'; 3505 } else { 3506 return $x; 3507 } 3508 }, 3509 ); 3510 my $for = shift; 3511 my $processor = 3512 defined($processors{$for}) ? $processors{$for} : sub { shift; }; 3513 3514 return map { $processor->($_); } @_; 3515} 3516 3517# collect_from_file($filename, $line_concat_cond_re, $line_concat) 3518# $filename is a file name to read from 3519# $line_concat_cond_re is a regexp detecting a line continuation ending 3520# $line_concat is a CODEref that takes care of concatenating two lines 3521sub collect_from_file { 3522 my $filename = shift; 3523 my $line_concat_cond_re = shift; 3524 my $line_concat = shift; 3525 3526 open my $fh, $filename || die "unable to read $filename: $!\n"; 3527 return sub { 3528 my $saved_line = ""; 3529 $_ = ""; 3530 while (<$fh>) { 3531 s|\R$||; 3532 if (defined $line_concat) { 3533 $_ = $line_concat->($saved_line, $_); 3534 $saved_line = ""; 3535 } 3536 if (defined $line_concat_cond_re && /$line_concat_cond_re/) { 3537 $saved_line = $_; 3538 next; 3539 } 3540 return $_; 3541 } 3542 die "$filename ending with continuation line\n" if $_; 3543 close $fh; 3544 return undef; 3545 } 3546} 3547 3548# collect_from_array($array, $line_concat_cond_re, $line_concat) 3549# $array is an ARRAYref of lines 3550# $line_concat_cond_re is a regexp detecting a line continuation ending 3551# $line_concat is a CODEref that takes care of concatenating two lines 3552sub collect_from_array { 3553 my $array = shift; 3554 my $line_concat_cond_re = shift; 3555 my $line_concat = shift; 3556 my @array = (@$array); 3557 3558 return sub { 3559 my $saved_line = ""; 3560 $_ = ""; 3561 while (defined($_ = shift @array)) { 3562 s|\R$||; 3563 if (defined $line_concat) { 3564 $_ = $line_concat->($saved_line, $_); 3565 $saved_line = ""; 3566 } 3567 if (defined $line_concat_cond_re && /$line_concat_cond_re/) { 3568 $saved_line = $_; 3569 next; 3570 } 3571 return $_; 3572 } 3573 die "input text ending with continuation line\n" if $_; 3574 return undef; 3575 } 3576} 3577 3578# collect_information($lineiterator, $line_continue, $regexp => $CODEref, ...) 3579# $lineiterator is a CODEref that delivers one line at a time. 3580# All following arguments are regex/CODEref pairs, where the regexp detects a 3581# line and the CODEref does something with the result of the regexp. 3582sub collect_information { 3583 my $lineiterator = shift; 3584 my %collectors = @_; 3585 3586 while(defined($_ = $lineiterator->())) { 3587 s|\R$||; 3588 my $found = 0; 3589 if ($collectors{"BEFORE"}) { 3590 $collectors{"BEFORE"}->($_); 3591 } 3592 foreach my $re (keys %collectors) { 3593 if ($re !~ /^OTHERWISE|BEFORE|AFTER$/ && /$re/) { 3594 $collectors{$re}->($lineiterator); 3595 $found = 1; 3596 }; 3597 } 3598 if ($collectors{"OTHERWISE"}) { 3599 $collectors{"OTHERWISE"}->($lineiterator, $_) 3600 unless $found || !defined $collectors{"OTHERWISE"}; 3601 } 3602 if ($collectors{"AFTER"}) { 3603 $collectors{"AFTER"}->($_); 3604 } 3605 } 3606} 3607 3608# tokenize($line) 3609# $line is a line of text to split up into tokens 3610# returns a list of tokens 3611# 3612# Tokens are divided by spaces. If the tokens include spaces, they 3613# have to be quoted with single or double quotes. Double quotes 3614# inside a double quoted token must be escaped. Escaping is done 3615# with backslash. 3616# Basically, the same quoting rules apply for " and ' as in any 3617# Unix shell. 3618sub tokenize { 3619 my $line = my $debug_line = shift; 3620 my @result = (); 3621 3622 while ($line =~ s|^\s+||, $line ne "") { 3623 my $token = ""; 3624 while ($line ne "" && $line !~ m|^\s|) { 3625 if ($line =~ m/^"((?:[^"\\]+|\\.)*)"/) { 3626 $token .= $1; 3627 $line = $'; 3628 } elsif ($line =~ m/^'([^']*)'/) { 3629 $token .= $1; 3630 $line = $'; 3631 } elsif ($line =~ m/^(\S+)/) { 3632 $token .= $1; 3633 $line = $'; 3634 } 3635 } 3636 push @result, $token; 3637 } 3638 3639 if ($ENV{CONFIGURE_DEBUG_TOKENIZE}) { 3640 print STDERR "DEBUG[tokenize]: Parsed '$debug_line' into:\n"; 3641 print STDERR "DEBUG[tokenize]: ('", join("', '", @result), "')\n"; 3642 } 3643 return @result; 3644} 3645