VS: Teach CMAKE_GENERATOR_PLATFORM to use Windows 10 SDKs for older versions

Honor an explicit `version=` field selecting a Windows 10 SDK regardless
of the Windows target version.

Issue: #25170
This commit is contained in:
Brad King
2023-08-08 16:03:40 -04:00
parent bba1a23da9
commit 15ff89654b
14 changed files with 91 additions and 59 deletions

View File

@@ -50,7 +50,7 @@ Supported pairs are:
.. versionadded:: 3.27
Specify the Windows SDK version to use. This is supported by VS 2015 and
above when targeting Windows 10.0+ or Windows Store. CMake will set the
above when targeting Windows or Windows Store. CMake will set the
:variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable to the
selected SDK version.

View File

@@ -544,7 +544,7 @@ bool cmGlobalVisualStudio10Generator::InitializePlatformWindows(cmMakefile*)
}
bool cmGlobalVisualStudio10Generator::VerifyNoGeneratorPlatformVersion(
cmMakefile*, cm::optional<std::string>) const
cmMakefile*) const
{
return true;
}

View File

@@ -187,8 +187,7 @@ protected:
bool InitializePlatform(cmMakefile* mf) override;
virtual bool InitializePlatformWindows(cmMakefile* mf);
virtual bool VerifyNoGeneratorPlatformVersion(
cmMakefile* mf, cm::optional<std::string> reason = cm::nullopt) const;
virtual bool VerifyNoGeneratorPlatformVersion(cmMakefile* mf) const;
virtual bool ProcessGeneratorToolsetField(std::string const& key,
std::string const& value);

View File

