#!/usr/bin/perl
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# Configure
#
# This script builds nmake and visual studio build files
#
require 5.000;
use strict;
use File::Spec;
use Cwd;
# files to configure
my $configfile = "..\\config.h";
my $platformfile = "..\\lib\\isc\\win32\\include\\isc\\platform.h";
my $confshfile = "..\\bin\\tests\\system\\conf.sh";
my $icshfile = "..\\isc-config.sh";
my @filelist = ("..\\bin\\python\\dnssec-checkds.py",
"..\\bin\\python\\dnssec-coverage.py",
"..\\bin\\python\\dnssec-keymgr.py",
"..\\bin\\python\\isc\\__init__.py",
"..\\bin\\python\\isc\\checkds.py",
"..\\bin\\python\\isc\\coverage.py",
"..\\bin\\python\\isc\\dnskey.py",
"..\\bin\\python\\isc\\eventlist.py",
"..\\bin\\python\\isc\\keydict.py",
"..\\bin\\python\\isc\\keyevent.py",
"..\\bin\\python\\isc\\keymgr.py",
"..\\bin\\python\\isc\\keyseries.py",
"..\\bin\\python\\isc\\keyzone.py",
"..\\bin\\python\\isc\\policy.py",
"..\\bin\\python\\isc\\rndc.py",
"..\\bin\\python\\isc\\tests\\dnskey_test.py",
"..\\bin\\python\\isc\\tests\\policy_test.py",
"..\\bin\\python\\isc\\utils.py",
"..\\lib\\dns\\win32\\libdns.def",
"..\\lib\\isc\\win32\\libisc.def");
my @projectlist = ("..\\bin\\check\\win32\\checkconf.vcxproj",
"..\\bin\\check\\win32\\checkconf.vcxproj.filters",
"..\\bin\\check\\win32\\checktool.vcxproj",
"..\\bin\\check\\win32\\checktool.vcxproj.filters",
"..\\bin\\check\\win32\\checkzone.vcxproj",
"..\\bin\\check\\win32\\checkzone.vcxproj.filters",
"..\\bin\\confgen\\win32\\confgentool.vcxproj",
"..\\bin\\confgen\\win32\\confgentool.vcxproj.filters",
"..\\bin\\confgen\\win32\\ddnsconfgen.vcxproj",
"..\\bin\\confgen\\win32\\ddnsconfgen.vcxproj.filters",
"..\\bin\\confgen\\win32\\rndcconfgen.vcxproj",
"..\\bin\\confgen\\win32\\rndcconfgen.vcxproj.filters",
"..\\bin\\delv\\win32\\delv.vcxproj",
"..\\bin\\delv\\win32\\delv.vcxproj.filters",
"..\\bin\\dig\\win32\\dig.vcxproj",
"..\\bin\\dig\\win32\\dig.vcxproj.filters",
"..\\bin\\dig\\win32\\dighost.vcxproj",
"..\\bin\\dig\\win32\\dighost.vcxproj.filters",
"..\\bin\\dig\\win32\\host.vcxproj",
"..\\bin\\dig\\win32\\host.vcxproj.filters",
"..\\bin\\dig\\win32\\nslookup.vcxproj",
"..\\bin\\dig\\win32\\nslookup.vcxproj.filters",
"..\\bin\\dnssec\\win32\\cds.vcxproj",
"..\\bin\\dnssec\\win32\\cds.vcxproj.filters",
"..\\bin\\dnssec\\win32\\dnssectool.vcxproj",
"..\\bin\\dnssec\\win32\\dnssectool.vcxproj.filters",
"..\\bin\\dnssec\\win32\\dsfromkey.vcxproj",
"..\\bin\\dnssec\\win32\\dsfromkey.vcxproj.filters",
"..\\bin\\dnssec\\win32\\importkey.vcxproj",
"..\\bin\\dnssec\\win32\\importkey.vcxproj.filters",
"..\\bin\\dnssec\\win32\\keyfromlabel.vcxproj",
"..\\bin\\dnssec\\win32\\keyfromlabel.vcxproj.filters",
"..\\bin\\dnssec\\win32\\keygen.vcxproj",
"..\\bin\\dnssec\\win32\\keygen.vcxproj.filters",
"..\\bin\\dnssec\\win32\\revoke.vcxproj",
"..\\bin\\dnssec\\win32\\revoke.vcxproj.filters",
"..\\bin\\dnssec\\win32\\settime.vcxproj",
"..\\bin\\dnssec\\win32\\settime.vcxproj.filters",
"..\\bin\\dnssec\\win32\\signzone.vcxproj",
"..\\bin\\dnssec\\win32\\signzone.vcxproj.filters",
"..\\bin\\dnssec\\win32\\verify.vcxproj",
"..\\bin\\dnssec\\win32\\verify.vcxproj.filters",
"..\\bin\\named\\win32\\named.vcxproj",
"..\\bin\\named\\win32\\named.vcxproj.filters",
"..\\bin\\nsupdate\\win32\\nsupdate.vcxproj",
"..\\bin\\nsupdate\\win32\\nsupdate.vcxproj.filters",
"..\\bin\\pkcs11\\win32\\pk11destroy.vcxproj",
"..\\bin\\pkcs11\\win32\\pk11destroy.vcxproj.filters",
"..\\bin\\pkcs11\\win32\\pk11keygen.vcxproj",
"..\\bin\\pkcs11\\win32\\pk11keygen.vcxproj.filters",
"..\\bin\\pkcs11\\win32\\pk11list.vcxproj",
"..\\bin\\pkcs11\\win32\\pk11list.vcxproj.filters",
"..\\bin\\pkcs11\\win32\\pk11tokens.vcxproj",
"..\\bin\\pkcs11\\win32\\pk11tokens.vcxproj.filters",
"..\\bin\\rndc\\win32\\rndc.vcxproj",
"..\\bin\\rndc\\win32\\rndc.vcxproj.filters",
"..\\bin\\rndc\\win32\\rndcutil.vcxproj",
"..\\bin\\rndc\\win32\\rndcutil.vcxproj.filters",
"..\\bin\\tools\\win32\\arpaname.vcxproj",
"..\\bin\\tools\\win32\\arpaname.vcxproj.filters",
"..\\bin\\tools\\win32\\journalprint.vcxproj",
"..\\bin\\tools\\win32\\journalprint.vcxproj.filters",
"..\\bin\\tools\\win32\\mdig.vcxproj",
"..\\bin\\tools\\win32\\mdig.vcxproj.filters",
"..\\bin\\tools\\win32\\nsec3hash.vcxproj",
"..\\bin\\tools\\win32\\nsec3hash.vcxproj.filters",
"..\\bin\\tools\\win32\\rrchecker.vcxproj",
"..\\bin\\tools\\win32\\rrchecker.vcxproj.filters",
"..\\bin\\tests\\system\\win32\\bigkey.vcxproj",
"..\\bin\\tests\\system\\win32\\bigkey.vcxproj.filters",
"..\\bin\\tests\\system\\win32\\feature-test.vcxproj",
"..\\bin\\tests\\system\\win32\\feature-test.vcxproj.filters",
"..\\bin\\tests\\system\\win32\\gencheck.vcxproj",
"..\\bin\\tests\\system\\win32\\gencheck.vcxproj.filters",
"..\\bin\\tests\\system\\win32\\keycreate.vcxproj",
"..\\bin\\tests\\system\\win32\\keycreate.vcxproj.filters",
"..\\bin\\tests\\system\\win32\\keydelete.vcxproj",
"..\\bin\\tests\\system\\win32\\keydelete.vcxproj.filters",
"..\\bin\\tests\\system\\win32\\pipequeries.vcxproj",
"..\\bin\\tests\\system\\win32\\pipequeries.vcxproj.filters",
"..\\bin\\tests\\win32\\backtrace_test.vcxproj",
"..\\bin\\tests\\win32\\backtrace_test.vcxproj.filters",
"..\\bin\\tests\\win32\\inter_test.vcxproj",
"..\\bin\\tests\\win32\\inter_test.vcxproj.filters",
"..\\bin\\tests\\win32\\makejournal.vcxproj",
"..\\bin\\tests\\win32\\makejournal.vcxproj.filters",
"..\\bin\\tests\\win32\\rwlock_test.vcxproj",
"..\\bin\\tests\\win32\\rwlock_test.vcxproj.filters",
"..\\bin\\tests\\win32\\shutdown_test.vcxproj",
"..\\bin\\tests\\win32\\shutdown_test.vcxproj.filters",
"..\\bin\\tests\\win32\\sock_test.vcxproj",
"..\\bin\\tests\\win32\\sock_test.vcxproj.filters",
"..\\bin\\tests\\win32\\task_test.vcxproj",
"..\\bin\\tests\\win32\\task_test.vcxproj.filters",
"..\\bin\\tests\\win32\\timer_test.vcxproj",
"..\\bin\\tests\\win32\\timer_test.vcxproj.filters",
"..\\bin\\tests\\win32\\inter_test.vcxproj",
"..\\bin\\tests\\win32\\inter_test.vcxproj.filters",
"..\\bin\\tests\\win32\\rwlock_test.vcxproj",
"..\\bin\\tests\\win32\\rwlock_test.vcxproj.filters",
"..\\bin\\tests\\win32\\shutdown_test.vcxproj",
"..\\bin\\tests\\win32\\shutdown_test.vcxproj.filters",
"..\\bin\\tests\\win32\\sock_test.vcxproj",
"..\\bin\\tests\\win32\\sock_test.vcxproj.filters",
"..\\bin\\tests\\win32\\task_test.vcxproj",
"..\\bin\\tests\\win32\\task_test.vcxproj.filters",
"..\\bin\\tests\\win32\\timer_test.vcxproj",
"..\\bin\\tests\\win32\\timer_test.vcxproj.filters",
"..\\bin\\win32\\BINDInstall\\BINDInstall.vcxproj",
"..\\bin\\win32\\BINDInstall\\BINDInstall.vcxproj.filters",
"..\\lib\\bind9\\win32\\libbind9.vcxproj",
"..\\lib\\bind9\\win32\\libbind9.vcxproj.filters",
"..\\lib\\dns\\win32\\gen.vcxproj",
"..\\lib\\dns\\win32\\gen.vcxproj.filters",
"..\\lib\\dns\\win32\\libdns.vcxproj",
"..\\lib\\dns\\win32\\libdns.vcxproj.filters",
"..\\lib\\irs\\win32\\libirs.vcxproj",
"..\\lib\\irs\\win32\\libirs.vcxproj.filters",
"..\\lib\\isc\\win32\\libisc.vcxproj",
"..\\lib\\isc\\win32\\libisc.vcxproj.filters",
"..\\lib\\isccc\\win32\\libisccc.vcxproj",
"..\\lib\\isccc\\win32\\libisccc.vcxproj.filters",
"..\\lib\\isccfg\\win32\\libisccfg.vcxproj",
"..\\lib\\isccfg\\win32\\libisccfg.vcxproj.filters",
"..\\lib\\ns\\win32\\libns.vcxproj",
"..\\lib\\samples\\win32\\resolve.vcxproj",
"..\\lib\\samples\\win32\\resolve.vcxproj.filters",
"..\\lib\\samples\\win32\\async.vcxproj",
"..\\lib\\samples\\win32\\async.vcxproj.filters",
"..\\lib\\samples\\win32\\gai.vcxproj",
"..\\lib\\samples\\win32\\gai.vcxproj.filters",
"..\\lib\\samples\\win32\\update.vcxproj",
"..\\lib\\samples\\win32\\update.vcxproj.filters",
"..\\lib\\samples\\win32\\request.vcxproj",
"..\\lib\\samples\\win32\\request.vcxproj.filters",
"..\\lib\\samples\\win32\\nsprobe.vcxproj",
"..\\lib\\samples\\win32\\nsprobe.vcxproj.filters",
"..\\lib\\win32\\bindevt\\bindevt.vcxproj",
"..\\lib\\win32\\bindevt\\bindevt.vcxproj.filters",
"bind9.sln");
# for config.h
my %configdefh;
my @substdefh = ("CONFIGARGS",
"DNS_RDATASET_FIXED",
"HAVE_GEOIP",
"HAVE_GEOIP2",
"HAVE_GEOIP_CITY_V6",
"HAVE_GEOIP_V6",
"HAVE_LIBXML2",
"HAVE_OPENSSL_ED25519",
"HAVE_OPENSSL_ED448",
"HAVE_DH_GET0_KEY",
"HAVE_ECDSA_SIG_GET0",
"HAVE_RSA_SET0_KEY",
"USE_BACKTRACE",
"USE_OPENSSL",
"USE_PKCS11",
"HAVE_PKCS11_ED25519",
"HAVE_PKCS11_ED448",
"HAVE_READLINE",
"HAVE_ZLIB",
"ISC_LIST_CHECKINIT",
"TUNE_LARGE",
"WANT_QUERYTRACE",
"WITH_IDN",
"CPU_RELAX",
"VALIDATION_DEFAULT",
"HAVE_CRYPTO_ZALLOC",
"HAVE_EVP_CIPHER_CTX_FREE",
"HAVE_EVP_CIPHER_CTX_NEW",
"HAVE_EVP_MD_CTX_FREE",
"HAVE_EVP_MD_CTX_NEW",
"HAVE_EVP_MD_CTX_RESET",
"HAVE_HMAC_CTX_FREE",
"HAVE_HMAC_CTX_GET_MD",
"HAVE_HMAC_CTX_NEW",
"HAVE_HMAC_CTX_RESET",
);
# for platform.h
my %configdefp;
my @substdefp = ();
# for conf.sh
my %configtest;
my @substtest = ("CHECKDS",
"COVERAGE",
"DNSTAP",
"FSTRM_CAPTURE",
"JSONSTATS",
"KEYMGR",
"NZD_TOOLS",
"XMLSTATS",
"ZLIB"),
# includes
my %configinc;
my @substinc = ("GSSAPI_INC",
"GEOIP_INC",
"IDN_INC",
"LIBXML2_INC",
"OPENSSL_INC",
"READLINE_INC",
"ZLIB_INC");
# libraries
my %configlib;
my @substlib = ("GSSAPI_LIB",
"GEOIP_LIB",
"IDN_LIB",
"KRB5_LIB",
"LIBXML2_LIB",
"OPENSSL_LIB",
"READLINE_LIB",
"READLINE_LIBD",
"ZLIB_LIB");
# DLLs
my %configdll;
my @substdll = ("COMERR_DLL",
"GSSAPI_DLL",
"GEOIP_DLL",
"ICONV_DLL",
"IDN_DLL",
"KRB5_DLL",
"K5SPRT_DLL",
"LIBXML2_DLL",
"OPENSSL_DLL",
"WSHELP_DLL",
"ZLIB_DLL");
# variables
my %configvar = (
"TOOLS_VERSION" => "4.0",
);
my @substvar = ("BIND9_VERSION",
"BUILD_MACHINE",
"BUILD_PLATFORM",
"COPTI",
"COPTML",
"COPTMLD",
"COPTX",
"COPTY",
"DLZ_SYSTEM_TEST",
"EXEEXT",
"expanded_sysconfdir",
"INTRINSIC",
"MACHINE",
"OPENSSL_PATH",
"PLATFORM",
"PKCS11_TOOLS",
"PLATFORM_TOOLSET",
"prefix",
"PSSUSPEND",
"PYTHON",
"PYTHON_INSTALL_DIR",
"TOOLS_VERSION",
"VCREDIST_PATH",
"WINDOWS_TARGET_PLATFORM_VERSION"),
# defines
my %configdefd;
my @substdefd = ("PK11_LIB_LOCATION",
"USE_GSSAPI",
"USE_PYTHON",
"USE_ISC_SPNEGO");
# conditions
my %configcond;
my @substcond = ("ATOMIC",
"GSSAPI",
"GEOIP",
"GEOIPLEGACY",
"IDNKIT",
"LIBXML2",
"OPENSSL",
"PKCS11",
"PYTHON",
"SAMPLES",
"STESTS",
"TESTS",
"XTESTS",
"ZLIB");
my @allcond = (@substcond, "NOTYET", "NOLONGER");
# arguments
# enable-xxx/disable-xxx
my @enablelist = ("developer",
"fixed-rrset",
"intrinsics",
"isc-spnego",
"native-pkcs11",
"openssl-hash",
"querytrace");
# with-xxx/without-xxx
my @withlist = ("aes",
"cc-alg",
"cross-compile",
"ecdsa",
"eddsa",
"extra-tests",
"gssapi",
"geoip",
"geoip2",
"iconv",
"idn",
"openssl",
"libxml2",
"pkcs11",
"pssuspend",
"python",
"readline",
"samples",
"system-tests",
"tests",
"tuning",
"vcredist",
"zlib");
# general arguments
my @optionlist = ("help", "verbose", "legacy", "win32", "x64", "clean");
# usage
my @usage = ("Usage: perl Configure help\n",
" perl Configure options* win32|x64\n",
" perl Configure clean\n");
# help
my @help = (
"'Configure' configures BIND9 build files.\n\n",
@usage,
"\nGeneral Options and Commands:\n",
" verbose (options) print messages\n",
" help (command) print this help\n",
" win32 (command) configure for Win32 platform\n",
" x64 (command) configure for x64 platform\n",
" clean (command) clean up generated files\n",
" <none> (command) print a summary of the configuration\n",
"\nOptional Features:\n",
" enable-intrinsics enable instrinsic/atomic functions [default=yes]\n",
" enable-native-pkcs11 use native PKCS#11 for all crypto [default=no]\n",
" enable-openssl-hash use OpenSSL for hash functions [default=yes]\n",
" enable-isc-spnego use SPNEGO from lib/dns [default=yes]\n",
" enable-fixed-rrset enable fixed rrset ordering [default=no]\n",
" enable-developer enable developer build settings [default=no]\n",
" enable-querytrace enable very verbose query trace [default=no]\n",
"\nOptional Packages:\n",
" with-tests build with test suite\n",
" with-extra-tests build with extra test suite\n",
" with-system-tests build with system test suite\n",
" with-samples build with sample programs\n",
" with-openssl[=PATH] build with OpenSSL yes|path (mandatory)\n",
" with-pkcs11[=PATH] build with PKCS#11 support yes|no|provider-path\n",
" with-eddsa crypto EDDSA yes|all|no\n",
" with-cc-alg choose the algorithm for cookies aes|sha1|sha256\n",
" with-gssapi[=PATH] build with MIT KfW GSSAPI yes|no|path\n",
" with-libxml2[=PATH] build with libxml2 library yes|no|path\n",
" with-geoip[=PATH] build with GeoIP support yes|no|path\n",
" with-geoip2[=PATH] build with GeoIP2 support yes|no|path\n",
" with-pssuspend[=COMMAND] specify pssuspend command\n",
" with-python[=COMMAND] specify python interpreter python|command\n",
" with-readline[=PATH] build with readline library support yes|no|path\n",
" with-idn[=PATH] build with IDN kit support yes|no|path\n",
" with-iconv[=PATH] path of the iconv DLL [default=same than idn]\n",
" with-zlib[=PATH] build with zlib library yes|no|path\n",
" with-vcredist[=PATH] visual C++ redistributable package yes|path\n",
" with-tuning=OPTION tune for platform size (large|default)\n",
" with-cross-compile 32 / 64 bit build / host platforms\n",
"\nOptional Visual Studio project parameters:\n",
" with-tools-version=VERSION set the ToolsVersion attribute to VERSION\n",
" with-platform-toolset=VERSION use supplied toolset VERSION for building\n",
" with-platform-version=VERSION use supplied Windows SDK VERSION for building\n");
# Parse arguments
my $verbose = 0;
my $legacy_only = 0;
my $want_help = "no";
my $want_win32 = "no";
my $want_x64 = "no";
my $want_clean = "no";
my $want_unknown = "no";
my $unknown_value;
my $enable_intrinsics = "yes";
my $cryptolib = "";
my $enable_native_pkcs11 = "no";
my $enable_crypto_rand = "yes";
my $enable_isc_spnego = "yes";
my $enable_fixed_rrset = "no";
my $enable_developer = "no";
my $enable_querytrace = "no";
my $enable_rpz_nsip = "yes";
my $enable_rpz_nsdname = "yes";
my $use_tests = "no";
my $use_xtests = "no";
my $use_stests = "no";
my $use_samples = "no";
my $use_openssl = "auto";
my $openssl_path = "..\\..\\";
my $use_pkcs11 = "no";
my $pkcs11_path = "unknown";
my $use_eddsa = "auto";
my $use_ed448 = "auto";
my $use_aes = "auto";
my $cookie_algorithm = "aes";
my $use_gssapi = "no";
my $validation_default = "auto";
my $gssapi_path = "C:\\Program\ Files\\MIT\\Kerberos\\";
my $use_geoip = "no";
my $geoip_path = "";
my $use_geoip2 = "no";
my $geoip2_path = "";
my $use_libxml2 = "auto";
my $libxml2_path = "..\\..\\";
my $with_pssuspend = "no";
my $pssuspend_command = "pssuspend.exe";
my $use_python = "auto";
my $python_command = "python.exe";
my $use_readline = "no";
my $readline_path = "..\\..\\";
my $use_idn = "no";
my $idn_path = "..\\..\\";
my $iconv_path = " --idn-- ";
my $use_zlib = "no";
my $zlib_path = "..\\..\\";
my $use_vcredist = "yes";
my $vcredist_path = " --infer-- ";
my $cross_compile = "no";
my $tuning = "default";
my $want_checkfiles = "no";
# no arguments -> usage
if ($#ARGV < 0) {
foreach (@usage) {
print $_;
}
exit 1;
}
# parse arguments
foreach (@ARGV) {
if (/^verbose$/i) {
$verbose = 1;
} elsif (/^help$/i) {
$want_help = "yes";
} elsif (/^disable-(.*)$/i) {
appargs($_);
myenable($1, "no");
} elsif (/^enable-(.*)$/i) {
appargs($_);
myenable($1, "yes");
} elsif (/^without-(.*)$/i) {
appargs($_);
mywith($1, "no");
} elsif (/^with-(.*)=(.*)$/i) {
appargs($_);
mywith($1, $2);
} elsif (/^with-(.*)$/i) {
appargs($_);
mywith($1, "yes");
} elsif (/^legacy$/i) {
$legacy_only = 1;
} elsif (/^win32$/i) {
$want_win32 = "yes";
} elsif (/^x64$/i) {
appargs($_);
$want_x64 = "yes";
} elsif (/^clean$/i) {
$want_clean = "yes";
} elsif (/^checkfiles$/i) {
$want_checkfiles = "yes";
} else {
$want_unknown = "yes";
$unknown_value = $_;
}
}
# old legacy mode
if ($legacy_only) {
print "legacy mode is obsolete (so ignored)\n";
}
if ($want_checkfiles eq "yes") {
my $status=0;
foreach (@filelist) {
my $name = $_;
$name =~ s/\\/\\\\/g;
next if -r $_ . ".in";
s/\\/\//g;
next if -r $_ . ".in";
print "remove '$name' from filelist in win32utils/Configure or add to repository\n";
$status = 1;
}
foreach (@projectlist) {
my $name = $_;
$name =~ s/\\/\\\\/g;
next if -r $_ . ".in";
s/\\/\//g;
next if -r $_ . ".in";
print "remove '$name' from projectlist in win32utils/Configure or add to repository\n";
$status = 1;
}
exit($status);
}
# configure the platform
if (($want_win32 eq "yes") && ($want_x64 eq "yes")) {
die "can't ask for both Win32 and x64 platforms\n";
} elsif ($want_win32 eq "yes") {
$configvar{"PLATFORM"} = "Win32";
$configvar{"BUILD_PLATFORM"} = "Win32";
$configvar{"MACHINE"} = "/machine:X86";
$configvar{"BUILD_MACHINE"} = "/machine:X86";
} elsif ($want_x64 eq "yes") {
$configvar{"PLATFORM"} = "x64";
$configvar{"BUILD_PLATFORM"} = "x64";
$configvar{"MACHINE"} = "/machine:X64";
$configvar{"BUILD_MACHINE"} = "/machine:X64";
}
# Standard configure variable
$configvar{"EXEEXT"} = ".exe";
# get the version information
my %Versions;
sub getversion {
my $data;
my $name;
my $value;
my $version;
open V, "..\\version" || die $!;
while (<V>) {
chomp;
($data) = split(/\#/);
if ($data) {
($name, $value) = split(/=/, $data);
($name) = split(/\s+/, $name);
if ($name eq 'PRODUCT' || $name eq 'DESCRIPTION') {
($value) =~ s/^["\s]+//;
($value) =~ s/["\s]+$//;
} else {
($value) = split(/\s+/, $value);
}
$Versions{$name} = $value;
}
}
close V;
$version = "$Versions{'MAJORVER'}.$Versions{'MINORVER'}";
if ($Versions{'PATCHVER'} ne "") {
$version = "$version.$Versions{'PATCHVER'}";
}
$version = "$version$Versions{'RELEASETYPE'}$Versions{'RELEASEVER'}";
$version = "$version$Versions{'EXTENSIONS'}";
$configvar{"BIND9_VERSION"} = "$version";
}
getversion();
# append seen args to CONFIGARGS define
sub appargs {
my $arg = $_[0];
# escape backslashes, spaces and double quotes
$arg =~ s/([\\ "])/\\$1/g;
if (defined($configdefh{"CONFIGARGS"})) {
$configdefh{"CONFIGARGS"} .= " " . $arg;
} else {
$configdefh{"CONFIGARGS"} = $arg;
}
}
if (!$configdefh{"CONFIGARGS"}) {
# CONFIGARGS default is "default"
$configdefh{"CONFIGARGS"} = "\"default\"";
} else {
my $val = $configdefh{"CONFIGARGS"};
$configdefh{"CONFIGARGS"} = "\"'$val'\"";
}
# parse enable/disable
sub myenable {
my $key = $_[0];
my $val = $_[1];
if ($key =~ /^intrinsics$/i) {
if ($val =~ /^no$/i) {
$enable_intrinsics = "no";
}
} elsif ($key =~ /^native-pkcs11$/i) {
if ($val =~ /^yes$/i) {
$enable_native_pkcs11 = "yes";
}
} elsif ($key =~ /^isc-spnego$/i) {
if ($val =~ /^no$/i) {
$enable_isc_spnego = "no";
}
} elsif ($key =~ /^fixed-rrset$/i) {
if ($val =~ /^yes$/i) {
$enable_fixed_rrset = "yes";
}
} elsif ($key =~ /^developer$/i) {
if ($val =~ /^yes$/i) {
$enable_developer = "yes";
}
} elsif ($key =~ /^querytrace$/i) {
if ($val =~ /^yes$/i) {
$enable_querytrace = "yes";
}
} elsif ($key =~ /^auto-validation$/i) {
if ($val =~ /^no$/i) {
$validation_default = "yes";
}
} else {
$want_unknown = "yes";
if ($val eq "no") {
$unknown_value = "disable-" . $key;
} else {
$unknown_value = "enable-". $key;
}
}
}
# enable-developer expansion now
if ($enable_developer eq "yes") {
$configdefh{"ISC_LIST_CHECKINIT"} = 1;
$enable_querytrace = "yes";
# no atf on WIN32
$enable_fixed_rrset = "yes";
# TODO: dlz filesystem
$use_tests = "yes";
$use_xtests = "yes";
$use_stests = "yes";
$use_samples = "yes";
}
# parse with/without
sub mywith {
my $key = $_[0];
my $val = $_[1];
if ($key =~ /^tests$/i) {
if ($val =~ /^yes$/i) {
$use_tests = "yes";
}
} elsif ($key =~ /^extra-tests$/i) {
if ($val =~ /^yes$/i) {
$use_tests = "yes";
$use_xtests = "yes";
}
} elsif ($key =~ /^system-tests$/i) {
if ($val =~ /^yes$/i) {
$use_tests = "yes";
$use_stests = "yes";
}
} elsif ($key =~ /^samples$/i) {
if ($val =~ /^yes$/i) {
$use_samples = "yes";
}
} elsif ($key =~ /^openssl$/i) {
if ($val =~ /^no$/i) {
die "OpenSSL support is now mandatory\n";
} elsif ($val !~ /^yes$/i) {
$use_openssl = "yes";
$openssl_path = $val;
}
} elsif ($key =~ /^pkcs11$/i) {
if ($val =~ /^yes$/i) {
$use_pkcs11 = "yes";
} elsif ($val !~ /^no$/i) {
$use_pkcs11= "yes";
$pkcs11_path = $val;
$pkcs11_path =~ s/\.dll$//i;
}
} elsif ($key =~ /^eddsa$/i) {
if ($val =~ /^no$/i) {
$use_eddsa = "no";
} elsif ($val !~ /^no$/i) {
$use_eddsa = "yes";
if ($val =~ /^all$/i) {
$use_ed448 = "yes";
}
}
} elsif ($key =~ /^aes$/i) {
if ($val =~ /^no$/i) {
$use_aes = "no";
} elsif ($val =~ /^yes$/i) {
$use_aes = "yes";
}
} elsif ($key =~ /^cc-alg$/i) {
$cookie_algorithm = $val;
} elsif ($key =~ /^gssapi$/i) {
if ($val !~ /^no$/i) {
$use_gssapi = "yes";
if ($val !~ /^yes$/i) {
$gssapi_path = $val;
}
}
} elsif ($key =~ /^libxml2$/i) {
if ($val =~ /^no$/i) {
$use_libxml2 = "no";
} elsif ($val !~ /^yes$/i) {
$use_libxml2 = "yes";
$libxml2_path = $val;
}
} elsif ($key =~ /^geoip$/i) {
if ($val !~ /^no$/i) {
$use_geoip = "yes";
if ($val !~ /^yes$/i) {
$geoip_path = $val;
}
}
} elsif ($key =~ /^geoip2$/i) {
if ($val !~ /^no$/i) {
$use_geoip2 = "yes";
# Disable GeoIP legacy.
$use_geoip = "no";
if ($val !~ /^yes$/i) {
$geoip2_path = $val;
} else {
$geoip2_path = "..\\..\\GeoIP2";
}
}
} elsif ($key =~ /^readline$/i) {
if ($val !~ /^no$/i) {
$use_readline = "yes";
if ($val !~ /^yes$/i) {
$readline_path = $val;
}
}
} elsif ($key =~ /^idn$/i) {
if ($val !~ /^no$/i) {
$use_idn = "yes";
if ($val !~ /^yes$/i) {
$idn_path = $val;
}
}
} elsif ($key =~ /^iconv$/i) {
if ($val =~ /^no$/i) {
$want_unknown = "yes";
$unknown_value = "without-iconv doesn't make sense)";
} elsif ($val !~ /^yes$/i) {
$iconv_path = $val;
}
} elsif ($key =~ /^zlib$/i) {
if ($val !~ /^no$/i) {
$use_zlib = "yes";
if ($val !~ /^yes$/i) {
$zlib_path = $val;
}
}
} elsif ($key =~ /^pssuspend$/i) {
if ($val =~ /^no$/i) {
$with_pssuspend = "no";
} else {
if ($val !~ /^yes$/i) {
$pssuspend_command = $val;
}
}
} elsif ($key =~ /^python$/i) {
if ($val =~ /^no$/i) {
$use_python = "no";
} else {
$use_python = "yes";
if ($val !~ /^yes$/i) {
$python_command = $val;
}
}
} elsif ($key =~ /^vcredist$/i) {
if ($val =~ /^no$/i) {
$want_unknown = "yes";
$unknown_value = "without-vcredist (vcredist is required)";
} elsif ($val !~ /^yes$/i) {
$vcredist_path = $val;
}
} elsif ($key =~ /^cross-compile$/i) {
if ($val =~ /^yes$/i) {
$cross_compile = "yes";
}
} elsif ($key =~ /^tuning$/i) {
if ($val =~ /^large$/i) {
$tuning = "large";
}
} elsif ($key =~ /^tools-version$/i) {
$configvar{"TOOLS_VERSION"} = $val;
} elsif ($key =~ /^platform-version$/i) {
$configvar{"WINDOWS_TARGET_PLATFORM_VERSION"} = "<WindowsTargetPlatformVersion>$val</WindowsTargetPlatformVersion>";
} elsif ($key =~ /^platform-toolset$/i) {
$configvar{"PLATFORM_TOOLSET"} = "<PlatformToolset>$val</PlatformToolset>";
} else {
$want_unknown = "yes";
if ($val eq "no") {
$unknown_value = "without-" . $key;
} else {
$unknown_value = "with-" . $key;
}
}
}
if ($want_help ne "no") {
foreach (@help) {
print $_;
}
exit 1;
}
# clean up and exit if requested
if ($want_clean eq "yes") {
my $file;
unlink($configfile);
unlink($platformfile);
unlink($confshfile);
unlink($icshfile);
foreach $file (@filelist) {
unlink($file);
}
foreach $file (@projectlist) {
unlink($file);
}
exit 0;
}
if ($want_unknown ne "no") {
print STDERR "can't parse $unknown_value\n";
exit 1;
}
if ($verbose) {
if ($want_win32 eq "yes") {
print "configure for win32\n";
}
if ($want_x64 eq "yes") {
print "configure for x64\n";
}
if ($cross_compile eq "yes") {
print "cross compiling";
if ($want_x64 eq "yes") {
print ": build on win32 for x64 host\n";
} elsif ($want_win32 eq "yes") {
print ": build on x64 for win32 host\n";
} else {
print "\n";
}
}
if ($enable_intrinsics eq "yes") {
print "intrinsics: enabled\n";
} else {
print "intrinsics: disabled\n";
}
if ($enable_native_pkcs11 eq "yes") {
print "native-pkcs11: enabled\n";
} else {
print "native-pkcs11: disabled\n";
}
print "openssl-hash: enabled\n";
if ($enable_isc_spnego eq "yes") {
print "isc-spnego: enabled\n";
} else {
print "isc-spnego: disabled\n";
}
if ($enable_fixed_rrset eq "yes") {
print "fixed-rrset: enabled\n";
} else {
print "fixed-rrset: disabled\n";
}
if ($enable_developer eq "yes") {
print "developer: enabled\n";
} else {
print "developer: disabled\n";
}
if ($enable_querytrace eq "yes") {
print "querytrace: enabled\n";
} else {
print "querytrace: disabled\n";
}
print "cookie algorithm: $cookie_algorithm\n";
print "openssl-path: $openssl_path\n";
if ($use_tests eq "yes") {
print "tests: enabled\n";
}
if ($use_xtests eq "yes") {
print "extra tests: enabled\n";
}
if ($use_stests eq "yes") {
print "system tests: enabled\n";
}
if ($use_samples eq "yes") {
print "sample programs: enabled\n";
}
if ($use_pkcs11 eq "no") {
print "pkcs11: disabled\n";
} else {
print "pkcs11-provider-path: $pkcs11_path\n";
}
print "ecdsa: enabled\n";
if ($use_eddsa eq "no") {
print "eddsa: disabled\n";
} else {
print "ed25519: enabled\n";
if ($use_ed448 eq "no") {
print "ed448: disabled\n";
} else {
print "ed448: enabled\n";
}
}
if ($use_aes eq "no") {
print "aes: disabled\n";
} else {
print "aes: enabled\n";
}
if ($use_gssapi eq "no") {
print "gssapi: disabled\n";
} else {
print "gssapi-path: $gssapi_path\n";
}
if ($use_libxml2 eq "no") {
print "libxml2: disabled\n";
} else {
print "libxml2-path: $libxml2_path\n";
}
if ($use_geoip eq "no") {
print "geoip: disabled\n";
} else {
print "geoip-path: $geoip_path\n";
}
if ($use_geoip2 eq "no") {
print "geoip2: disabled\n";
} else {
print "geoip2-path: $geoip2_path\n";
}
if ($use_readline eq "no") {
print "readline: disabled\n";
} else {
print "readline-path: $readline_path\n";
}
if ($use_idn eq "no") {
print "idn: disabled\n";
} else {
print "idn-path: $idn_path\n";
if ($iconv_path ne " --idn-- ") {
print "iconv-path: $iconv_path\n";
}
}
if ($use_zlib eq "no") {
print "zlib: disabled\n";
} else {
print "zlib-path: $zlib_path\n";
}
if ($with_pssuspend eq "no") {
print "pssuspend: disabled\n";
} else {
print "pssuspend-command: $pssuspend_command\n";
}
if ($use_python eq "no") {
print "python: disabled\n";
} else {
print "python-command: $python_command\n";
}
print "vcredist-path: $vcredist_path\n";
}
# Check environment
# infer vcredist when not given
if ($vcredist_path eq " --infer-- ") {
if ($verbose) {
print "trying to infer vcredist path from build environment\n";
}
my @vcpaths = {};
push(@vcpaths, $ENV{"VCRedistPath"}) if ($ENV{"VCRedistPath"} ne "");
push(@vcpaths, File::Spec->catfile( cwd(), "..", ".." ));
if ($ENV{"FrameworkSDKDir"} ne "" && $want_win32 eq "yes") {
push(@vcpaths, File::Spec->catfile($ENV{"FrameworkSDKDir"},
"BootStrapper", "Packages",
"vcredist_x86"));
} elsif ($ENV{"FrameworkSDKDir"} ne "" && $want_x64 eq "yes") {
push(@vcpaths, File::Spec->catfile($ENV{"FrameworkSDKDir"},
"BootStrapper", "Packages",
"vcredist_x64"));
}
if ($ENV{"WindowsSDKDir"} ne "" && $want_win32 eq "yes") {
push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir"},
"BootStrapper", "Packages",
"vcredist_x86"));
} elsif ($ENV{"WindowsSDKDir"} ne "" && $want_x64 eq "yes") {
push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir"},
"BootStrapper", "Packages",
"vcredist_x64"));
}
if ($ENV{"WindowsSDKDir_old"} ne "" && $want_win32 eq "yes") {
push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir_old"},
"BootStrapper", "Packages",
"vcredist_x86"));
} elsif ($ENV{"WindowsSDKDir_old"} ne "" && $want_x64 eq "yes") {
push(@vcpaths, File::Spec->catfile($ENV{"WindowsSDKDir_old"},
"BootStrapper", "Packages",
"vcredist_x64"));
}
if ($ENV{"VCINSTALLDIR"}) {
push(@vcpaths, File::Spec->catfile($ENV{"VCINSTALLDIR"},
"redist", "1033"));
}
# 'VCToolsRedistDir' is available since Visual Studio 2017.
if ($ENV{"VCToolsRedistDir"}) {
push(@vcpaths, $ENV{"VCToolsRedistDir"});
}
my $rfile;
if ($want_win32 eq "yes") {
$rfile = "vcredist_x86.exe";
} else {
$rfile = "vcredist_x64.exe";
}
foreach (@vcpaths) {
my $vp = File::Spec->catfile($_, $rfile);
if (-f $vp) {
$vcredist_path = $vp;
last;
}
}
if ($vcredist_path eq " --infer-- ") {
die "with-vcredist is REQUIRED\n";
}
if ($verbose) {
print "found vcredist at " . $vcredist_path . "\n";
}
}
my $msc_ver = 0;
open F, ">mscver.c" || die $!;
print F << 'EOF';
#include <windows.h>
#include <stdio.h>
int
main(void)
{
printf("%d\n", _MSC_VER);
return(0);
}
EOF
close F;
my $compret = `cl /nologo /MD mscver.c`;
if (grep { -f and -x } ".\\mscver.exe") {
$msc_ver = `.\\mscver.exe`;
} else {
die "can't get _MSC_VER value: $compret\n";
}
if ($verbose) {
print "_MSC_VER == $msc_ver\n";
}
if ($msc_ver < 1600) {
print STDERR "too old version of C++ compiler/Visual Studio\n";
exit 1;
}
# gen single threaded for < VS 2005
if ($msc_ver < 1400) {
$configvar{"COPTML"} = "/ML";
$configvar{"COPTMLD"} = "/MLD";
}
# /GX deprecated in VS 2005
if ($msc_ver < 1400) {
$configvar{"COPTX"} = "/GX";
} else {
$configvar{"COPTX"} = "/EHsc";
}
# /YX for < VS 2005
if ($msc_ver < 1400) {
$configvar{"COPTY"} = "/YX";
}
# backtrace for >= VS 2012
if ($msc_ver >= 1700) {
$configdefh{"USE_BACKTRACE"} = 1;
}
# warn when cross compiling
if ($cross_compile eq "yes") {
if ($want_x64 eq "yes") {
$configvar{"BUILD_PLATFORM"} = "Win32";
$configvar{"BUILD_MACHINE"} = "/machine:X86";
}
if ($want_win32 eq "yes") {
$configvar{"BUILD_PLATFORM"} = "x64";
$configvar{"BUILD_MACHINE"} = "/machine:X64";
}
} elsif ($want_win32 eq "yes") {
open F, ">cross.c" || die $!;
print F << 'EOF';
#include <windows.h>
#include <stdio.h>
int
main(void)
{
#ifdef _WIN64
fprintf(stderr, "compiling for x64 when win32 was asked?!\n");
#endif
return(0);
}
EOF
close F;
my $compret = `cl /nologo /MD cross.c`;
if (grep { -f and -x } ".\\cross.exe") {
my $cross = `.\\cross.exe`;
if ($cross) {
print STDERR $cross;
}
} else {
print STDERR "can't check cross compile: $compret\n";
}
} else {
open F, ">cross.c" || die $!;
print F << 'EOF';
#include <windows.h>
#include <stdio.h>
int
main(void)
{
#ifndef _WIN64
fprintf(stderr, "compiling in 32 bits when x64 was asked?!\n");
#endif
return(0);
}
EOF
close F;
my $compret = `cl /nologo /MD cross.c`;
if (grep { -f and -x } ".\\cross.exe") {
my $cross = `.\\cross.exe`;
if ($cross) {
print STDERR $cross;
}
} else {
print STDERR "can't check cross compile: $compret\n";
}
}
# Process arguments
# enable-native-pkcs11
if ($enable_native_pkcs11 eq "yes") {
$cryptolib = "pkcs11";
if ($use_pkcs11 ne "yes") {
if ($verbose) {
print "native PKCS#11 support: force with-pkcs11\n";
}
$use_pkcs11 = "yes";
}
if ($pkcs11_path eq "unknown") {
if ($verbose) {
print "native PKCS#11 support: no PKCS#11 provider defined?\n";
}
}
if ($use_eddsa eq "no") {
if ($verbose) {
print "no EDDSA support in native PKCS#11\n";
}
} else {
if ($verbose) {
print "enabled Ed25519 support in native PKCS#11\n";
}
$configdefh{"HAVE_PKCS11_ED25519"} = 1;
if ($use_ed448 eq "no") {
if ($verbose) {
print "no Ed448 support in native PKCS#11\n";
}
} else {
if ($verbose) {
print "enabled Ed448 support in native PKCS#11\n";
}
$configdefh{"HAVE_PKCS11_ED448"} = 1;
}
}
}
# enable-fixed-rrset
if ($enable_fixed_rrset eq "yes") {
$configdefh{"DNS_RDATASET_FIXED"} = 1;
}
# enable-querytrace
if ($enable_querytrace eq "yes") {
$configdefh{"WANT_QUERYTRACE"} = 1;
}
# with-tests
if ($use_tests eq "yes") {
$configcond{"TESTS"} = 1;
}
# with-extra-tests
if ($use_xtests eq "yes") {
$configcond{"XTESTS"} = 1;
}
# with-system-tests
if ($use_stests eq "yes") {
$configcond{"STESTS"} = 1;
}
# with-samples
if ($use_samples eq "yes") {
$configcond{"SAMPLES"} = 1;
}
# with-openssl
if ($use_openssl eq "auto") {
if ($verbose) {
print "checking for an OpenSSL built directory at sibling root\n";
}
opendir DIR, $openssl_path || die "No Directory: $!\n";
my @dirlist = grep (/^openssl-[0-9]+\.[0-9]+\.[0-9]+[a-z]{0,1}$/i,
readdir(DIR));
closedir(DIR);
# Make sure we have something
if (scalar(@dirlist) == 0) {
die "can't find an OpenSSL at sibling root\n";
}
# Now see if we have a directory or just a file.
# Make sure we are case insensitive
my $file;
foreach $file (sort {uc($b) cmp uc($a)} @dirlist) {
if (-f File::Spec->catfile($openssl_path,
$file,
"inc32\\openssl\\opensslv.h")) {
$openssl_path = File::Spec->catdir($openssl_path, $file);
$use_openssl = "yes";
last;
}
if (-f File::Spec->catfile($openssl_path,
$file,
"include\\openssl\\opensslv.h")) {
$openssl_path = File::Spec->catdir($openssl_path, $file);
$use_openssl = "yes";
last;
}
}
# If we have one use it otherwise report the error
if ($use_openssl eq "auto") {
die "can't find an OpenSSL built directory at sibling root\n";
}
}
# falls into (so no else)
if ($use_openssl eq "yes") {
$openssl_path = File::Spec->rel2abs($openssl_path);
if ($verbose) {
print "checking for OpenSSL built directory at \"$openssl_path\"\n";
}
my $openssl_new = 0;
if (!-f File::Spec->catfile($openssl_path,
"inc32\\openssl\\opensslv.h")) {
$openssl_new = 1;
if (!-f File::Spec->catfile($openssl_path,
"include\\openssl\\opensslv.h")) {
die "can't find OpenSSL opensslv.h include\n";
}
}
my $openssl_inc = File::Spec->catdir($openssl_path, "inc32");
my $openssl_libdir = File::Spec->catdir($openssl_path, "out32dll");
my $openssl_lib = File::Spec->catfile($openssl_libdir, "libeay32.lib");
my $openssl_dll = File::Spec->catfile($openssl_libdir, "libeay32.dll");
if (!$openssl_new) {
# Check libraries are where we expect
if (!-f $openssl_lib) {
die "can't find OpenSSL libeay32.lib library\n";
}
if (!-f $openssl_dll) {
die "can't find OpenSSL libeay32.dll DLL\n";
}
} else {
# OpenSSL >= 1.1 is easier at the exception of the DLL
if ($verbose) {
print "new (>= 1.1) OpenSSL version\n";
}
$openssl_inc = File::Spec->catdir($openssl_path, "include");
$openssl_libdir = $openssl_path;
$openssl_lib = File::Spec->catfile($openssl_path, "libcrypto.lib");
if (!-f $openssl_lib) {
die "can't find OpenSSL libcrypto.lib library\n";
}
opendir DIR, $openssl_path || die "No Directory: $!\n";
my @dirlist = grep (/^libcrypto-[^.]+\.dll$/i, readdir(DIR));
closedir(DIR);
# We must get one file only
if (scalar(@dirlist) == 0) {
die "can't find OpenSSL libcrypto-*.dll DLL\n";
}
if (scalar(@dirlist) != 1) {
die "find more than one OpenSSL libcrypto-*.dll DLL candidate\n";
}
$openssl_dll = File::Spec->catdir($openssl_path, "@dirlist[0]");
}
$cryptolib = "openssl";
$configvar{"OPENSSL_PATH"} = "$openssl_path";
$configinc{"OPENSSL_INC"} = "$openssl_inc";
$configlib{"OPENSSL_LIB"} = "$openssl_lib";
$configdll{"OPENSSL_DLL"} = "$openssl_dll";
}
if ($cryptolib eq "openssl") {
$configdefh{"USE_OPENSSL"} = 1;
} else {
$configdefh{"USE_PKCS11"} = 1;
}
# check OpenSSL
if ($use_openssl eq "yes") {
if ($verbose) {
print "checking whether linking with OpenSSL works\n";
}
my $dll = $configdll{"OPENSSL_DLL"};
my $ret = `copy "$dll" .`;
if ($? != 0) {
die "Can't copy OpenSSL DLL to working directory: $ret\n";
}
open F, ">testossl.c" || die $!;
print F << 'EOF';
#include <openssl/err.h>
int
main(void)
{
ERR_clear_error();
return(0);
}
EOF
close F;
my $include = $configinc{"OPENSSL_INC"};
my $library = $configlib{"OPENSSL_LIB"};
$compret = `cl /nologo /MD /I "$include" testossl.c "$library"`;
if (grep { -f and -x } ".\\testossl.exe") {
`.\\testossl.exe`;
if ($? != 0) {
die "OpenSSL test failed\n";
}
} else {
die "can't compile OpenSSL test: $compret\n";
}
}
# check OpenSSL version
if ($use_openssl eq "yes") {
if ($verbose) {
printf "checking OpenSSL library version\n";
}
open F, ">testosslv.c" || die $!;
print F << 'EOF';
#include <stdio.h>
#include <openssl/opensslv.h>
int main() {
if (OPENSSL_VERSION_NUMBER >= 0x10000000L) {
return (0);
}
printf("\n\nFound OPENSSL_VERSION_NUMBER %#010x\n",
OPENSSL_VERSION_NUMBER);
printf("Require OPENSSL_VERSION_NUMBER 0x10000000L or greater (1.0.0)\n\n");
return (1);
}
EOF
close F;
my $include = $configinc{"OPENSSL_INC"};
my $library = $configlib{"OPENSSL_LIB"};
$compret = `cl /nologo /MD /I "$include" testosslv.c "$library"`;
if (grep { -f and -x } ".\\testosslv.exe") {
`.\\testosslv.exe`;
if ($? != 0) {
die "OpenSSL version test failed\n";
}
} else {
die "can't compile OpenSSL version test: $compret\n";
}
}
# check OpenSSL built-in support for DH/ECDSA/RSA/CRYPTO_ZALLOC/EVP_CIPHER_CTX/EVP_MD_CTX/HMAC_CTX functions
if ($use_openssl eq "yes") {
if ($verbose) {
printf "checking OpenSSL built-in support for DH/ECDSA/RSA/CRYPTO_ZALLOC/EVP_CIPHER_CTX/EVP_MD_CTX/HMAC_CTX functions\n";
}
open F, ">testosslfunc.c" || die $!;
print F << 'EOF';
#include <stdio.h>
#include <openssl/opensslv.h>
int main() {
if (OPENSSL_VERSION_NUMBER >= 0x10100000L) {
return (0);
}
printf("\n\nFound OPENSSL_VERSION_NUMBER %#010x\n",
OPENSSL_VERSION_NUMBER);
printf("This version has no built-in support for DH/ECDSA/RSA/CRYPTO_ZALLOC/EVP_CIPHER_CTX/EVP_MD_CTX/HMAC_CTX functions.\n\n");
return (1);
}
EOF
close F;
my $include = $configinc{"OPENSSL_INC"};
my $library = $configlib{"OPENSSL_LIB"};
$compret = `cl /nologo /MD /I "$include" testosslfunc.c "$library"`;
if (grep { -f and -x } ".\\testosslfunc.exe") {
`.\\testosslfunc.exe`;
if ($? == 0) {
$configdefh{"HAVE_DH_GET0_KEY"} = 1;
$configdefh{"HAVE_ECDSA_SIG_GET0"} = 1;
$configdefh{"HAVE_RSA_SET0_KEY"} = 1;
$configdefh{"HAVE_CRYPTO_ZALLOC"} = 1;
$configdefh{"HAVE_EVP_CIPHER_CTX_FREE"} = 1;
$configdefh{"HAVE_EVP_CIPHER_CTX_NEW"} = 1;
$configdefh{"HAVE_EVP_MD_CTX_FREE"} = 1;
$configdefh{"HAVE_EVP_MD_CTX_NEW"} = 1;
$configdefh{"HAVE_EVP_MD_CTX_RESET"} = 1;
$configdefh{"HAVE_HMAC_CTX_FREE"} = 1;
$configdefh{"HAVE_HMAC_CTX_GET_MD"} = 1;
$configdefh{"HAVE_HMAC_CTX_NEW"} = 1;
$configdefh{"HAVE_HMAC_CTX_RESET"} = 1;
}
}
}
# check FIPS_mode
# with-eddsa
if ($use_openssl eq "no") {
$use_eddsa = "no";
}
if ($use_eddsa eq "auto") {
if ($verbose) {
print "checking for OpenSSL ED25519 support\n";
}
open F, ">tested25519.c" || die $!;
print F << 'EOF';
#include <openssl/evp.h>
#include <openssl/objects.h>
int
main(void)
{
EVP_PKEY_CTX *ctx;
ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL);
if (ctx == NULL)
return (2);
return (0);
}
EOF
close F;
my $include = $configinc{"OPENSSL_INC"};
my $library = $configlib{"OPENSSL_LIB"};
$compret = `cl /nologo /MD /I "$include" tested25519.c "$library"`;
if (grep { -f and -x } ".\\tested25519.exe") {
`.\\tested25519.exe`;
if ($? != 0) {
if ($verbose) {
print "EDDSA test failed: disabling EDDSA\n";
}
$use_eddsa = "no";
}
} else {
if ($verbose) {
print "can't compile EDDSA test: $compret\n";
print "disabling EDDSA\n";
}
$use_eddsa = "no";
}
}
if ($use_eddsa ne "no") {
$use_eddsa = "yes";
$configdefh{"HAVE_OPENSSL_ED25519"} = 1;
} else {
$use_ed448 = "no";
}
if ($use_ed448 eq "auto") {
if ($verbose) {
print "checking for OpenSSL ED448 support\n";
}
open F, ">tested448.c" || die $!;
print F << 'EOF';
#include <openssl/evp.h>
#include <openssl/objects.h>
int
main(void)
{
EVP_PKEY_CTX *ctx;
ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL);
if (ctx == NULL)
return (2);
return (0);
}
EOF
close F;
my $include = $configinc{"OPENSSL_INC"};
my $library = $configlib{"OPENSSL_LIB"};
$compret = `cl /nologo /MD /I "$include" tested448.c "$library"`;
if (grep { -f and -x } ".\\tested448.exe") {
`.\\tested448.exe`;
if ($? != 0) {
if ($verbose) {
print "ED448 test failed: disabling ED448\n";
}
$use_ed448 = "no";
}
} else {
if ($verbose) {
print "can't compile ED448 test: $compret\n";
print "disabling ED448\n";
}
$use_ed448 = "no";
}
}
if ($use_ed448 ne "no") {
$use_ed448 = "yes";
$configdefh{"HAVE_OPENSSL_ED448"} = 1;
}
# with-aes
if ($use_openssl eq "no") {
if ($use_aes ne "pkcs11") {
$use_aes = "no";
}
}
if ($cryptolib ne "") {
print "Cryptographic library for DNSSEC: $cryptolib\n";
} else {
die "No cryptography library has been found or provided."
}
# with-pkcs11
if ($use_pkcs11 ne "no") {
$configcond{"PKCS11"} = 1;
$configvar{"PKCS11_TOOLS"} = "pkcs11";
$configdefd{"PK11_LIB_LOCATION"} = "PK11_LIB_LOCATION=\"$pkcs11_path\"";
}
# with-gssapi
if ($use_gssapi eq "no") {
if ($verbose) {
print "gssapi library is disabled\n";
}
} else {
$gssapi_path = File::Spec->rel2abs($gssapi_path);
if ($verbose) {
print "checking for gssapi directory at \"$gssapi_path\"\n";
}
$configcond{"GSSAPI"} = 1;
$configdefd{"USE_GSSAPI"} = "GSSAPI";
if (!-f File::Spec->catfile($gssapi_path, "include",
"gssapi", "gssapi.h")) {
die "can't find gssapi.h include\n";
}
if (!-f File::Spec->catfile($gssapi_path, "include",
"gssapi", "gssapi_krb5.h")) {
die "can't find gssapi_krb5.h include\n";
}
if (!-f File::Spec->catfile($gssapi_path, "include",
"krb5", "krb5.h")) {
die "can't find krb5.h include\n";
}
$configinc{"GSSAPI_INC"} = File::Spec->catdir($gssapi_path, "include");
my $bits = "32";
my $gssapi_lib;
my $krb5_lib;
if ($want_win32 eq "yes") {
$bits = "32";
if (!-f File::Spec->catfile($gssapi_path, "lib", "i386",
"gssapi${bits}.lib")) {
die "can't find gssapi${bits}.lib library\n";
}
$gssapi_lib = File::Spec->catfile($gssapi_path, "lib", "i386",
"gssapi${bits}.lib");
if (!-f File::Spec->catfile($gssapi_path, "lib", "i386",
"krb5_${bits}.lib")) {
die "can't find krb5_${bits}.lib library\n";
}
$krb5_lib = File::Spec->catfile($gssapi_path, "lib", "i386",
"krb5_${bits}.lib");
} elsif ($want_x64 eq "yes") {
$bits = "64";
if (!-f File::Spec->catfile($gssapi_path, "lib", "amd64",
"gssapi${bits}.lib")) {
die "can't find gssapi${bits}.lib library\n";
}
$gssapi_lib = File::Spec->catfile($gssapi_path, "lib", "amd64",
"gssapi${bits}.lib");
if (!-f File::Spec->catfile($gssapi_path, "lib", "amd64",
"krb5_${bits}.lib")) {
die "can't find krb5_${bits}.lib library\n";
}
$krb5_lib = File::Spec->catfile($gssapi_path, "lib", "amd64",
"krb5_${bits}.lib");
} else {
die "can't happen: no choice between Win32 and x64\n";
}
if (!-f File::Spec->catfile($gssapi_path, "bin", "gssapi${bits}.dll")) {
die "can't find gssapi${bits}.dll DLL\n";
}
if (!-f File::Spec->catfile($gssapi_path, "bin", "krb5_${bits}.dll")) {
die "can't find krb5_${bits}.dll DLL\n";
}
if (!-f File::Spec->catfile($gssapi_path, "bin", "comerr${bits}.dll")) {
die "can't find comerr${bits}.dll DLL\n";
}
if (!-f File::Spec->catfile($gssapi_path, "bin", "k5sprt${bits}.dll")) {
die "can't find k5sprt${bits}.dll DLL\n";
}
if (!-f File::Spec->catfile($gssapi_path, "bin", "wshelp${bits}.dll")) {
die "can't find wshelp${bits}.dll DLL\n";
}
$configlib{"GSSAPI_LIB"} = "$gssapi_lib";
$configlib{"KRB5_LIB"} = "$krb5_lib";
my $gssapi_dll = File::Spec->catfile($gssapi_path, "bin",
"gssapi${bits}.dll");
$configdll{"GSSAPI_DLL"} = "$gssapi_dll";
my $krb5_dll = File::Spec->catfile($gssapi_path, "bin",
"krb5_${bits}.dll");
$configdll{"KRB5_DLL"} = "$krb5_dll";
my $comerr_dll = File::Spec->catfile($gssapi_path, "bin",
"comerr${bits}.dll");
$configdll{"COMERR_DLL"} = "$comerr_dll";
my $k5sprt_dll = File::Spec->catfile($gssapi_path, "bin",
"k5sprt${bits}.dll");
$configdll{"K5SPRT_DLL"} = "$k5sprt_dll";
my $wshelp_dll = File::Spec->catfile($gssapi_path, "bin",
"wshelp${bits}.dll");
$configdll{"WSHELP_DLL"} = "$wshelp_dll";
}
# enable-isc-spnego
if ($use_gssapi ne "yes") {
$enable_isc_spnego = "no";
} elsif ($enable_isc_spnego eq "yes") {
if ($use_gssapi eq "no") {
die "No GSSAPI for SPNEGO\n";
}
$configdefd{"USE_ISC_SPNEGO"} = "USE_ISC_SPNEGO";
}
# disable-auto-validation
$configdefh{"VALIDATION_DEFAULT"} = "\"$validation_default\"";
# with-geoip
if ($use_geoip eq "no") {
if ($verbose) {
print "geoip library is disabled\n";
}
} else {
$configcond{"GEOIPLEGACY"} = 1;
$geoip_path = File::Spec->rel2abs($geoip_path);
if ($verbose) {
print "checking for geoip directory at \"$geoip_path\"\n";
}
if (!-f File::Spec->catfile($geoip_path, "GeoIP.h")) {
die "can't find GeoIP.h include\n";
}
if (!-f File::Spec->catfile($geoip_path, "GeoIP.lib")) {
die "can't find Geoip.lib library\n";
}
if (!-f File::Spec->catfile($geoip_path, "GeoIP.dll")) {
die "can't find Geoip.dll DLL\n";
}
$configinc{"GEOIP_INC"} = "$geoip_path";
my $geoip_lib = File::Spec->catfile($geoip_path, "GeoIP.lib");
$configlib{"GEOIP_LIB"} = "$geoip_lib";
my $geoip_dll = File::Spec->catfile($geoip_path, "GeoIP.dll");
$configdll{"GEOIP_DLL"} = "$geoip_dll";
if ($verbose) {
print "checking for GeoIP support\n";
}
my $ret = `copy "$geoip_dll" .`;
if ($? != 0) {
die "Can't copy GeoIP DLL to working directory: $ret\n";
}
open F, ">testgeoip.c" || die $!;
print F << 'EOF';
extern void *GeoIP_open();
int main() {
return GeoIP_open != 0;
}
EOF
close F;
$compret = `cl /nologo /MD testgeoip.c "$geoip_lib"`;
if (grep { -f and -x } ".\\testgeoip.exe") {
`.\\testgeoip.exe`;
if ($? == 0) {
die "GeoIP test failed\n";
}
} else {
die "can't compile GeoIP test: $compret\n";
}
$configdefh{"HAVE_GEOIP"} = 1;
if ($verbose) {
print "checking for GeoIP Country IPv6 support\n";
}
my $geoip_inc = qq(/I "$geoip_path");
my $geoip_libs = qq("$geoip_lib" ws2_32.lib);
open F, ">testgeoip1.c" || die $!;
print F << 'EOF';
#include <GeoIP.h>
struct in6_addr in6;
int flag = 1;
int main() {
if (flag)
return 1;
return GeoIP_country_name_by_ipnum_v6(NULL, in6) != NULL;
}
EOF
close F;
$compret = `cl /nologo $geoip_inc /MD testgeoip1.c $geoip_libs`;
if (grep { -f and -x } ".\\testgeoip1.exe") {
`.\\testgeoip1.exe`;
if ($? == 0) {
die "GeoIP Country IPv6 test failed\n";
}
} else {
die "can't compile GeoIP Country IPv6 test: $compret\n";
}
$configdefh{"HAVE_GEOIP_V6"} = 1;
if ($verbose) {
print "checking for GeoIP City IPv6 support\n";
}
open F, ">testgeoip2.c" || die $!;
print F << 'EOF';
#include <GeoIP.h>
#include <GeoIPCity.h>
struct in6_addr in6;
int i = GEOIP_CITY_EDITION_REV0_V6;
int flag = 1;
int main() {
if (flag)
return 1;
return GeoIP_record_by_ipnum_v6(NULL, in6) != NULL;
}
EOF
close F;
$compret = `cl /nologo $geoip_inc /MD testgeoip2.c $geoip_libs`;
if (grep { -f and -x } ".\\testgeoip2.exe") {
`.\\testgeoip2.exe`;
if ($? == 0) {
die "GeoIP City IPv6 test failed\n";
}
} else {
die "can't compile GeoIP City IPv6 test: $compret\n";
}
$configdefh{"HAVE_GEOIP_CITY_V6"} = 1;
}
# with-geoip2
if ($use_geoip2 eq "no") {
if ($verbose) {
print "geoip2 library is disabled\n";
}
} else {
$configcond{"GEOIP"} = 1;
$geoip2_path = File::Spec->rel2abs($geoip2_path);
if ($verbose) {
print "checking for geoip2 directory at \"$geoip2_path\"\n";
}
if (!-f File::Spec->catfile($geoip2_path, "maxminddb.h")) {
die "can't find maxminddb.h include\n";
}
if (!-f File::Spec->catfile($geoip2_path, "maxminddb_config.h")) {
die "can't find maxminddb_config.h include\n";
}
if (!-f File::Spec->catfile($geoip2_path, "libmaxminddb.lib")) {
die "can't find libmaxminddb.lib library\n";
}
$configinc{"GEOIP_INC"} = "$geoip2_path";
my $geoip2_lib = File::Spec->catfile($geoip2_path, "libmaxminddb.lib");
$configlib{"GEOIP_LIB"} = "$geoip2_lib";
my $geoip_inc = qq(/I "$geoip2_path");
my $geoip2_libs = qq("$geoip2_lib" Ws2_32.Lib);
if ($verbose) {
print "checking for GeoIP2 support\n";
}
open F, ">testgeoip2.c" || die $!;
print F << 'EOF';
#include <maxminddb.h>
int main(void) {
return MMDB_lib_version() != 0;
}
EOF
close F;
$compret = `cl /nologo $geoip_inc /MD testgeoip2.c $geoip2_libs`;
if (grep { -f and -x } ".\\testgeoip2.exe") {
`.\\testgeoip2.exe`;
if ($? == 0) {
die "GeoIP2 test failed\n";
}
} else {
die "can't compile GeoIP2 test: $compret\n";
}
$configdefh{"HAVE_GEOIP2"} = 1;
}
# with-readline
if ($use_readline eq "no") {
if ($verbose) {
print "readline library is disabled\n";
}
} else {
$readline_path = File::Spec->rel2abs($readline_path);
if ($verbose) {
print "checking for readline directory at \"$readline_path\"\n";
}
if (!-f File::Spec->catfile($readline_path, "readline", "readline.h")) {
die "can't find readline.h include\n";
}
if (!-f File::Spec->catfile($readline_path, "readline", "readline.lib")) {
die "can't find readline.lib library\n";
}
$configdefh{"HAVE_READLINE"} = 1;
$configinc{"READLINE_INC"} = "$readline_path";
my $readline_lib = File::Spec->catfile($readline_path,
"readline", "readline.lib");
$configlib{"READLINE_LIB"} = "$readline_lib";
if (-f File::Spec->catfile($readline_path, "readline", "readlineD.lib")) {
my $readline_libd = File::Spec->catfile($readline_path,
"readline", "readlineD.lib");
$configlib{"READLINE_LIBD"} = "$readline_libd";
} else {
$configlib{"READLINE_LIBD"} = "$readline_lib";
}
}
# with-idn (including with-iconv)
if ($use_idn eq "no") {
if ($verbose) {
print "IDN kit is disabled\n";
}
} else {
$idn_path = File::Spec->rel2abs($idn_path);
if ($verbose) {
print "checking for IDN kit directory at \"$idn_path\"\n";
}
if (!-f File::Spec->catfile($idn_path, "idn", "api.h")) {
die "can't find idn\\api.h include\n";
}
if (!-f File::Spec->catfile($idn_path, "idn", "idnkit.lib")) {
die "can't find idnkit.lib library\n";
}
if (!-f File::Spec->catfile($idn_path, "idn", "idnkit.dll")) {
die "can't find idnkit.dll DLL\n";
}
$configcond{"IDNKIT"} = 1;
$configdefh{"WITH_IDN"} = 1;
$configinc{"IDN_INC"} = "$idn_path";
my $idn_lib = File::Spec->catfile($idn_path, "idn", "idnkit.lib");
$configlib{"IDN_LIB"} = "$idn_lib";
my $idn_dll = File::Spec->catfile($idn_path, "idn", "idnkit.dll");
$configdll{"IDN_DLL"} = "$idn_dll";
if ($iconv_path eq " --idn-- ") {
my $iconv_dll = File::Spec->catfile($idn_path, "idn", "iconv.dll");
$configdll{"ICONV_DLL"} = "$iconv_dll";
} else {
my $iconv_dll =File::Spec->catfile($iconv_path, "iconv.dll");
$configdll{"ICONV_DLL"} = "$iconv_dll";
}
}
# with-libxml2
if ($use_libxml2 eq "no") {
if ($verbose) {
print "libxml2 library is disabled\n";
}
} elsif ($use_libxml2 eq "auto") {
if ($verbose) {
print "checking for a libxml2 built directory at sibling root\n";
}
opendir DIR, $libxml2_path || die "No Directory: $!\n";
my @dirlist = grep (/^libxml2-[0-9]+\.[0-9]+\.[0-9]+[a-z]*/i,
readdir(DIR));
closedir(DIR);
# Make sure we have something
if (scalar(@dirlist) == 0) {
die "can't find a libxml2 at sibling root\n";
}
# Now see if we have a directory or just a file.
# Make sure we are case insensitive
my $file;
foreach $file (sort {uc($b) cmp uc($a)} @dirlist) {
if (-f File::Spec->catfile($libxml2_path,
$file,
"include\\libxml",
"xmlversion.h")) {
$libxml2_path = File::Spec->catdir($libxml2_path, $file);
$use_libxml2 = "yes";
last;
}
}
# If we have one use it otherwise report the error
if ($use_libxml2 eq "auto") {
die "can't find a libxml2 built directory at sibling root\n";
}
}
# falls into (so no else)
if ($use_libxml2 eq "yes") {
$libxml2_path = File::Spec->rel2abs($libxml2_path);
if ($verbose) {
print "checking for libxml2 built directory at \"$libxml2_path\"\n";
}
if (!-f File::Spec->catfile($libxml2_path,
"include\\libxml",
"xmlversion.h")) {
die "can't find libxml2 xmlversion.h include\n";
}
if (!-f File::Spec->catfile($libxml2_path,
"win32\\bin.msvc",
"libxml2.lib")) {
die "can't find Libxml2 libxml2.lib library\n";
}
if (!-f File::Spec->catfile($libxml2_path,
"win32\\bin.msvc",
"libxml2.dll")) {
die "can't find Libxml2 DLL\n";
}
$configcond{"LIBXML2"} = 1;
$configdefh{"HAVE_LIBXML2"} = 1;
$configtest{"XMLSTATS"} = 1;
my $libxml2_inc = File::Spec->catdir($libxml2_path, "include");
$configinc{"LIBXML2_INC"} = "$libxml2_inc";
my $libxml2_libdir = File::Spec->catdir($libxml2_path, "win32\\bin.msvc");
my $libxml2_lib = File::Spec->catfile($libxml2_libdir, "libxml2.lib");
$configlib{"LIBXML2_LIB"} = "$libxml2_lib";
my $libxml2_dll = File::Spec->catfile($libxml2_libdir, "libxml2.dll");
$configdll{"LIBXML2_DLL"} = "$libxml2_dll";
}
# with-zlib
if ($use_zlib eq "no") {
if ($verbose) {
print "zlib library is disabled\n";
}
} else {
$configcond{"ZLIB"} = 1;
$configtest{"ZLIB"} = 1;
$zlib_path = File::Spec->rel2abs($zlib_path);
if ($verbose) {
print "checking for zlib directory at \"$zlib_path\"\n";
}
if (!-f File::Spec->catfile($zlib_path, "zlib.h")) {
die "can't find zlib.h include\n";
}
if (!-f File::Spec->catfile($zlib_path, "zdll.lib")) {
die "can't find zdll.lib library\n";
}
if (!-f File::Spec->catfile($zlib_path, "zlib1.dll")) {
die "can't find zlib1.dll DLL\n";
}
$configdefh{"HAVE_ZLIB"} = 1;
$configinc{"ZLIB_INC"} = "$zlib_path";
my $zlib_lib = File::Spec->catfile($zlib_path, "zdll.lib");
$configlib{"ZLIB_LIB"} = "$zlib_lib";
my $zlib_dll = File::Spec->catfile($zlib_path, "zlib1.dll");
$configdll{"ZLIB_DLL"} = "$zlib_dll";
}
if ($with_pssuspend ne "no") {
$configvar{"PSSUSPEND"} = "$pssuspend_command";
}
# with-python
if ($use_python eq "no") {
if ($verbose) {
print "python is disabled\n";
}
} elsif ($use_python eq "auto") {
if ($verbose) {
print "checking for python in path\n";
}
my $pythonret = `python.exe -c "quit()" 2>&1`;
if ($? != 0) {
print STDERR "can't launch the python interpreter: $pythonret\n";
$use_python = "no";
}
}
if ($use_python ne "no") {
if ($use_python ne "auto") {
if ($verbose) {
print "checking for $python_command\n";
}
my $pythonret = `"$python_command" -c "quit()" 2>&1`;
if ($? != 0) {
die "can't launch $python_command: $pythonret\n";
}
}
if ($python_command !~ /\.exe$/i) {
$python_command = $python_command . ".exe";
}
# tried to use the full path without success here
if ($verbose) {
print "checking for python module 'argparse'\n";
}
my $pythonret = `"$python_command" -c "import argparse" 2>&1`;
if ($? != 0) {
if ($use_python ne "auto") {
die "can't find python module 'argparse': $pythonret\n";
} else {
print STDERR "can't find python module 'argparse': $pythonret\n";
$use_python = "no";
}
}
if ($use_python ne "no") {
if ($verbose) {
print "checking for python module 'ply'\n";
}
$pythonret = `"$python_command" -c "from ply import *" 2>&1`;
if ($? != 0) {
if ($use_python ne "auto") {
die "can't find python module 'ply': $pythonret\n";
} else {
print STDERR "can't find python module 'ply': $pythonret\n";
$use_python = "no";
}
}
}
if ($use_python ne "no") {
if ($verbose) {
print "checking for python module 'win32api'\n";
}
$pythonret = `"$python_command" -c "import win32api" 2>&1`;
if ($? != 0) {
if ($use_python ne "auto") {
die "can't find python module 'win32api': $pythonret\n";
} else {
print STDERR
"can't find python module 'win32api': $pythonret\n";
$use_python = "no";
}
}
}
if ($use_python ne "no") {
if ($verbose) {
print "checking for python module 'win32con'\n";
}
$pythonret = `"$python_command" -c "import win32con" 2>&1`;
if ($? != 0) {
if ($use_python ne "auto") {
die "can't find python module 'win32con': $pythonret\n";
} else {
print STDERR
"can't find python module 'win32con': $pythonret\n";
$use_python = "no";
}
}
}
if ($use_python ne "no") {
$configcond{"PYTHON"} = 1;
$configdefd{"USE_PYTHON"} = "USE_PYTHON";
$configvar{"PYTHON"} = "$python_command";
$configtest{"CHECKDS"} = "checkds";
$configtest{"COVERAGE"} = "coverage";
$configtest{"KEYMGR"} = "keymgr";
# Doesn't matter
$configvar{"prefix"} = "__prefix__";
$configvar{"expanded_sysconfdir"} = "__prefix__\\etc";
}
}
# with-vcredist
$vcredist_path = File::Spec->rel2abs($vcredist_path);
if (!grep { -f and -x } $vcredist_path) {
die "$vcredist_path is not correct\n";
} else {
$configvar{"VCREDIST_PATH"} = "$vcredist_path";
}
# tuning
if ($tuning eq "large") {
$configdefh{"TUNE_LARGE"} = 1;
}
# escape spaces
sub kw {
if ($_[0] =~ / /) {
return "\"$_[0]\"";
} else {
return "$_[0]";
}
}
# setup config.h with %configdefh
sub setupconfigh {
my $line;
my @Lines;
open F, $configfile . ".win32" || die $!;
@Lines = <F>;
close F;
foreach $line (@Lines) {
chomp $line;
if ($line =~ /^@([^@]+)\@$/) {
if (defined($configdefh{$1})) {
$line = "#define $1 $configdefh{$1}";
} else {
$line = "/* #undef $1 */";
}
}
}
open F, ">" . $configfile || die $!;
if ($verbose) {
print "Setting up $configfile\n";
}
foreach $line (@Lines) {
print F $line . "\n";
}
close F;
}
# setup platform.h with %configdefp
sub setupplatformh {
my $line;
my @Lines;
open F, $platformfile . ".in" || die $!;
@Lines = <F>;
close F;
foreach $line (@Lines) {
chomp $line;
if ($line =~ /^@([^@]+)\@$/) {
if (defined($configdefp{$1})) {
$line = "#define $1 $configdefp{$1}";
} else {
$line = "/* #undef $1 */";
}
}
}
open F, ">" . $platformfile || die $!;
if ($verbose) {
print "Setting up $platformfile\n";
}
foreach $line (@Lines) {
print F $line . "\n";
}
close F;
}
# setup conf.sh with %configtest and %configvar
sub setupconfsh {
my $line;
my @Lines;
my $val;
open F, $confshfile . ".win32" || die $!;
@Lines = <F>;
close F;
foreach $line (@Lines) {
chomp $line;
while ($line =~ /@([^@]+)\@/) {
if ($1 ~~ @substtest) {
if (defined($configtest{$1})) {
$val = kw($configtest{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substvar) {
if (defined($configvar{$1})) {
$val = kw($configvar{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} else {
die "unknown control $& in $confshfile.win32\n";
}
}
}
open F, ">" . $confshfile || die $!;
if ($verbose) {
print "Setting up $confshfile\n";
}
binmode(F);
foreach $line (@Lines) {
print F $line . "\n";
}
close F;
}
# setup isc-config.sh with %configvar accepting undefined
sub setupicsh {
my $line;
my @Lines;
my $val;
open F, $icshfile . ".in" || die $!;
@Lines = <F>;
close F;
foreach $line (@Lines) {
chomp $line;
while ($line =~ /@([^@]+)\@/) {
if ($1 ~~ @substvar) {
if (defined($configvar{$1})) {
$val = kw($configvar{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} else {
$line = "$`__$1__$'";
}
}
}
open F, ">" . $icshfile || die $!;
if ($verbose) {
print "Setting up $icshfile\n";
}
binmode(F);
foreach $line (@Lines) {
print F $line . "\n";
}
close F;
}
# setup a file with %configcond stack and %config{var,defd,inc,lib,dll,test}
sub setupfile {
my $line;
my @Linesin;
my @Linesout;
my $filename = $_[0];
my $cond;
my @conds;
my $pass = 1;
my @passes;
my $val;
open F, $filename . ".in" || die $!;
@Linesin = <F>;
close F;
foreach $line (@Linesin) {
chomp $line;
if ($line =~ /^\@IF (.*)$/) {
if (defined($cond)) {
unshift(@conds, $cond);
unshift(@passes, $pass);
}
if ($1 ~~ @allcond) {
$cond = $1;
if (defined($configcond{$cond})) {
# do nothing
} else {
$pass = 0;
}
} else {
die "unknown condition \@IF $1 in $filename\n";
}
next;
} elsif ($line =~ /^\@ELSE (.*)$/) {
if ($cond ne $1) {
die "\@ELSE $1 mismatch in $filename\n";
}
if (defined($configcond{$cond})) {
$pass = 0;
} else {
if (scalar(@conds) > 0) {
$pass = $passes[0];
} else {
$pass = 1;
}
}
next;
} elsif ($line =~ /^\@END (.*)$/) {
if ($cond ne $1) {
die "\@END $1 mismatch in $filename\n";
}
$cond = shift(@conds);
if (scalar(@passes) > 0) {
$pass = shift(@passes);
} else {
$pass = 1;
}
next;
}
if ($pass == 0) {
next;
}
while ($line =~ /@([^@ ]*)@/) {
if ($1 ~~ @substvar) {
if (defined($configvar{$1})) {
$val = kw($configvar{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substdefd) {
if (defined($configdefd{$1})) {
my $def = $configdefd{$1};
my $pre = "$`";
my $post = "$'";
$def =~ s/([\\ "])/\\$1/g;
$line = qq($pre/D "$def"$post);
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substinc) {
if (defined($configinc{$1})) {
$line = qq($`/I "$configinc{$1}"$');
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substlib) {
if (defined($configlib{$1})) {
$val = kw($configlib{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substdll) {
if (defined($configdll{$1})) {
$val = kw($configdll{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} else {
die "unknown control $& in $filename\n";
}
}
push @Linesout, $line;
}
open F, ">" . $filename || die $!;
if ($verbose) {
print "Setting up $filename\n";
}
binmode(F);
foreach $line (@Linesout) {
print F $line . "\n";
}
close F;
}
# setup a project with %configcond stack and %config{var,defd,inc,lib,dll}
sub setupproject {
my $line;
my @Linesin;
my @Linesout;
my $projectname = $_[0];
my $cond;
my @conds;
my $pass = 1;
my @passes;
my $val;
open F, $projectname . ".in" || die $!;
@Linesin = <F>;
close F;
foreach $line (@Linesin) {
chomp $line;
if ($line =~ /^\@IF (.*)$/) {
if (defined($cond)) {
unshift(@conds, $cond);
unshift(@passes, $pass);
}
if ($1 ~~ @allcond) {
$cond = $1;
if (defined($configcond{$cond})) {
# do nothing
} else {
$pass = 0;
}
} else {
die "unknown condition \@IF $1 in $projectname\n";
}
next;
} elsif ($line =~ /^\@ELSE (.*)$/) {
if ($cond ne $1) {
die "\@ELSE $1 mismatch in $projectname\n";
}
if (defined($configcond{$cond})) {
$pass = 0;
} else {
if (scalar(@conds) > 0) {
$pass = $passes[0];
} else {
$pass = 1;
}
}
next;
} elsif ($line =~ /^\@END (.*)$/) {
if ($cond ne $1) {
die "\@END $1 mismatch in $projectname\n";
}
$cond = shift(@conds);
if (scalar(@passes) > 0) {
$pass = shift(@passes);
} else {
$pass = 1;
}
next;
}
if ($pass == 0) {
next;
}
while ($line =~ /@([^@ ]*)@/) {
if ($1 ~~ @substvar) {
if (defined($configvar{$1})) {
$val = kw($configvar{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substdefd) {
if (defined($configdefd{$1})) {
$val = kw($configdefd{$1});
$line = "$`$val;$'";
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substinc) {
if (defined($configinc{$1})) {
$val = kw($configinc{$1});
$line = "$`$val;$'";
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substlib) {
if (defined($configlib{$1})) {
$val = kw($configlib{$1});
$line = "$`$val;$'";
} else {
$line = "$`$'";
}
} elsif ($1 ~~ @substdll) {
if (defined($configdll{$1})) {
$val = kw($configdll{$1});
$line = "$`$val$'";
} else {
$line = "$`$'";
}
} else {
die "unknown control $& in $projectname\n";
}
}
push @Linesout, $line;
}
open F, ">" . $projectname || die $!;
if ($verbose) {
print "Setting up $projectname\n";
}
foreach $line (@Linesout) {
print F $line . "\n";
}
close F;
}
# make versions.h
sub makeversion {
# List of directories with version files
my @dirlist = ("isc", "dns", "ns", "isccc", "isccfg", "bind9", "irs");
my %LibMacros = (
"bind9" => "LIBBIND9_EXPORTS",
"dns" => "LIBDNS_EXPORTS",
"irs" => "LIBIRS_EXPORTS",
"isc" => "LIBISC_EXPORTS",
"isccc" => "LIBISCCC_EXPORTS",
"isccfg" => "LIBISCCFG_EXPORTS",
"ns" => "LIBNS_EXPORTS");
my @VersionNames = ("LIBINTERFACE", "LIBREVISION", "LIBAGE");
my $Version;
my %ApiVersions;
my $Mapapi;
my $versionfile = "versions.h";
my $versionpath = "..\\$versionfile";
my $data;
my $name;
my $value;
# And the mapapi one
open M, "..\\lib\\dns\\mapapi" || die $!;
while (<M>) {
chomp;
($data) = split(/\#/);
if ($data) {
($name, $value) = split(/=/, $data);
($name) = split(/\s+/, $name);
if ($name eq 'MAPAPI') {
($value) =~ s/^["\s]+//;
($value) =~ s/["\s]+$//;
} else {
($value) = split(/\s+/, $value);
}
$Mapapi = $value;
}
}
close M;
# Now set up the output version file
my $ThisDate = scalar localtime();
open O, ">$versionpath" ||
die "Can't open output file $versionpath: $!\n";
# Standard Header
print O '/*
* Copyright (C) 2001 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
';
print O "/*\n";
print O " * $versionfile.";
print O " Generated automatically by Configure.pl.\n";
print O " * Date generated: $ThisDate\n";
print O " */\n\n";
print O '
#ifndef VERSIONS_H
#define VERSIONS_H 1
';
$Version = "$Versions{'MAJORVER'}.$Versions{'MINORVER'}";
if ($Versions{'PATCHVER'} ne "") {
$Version = "$Version.$Versions{'PATCHVER'}";
}
$Version = "$Version$Versions{'RELEASETYPE'}$Versions{'RELEASEVER'}";
$Version = "$Version$Versions{'EXTENSIONS'}";
if ($verbose) {
print "BIND Version: $Version\n";
}
print O "#define VERSION \"$Version\"\n";
print O "#define PRODUCT \"$Versions{'PRODUCT'}\"\n\n";
print O "#define DESCRIPTION \"$Versions{'DESCRIPTION'}\"\n\n";
print O
"#define MAJOR \"$Versions{'MAJORVER'}.$Versions{'MINORVER'}\"\n\n";
print O "#define MAPAPI \"$Mapapi\"\n\n";
my $dir;
my $apifile;
foreach $dir (@dirlist) {
$apifile = "..\\lib\\$dir\\api";
open A, $apifile || die $!;
while (<A>) {
chomp;
($data) = split(/\#/);
if ($data) {
($name, $value) = split(/=/, $data);
$name =~ s/\s+//;
$value =~ s/\s+//;
$ApiVersions{$name} = $value;
}
}
close A;
print O "\n#ifdef $LibMacros{$dir}\n";
foreach $name (@VersionNames) {
print O "#define $name\t$ApiVersions{$name}\n";
}
print O "#endif\n\n";
}
print O "#endif /* VERSIONS_H */\n";
close O;
}
# make srcid.h
sub makesrcid {
my $data;
my $name;
my $value;
my $srcid = "unset_id";
open SOUT, ">..\\srcid.h" || die "cannot open srcid.h: $!\n";
if (open (SIN, "..\\srcid")) {
LOOP: while (<SIN>) {
chomp;
($data) = split(/\#/);
if ($data) {
($name, $value) = split(/=/, $data);
($name) = split(/\s+/, $name);
($value) = split(/\s+/, $value);
next LOOP if ($name != "SRCID");
$srcid = $value;
}
}
close SIN;
}
# Now set up the output version file
my $ThisDate = scalar localtime();
# Standard Header
print SOUT '/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
';
print SOUT "/*\n";
print SOUT " * srcid.h";
print SOUT " * Generated automatically by Configure.pl.\n";
print SOUT " * Date generated: $ThisDate\n";
print SOUT " */\n\n";
print SOUT '
#ifndef SRCID_H
#define SRCID_H 1
';
if ($verbose) {
print "BIND SRCID: $srcid\n";
}
print SOUT "#define SRCID\t\"$srcid\"\n";
print SOUT "#endif /* SRCID_H */\n";
close SOUT;
}
# Build install files
sub makeinstallfile {
open FOUT, ">InstallFlags" || die "cannot open InstallFlags: $!\n";
print FOUT "# Flags for BINDInstall\n";
if ($msc_ver >= 1400) {
print FOUT "runvcredist\n";
}
if ($want_x64 eq "yes") {
print FOUT "forwin64\n";
}
close FOUT;
open LOUT, ">InstallFiles" || die "cannot open InstallFiles: $!\n";
print LOUT "# File list for BINDInstall\n";
if ($msc_ver < 1400) {
if ($msc_ver >= 1310) {
print LOUT "mfc71.dll-WCTT\n";
print LOUT "msvcr71.dll-WCTT\n";
} elsif (($msc_ver > 1200) && ($msc_ver < 1310)) {
print LOUT "mfc70.dll-WCTT\n";
print LOUT "msvcr70.dll-WCTT\n";
}
}
print LOUT "bindevt.dll-BNFT\n";
print LOUT "libbind9.dll-BCFT\n";
print LOUT "libisc.dll-BCFT\n";
print LOUT "libisccfg.dll-BCFT\n";
print LOUT "libisccc.dll-BCFT\n";
print LOUT "libdns.dll-BCFT\n";
print LOUT "libirs.dll-BCFT\n";
print LOUT "libns.dll-BCFT\n";
if ($use_openssl eq "yes") {
my $v;
my $d;
my $name;
($v, $d, $name) =File::Spec->splitpath($configdll{"OPENSSL_DLL"});
print LOUT "${name}-BCFT\n";
}
if ($use_libxml2 eq "yes") {
print LOUT "libxml2.dll-BCFT\n";
}
if ($use_gssapi eq "yes") {
if ($want_x64 eq "yes") {
print LOUT "gssapi64.dll-BCFT\n";
print LOUT "krb5_64.dll-BCFT\n";
} else {
print LOUT "gssapi32.dll-BCFT\n";
print LOUT "krb5_32.dll-BCFT\n";
}
}
if ($use_geoip eq "yes") {
print LOUT "libgeoip.dll-BCFT\n";
}
if ($use_idn eq "yes") {
print LOUT "idnkit.dll-BCFT\n";
print LOUT "iconv.dll-BCFT\n";
}
print LOUT "named.exe-BCFF\n";
print LOUT "nsupdate.exe-BNFT\n";
print LOUT "BINDInstall.exe-BNFT\n";
print LOUT "InstallFlags-BNFT\n";
print LOUT "InstallFiles-BNFT\n";
print LOUT "rndc.exe-BNFF\n";
print LOUT "dig.exe-BNFT\n";
print LOUT "host.exe-BNFT\n";
print LOUT "mdig.exe-BNFT\n";
print LOUT "nslookup.exe-BNFT\n";
print LOUT "delv.exe-BNFT\n";
print LOUT "arpaname.exe-BNFT\n";
print LOUT "nsec3hash.exe-BNFF\n";
print LOUT "rndc-confgen.exe-BNFF\n";
print LOUT "ddns-confgen.exe-BNFF\n";
print LOUT "tsig-keygen.exe-BNFF\n";
print LOUT "dnssec-keygen.exe-BNFF\n";
print LOUT "dnssec-signzone.exe-BNFF\n";
print LOUT "dnssec-dsfromkey.exe-BNFF\n";
print LOUT "dnssec-importkey.exe-BNFF\n";
print LOUT "dnssec-keyfromlabel.exe-BNFF\n";
print LOUT "dnssec-revoke.exe-BNFF\n";
print LOUT "dnssec-settime.exe-BNFF\n";
print LOUT "dnssec-verify.exe-BNFF\n";
print LOUT "named-checkconf.exe-BNFF\n";
print LOUT "named-checkzone.exe-BNFF\n";
print LOUT "named-compilezone.exe-BNFF\n";
print LOUT "named-journalprint.exe-BNFF\n";
print LOUT "named-rrchecker.exe-BNFF\n";
if ($use_pkcs11 eq "yes") {
print LOUT "pkcs11-destroy.exe-BNFF\n";
print LOUT "pkcs11-keygen.exe-BNFF\n";
print LOUT "pkcs11-list.exe-BNFF\n";
print LOUT "pkcs11-tokens.exe-BNFF\n";
}
if ($use_python ne "no") {
print LOUT "dnssec-checkds.py-BNFF\n";
print LOUT "dnssec-coverage.py-BNFF\n";
print LOUT "dnssec-keymgr.py-BNFF\n";
}
print LOUT "readme1st.txt-BTFT\n";
close LOUT;
}
# Adjust system tests
# dnstap not supported
#$configtest{"DNSTAP"} = "dnstap";
#$configtest{"FSTRM_CAPTURE"} = "fstrm_capture";
# no json-c library for WIN32
#$configtest{"JSONSTATS"} = 1;
# lmdb not supported
#$configtest{"NZD_TOOLS"} = "nzd";
# TODO check for pkcs11ssl and set PKCS11_TEST
# Status
if ($verbose) {
my $name;
print "Configuration Status\n";
print "\tconfig.h:\n";
foreach $name (@substdefh) {
if (defined($configdefh{$name})) {
print qq(\t\t$name defined to "$configdefh{$name}"\n);
} else {
printf qq(\t\t$name undefined\n);
}
}
print "\tplatform.h:\n";
foreach $name (@substdefp) {
if (defined($configdefp{$name})) {
print qq(\t\t$name defined to "$configdefp{$name}"\n);
} else {
printf qq(\t\t$name undefined\n);
}
}
print "\tconf.sh:\n";
foreach $name (@substtest) {
if (defined($configtest{$name})) {
print qq(\t\t$name defined to "$configtest{$name}"\n);
} else {
printf qq(\t\t$name undefined\n);
}
}
print "\tconditions:\n";
foreach $name (@substcond) {
if (defined($configcond{$name})) {
print "\t\t$name is true\n";
} else {
print "\t\t$name is false\n";
}
}
print "\tsubstitutions:\n";
foreach $name (@substvar) {
if (defined($configvar{$name})) {
print qq(\t\t$name -> "$configvar{$name}"\n);
}
}
print "\tdefines:\n";
foreach $name (@substdefd) {
if (defined($configdefd{$name})) {
print qq(\t\t/D "$configdefd{$name}"\n);
}
}
print "\tincludes:\n";
foreach $name (@substinc) {
if (defined($configinc{$name})) {
print qq(\t\t/I "$configinc{$name}"\n);
}
}
print "\tlibraries:\n";
foreach $name (@substlib) {
if (defined($configlib{$name})) {
print "\t\t$configlib{$name}\n";
}
}
print "\tDLLs:\n";
foreach $name (@substdll) {
if (defined($configdll{$name})) {
print "\t\t$configdll{$name}\n";
}
}
print "\n";
}
# Setup
if (($want_win32 eq "yes") || ($want_x64 eq "yes")) {
setupconfigh();
setupplatformh();
setupconfsh();
setupicsh();
my $file;
foreach $file (@filelist) {
setupfile($file);
}
foreach $file (@projectlist) {
setupproject($file);
}
makeversion();
makesrcid();
makeinstallfile();
print "Configured.\n";
} else {
print "add win32 or x64 to commit configuration to build files\n";
}
exit 0;
# Notes: Unix configure.in options
# --enable-developer partially supported
# --enable-newstats (9.9/9.9sub only)
# --enable-native-pkcs11 supported
# --enable-openssl-version-check included without a way to disable it
# --enable-openssl-hash supported
# --enable-threads included without a way to disable it
# --enable-backtrace backtrace included without a way to disable it
# --enable-symtable incompatible with DLLs (or libtool)
# --enable-ipv6 included without a way to disable it
# --enable-atomic supported (renamed to intrinsic)
# --enable-isc-spnego supported (part of GSSAPI)
# --enable-fixed-rrset supported
# --enable-querytrace supported
# --enable-full-report supported by verbose
# --enable-dnstap not supported (requires libfstrm support on WIN32)
# --enable-afl not supported (not yet available on Visual Studio C++)
# --disable-auto-validation supported
# --with-python supported
# --with-openssl supported
# --with-pkcs11 supported
# --with-ecdsa supported
# --with-eddsa supported
# --with-aes supported
# --with-cc-alg supported
# --with-randomdev not supported on WIN32 (makes no sense)
# --with-geoip supported
# --with-geoip2 supported
# --with-gssapi supported with MIT (K)erberos (f)or (W)indows
# --with-lmdb no supported on WIN32 (port is not reliable)
# --with-libxml2 supported
# --with-libjson not supported on WIN32 (package not available on WIN32)
# --with-zlib supported
# --with-purify not supported (package available on WIN32 but for free?)
# --with-gperftools-profiler not supported (package not available on WIN32)
# --with-libtool not supported on WIN32 (never)
# --with-locktype not supported on WIN32 (not yet available on WIN32)
# --with-readline supported
# --with-protobuf-c not supported (no reason to until libfstrm is ready)
# --with-libfrtrm not supported (not yet available on WIN32)
# --with-docbook-xsl not supported (?)
# --with-idn[lib] supported
# --with-[lib]iconv supported (part of IDN)
# --with-atf not supported on WIN32 (package not available on WIN32)
# --with-tuning supported
# --with-dlopen included without a way to disable it
# --with-dlz-* ?
#
# Notes: MSVC versions
# MSVC 15.x _MSC_VER == 191y (VS 2017)
# MSVC 14.0 _MSC_VER == 1900 (VS 2015)
# MSVC 12.0 _MSC_VER == 1800 (VS 2013)
# MSVC 11.0 _MSC_VER == 1700 (VS 2012)
# MSVC 10.0 _MSC_VER == 1600 (VS 2010)
# MSVC 9.0 _MSC_VER == 1500 (VS 2008)
# MSVC 8.0 _MSC_VER == 1400 (VS 2005)
# MSVC 7.1 _MSC_VER == 1310 (VS .NET 2003)
# MSVC 7.0 _MSC_VER == 1300 (VS .NET (2002))
# MSVC 6.0 _MSC_VER == 1200 (VS 6.0 (1998))
# MSVC 5.0 _MSC_VER == 1100 (VS 97)