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