@@ -6,6 +6,7 @@
#include <sstream>
#include <cm/vector>
#include <cmext/string_view>
#include "cmGlobalGenerator.h"
#include "cmGlobalGeneratorFactory.h"
@@ -140,6 +141,57 @@ bool cmGlobalVisualStudio14Generator::MatchesGeneratorName(
bool cmGlobalVisualStudio14Generator::InitializePlatformWindows(cmMakefile* mf)
{
// If a Windows SDK version is explicitly requested, search for it.
if (this->GeneratorPlatformVersion) {
std::string const& version = *this->GeneratorPlatformVersion;
// VS 2019 and above support specifying plain "10.0".
if (version == "10.0"_s) {
if (this->Version >= VSVersion::VS16) {
this->SetWindowsTargetPlatformVersion("10.0", mf);
return true;
}
/* clang-format off */
mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat(
"Generator\n"
" ", this->GetName(), "\n"
"given platform specification containing a\n"
" version=10.0\n"
"field. The value 10.0 is only supported by VS 2019 and above.\n"
));
/* clang-format on */
return false;
}
if (cmHasLiteralPrefix(version, "10.0.")) {
return this->SelectWindows10SDK(mf);
}
if (version.empty()) {
/* clang-format off */
mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat(
"Generator\n"
" ", this->GetName(), "\n"
"given platform specification with empty\n"
" version=\n"
"field.\n"
));
/* clang-format on */
return false;
}
/* clang-format off */
mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat(
"Generator\n"
" ", this->GetName(), "\n"
"given platform specification containing a\n"
" version=", version, "\n"
"field with unsupported value.\n"
));
/* clang-format on */
return false;
}
// If we are targeting Windows 10+, we select a Windows 10 SDK.
// If no Windows 8.1 SDK is installed, which is possible with VS 2017 and
// higher, then we must choose a Windows 10 SDK anyway.
@@ -153,15 +205,12 @@ bool cmGlobalVisualStudio14Generator::InitializePlatformWindows(cmMakefile* mf)
if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 &&
!cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) {
this->SetWindowsTargetPlatformVersion("8.1", mf);
return this->VerifyNoGeneratorPlatformVersion(
mf, "with the Windows 8.1 SDK installed");
}
return this->VerifyNoGeneratorPlatformVersion(mf);
return true;
}
bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion(
cmMakefile* mf, cm::optional<std::string> reason) const
cmMakefile* mf) const
{
if (!this->GeneratorPlatformVersion) {
return true;
@@ -177,9 +226,6 @@ bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion(
" " << this->SystemName << " " << this->SystemVersion << "\n"
;
/* clang-format on */
if (reason) {
e << *reason << ".";
}
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
return false;
}
@@ -221,16 +267,6 @@ bool cmGlobalVisualStudio14Generator::ProcessGeneratorPlatformField(
bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf)
{
if (this->GeneratorPlatformVersion &&
this->GeneratorPlatformVersion->empty()) {
mf->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Generator\n ", this->GetName(),
"\ngiven platform specification with empty\n version=\n"
"field."));
return false;
}
// Find the default version of the Windows 10 SDK.
std::string const version = this->GetWindows10SDKVersion(mf);
@@ -376,16 +412,6 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion(
cmMakefile* mf)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
// Accept specific version requests as-is.
if (this->GeneratorPlatformVersion) {
std::string const& ver = *this->GeneratorPlatformVersion;
// VS 2019 and above support specifying plain "10.0".
if (this->Version >= VSVersion::VS16 && ver == "10.0") {
return ver;
}
}
std::vector<std::string> win10Roots;
{

View File

@@ -43,9 +43,7 @@ protected:
virtual bool IsWin81SDKInstalled() const;
bool InitializePlatformWindows(cmMakefile* mf) override;
bool VerifyNoGeneratorPlatformVersion(
cmMakefile* mf,
cm::optional<std::string> reason = cm::nullopt) const override;
bool VerifyNoGeneratorPlatformVersion(cmMakefile* mf) const override;
bool ProcessGeneratorPlatformField(std::string const& key,
std::string const& value) override;

View File

@@ -6,6 +6,6 @@
given platform specification with
version=1\.2\.3\.4
version=10\.0\.0\.0
field, but no Windows SDK with that version was found\.$

View File

@@ -1,19 +0,0 @@
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
Generator
Visual Studio [^
]+
given platform specification (containing a
version=8\.1
field\. The version field is not supported when targeting
Windows 8\.1(
with the Windows 8\.1 SDK installed\.)?|with
version=8\.1
field, but no Windows SDK with that version was found\.)$

View File

@@ -0,0 +1,11 @@
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
Generator
Visual Studio [^
]+
given platform specification containing a
version=10\.0
field\. The value 10\.0 is only supported by VS 2019 and above\.$

View File

@@ -0,0 +1,11 @@
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
Generator
Visual Studio [^
]+
given platform specification containing a
version=1\.2\.3\.4
field with unsupported value\.$

View File

@@ -0,0 +1 @@
message(FATAL_ERROR "This should not be reached!")

View File

@@ -36,12 +36,16 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$")
run_cmake(BadFieldUnknown)
set(RunCMake_GENERATOR_PLATFORM "version=")
run_cmake(BadVersionEmpty)
set(RunCMake_GENERATOR_PLATFORM "version=1.2.3.4")
set(RunCMake_GENERATOR_PLATFORM "version=10.0.0.0")
run_cmake(BadVersionMissing)
set(RunCMake_GENERATOR_PLATFORM "version=8.1")
run_cmake_with_options(BadVersionPlatform -DCMAKE_SYSTEM_VERSION=8.1)
set(RunCMake_GENERATOR_PLATFORM "version=1.2.3.4")
run_cmake(BadVersionUnsupported)
if(NOT RunCMake_GENERATOR MATCHES "^Visual Studio (1[45]) ")
if(RunCMake_GENERATOR MATCHES "^Visual Studio (1[45]) ")
set(RunCMake_GENERATOR_PLATFORM "version=10.0")
run_cmake(BadVersionPre2019)
unset(RunCMake_GENERATOR_PLATFORM)
else()
set(expect_version "10.0")
set(RunCMake_GENERATOR_PLATFORM "version=${expect_version}")
set(RunCMake_TEST_VARIANT_DESCRIPTION "-${expect_version}")