diff options
author | Brad King <brad.king@kitware.com> | 2023-04-06 13:13:24 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2023-04-06 13:13:31 (GMT) |
commit | fbdb509efe21a02f075536eaf7fde0594e9419ef (patch) | |
tree | 254d5c3b7f4692126206ed2e0383fa18e579075f /Source | |
parent | 703f87f32f067ab2122571e652861b43dd86fb4c (diff) | |
parent | 8ecb6459345c550b77d8f689ed397137f2855fca (diff) | |
download | CMake-fbdb509efe21a02f075536eaf7fde0594e9419ef.zip CMake-fbdb509efe21a02f075536eaf7fde0594e9419ef.tar.gz CMake-fbdb509efe21a02f075536eaf7fde0594e9419ef.tar.bz2 |
Merge topic 'vs-sdk-selection'
8ecb645934 VS: Select Windows SDK matching WindowsSDKVersion env var
f90c8ab54e VS: Select latest available Windows SDK version by default
b512c53d43 VS: Add support for setting WindowsTargetPlatformVersion to 10.0
2f3d945f83 VS: Add CMAKE_GENERATOR_PLATFORM field to control Windows SDK selection
f0a67b6291 VS: Parse comma-separated fields from CMAKE_GENERATOR_PLATFORM
e259063b0a VS: Defer Windows SDK selection until CMAKE_GENERATOR_PLATFORM is known
8499374c6a VS: Simplify logic to require SDK for Windows Store
1c8d4b4bf1 Tests: Teach RunCMake_TEST_FILTER to account for test variant description
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !8389
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGlobalVisualStudio10Generator.cxx | 24 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio10Generator.h | 5 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio14Generator.cxx | 125 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio14Generator.h | 15 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio8Generator.cxx | 92 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio8Generator.h | 8 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioVersionedGenerator.cxx | 10 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioVersionedGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmPolicies.h | 3 |
9 files changed, 259 insertions, 26 deletions
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 1e01dd6..321f377 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -525,6 +525,30 @@ bool cmGlobalVisualStudio10Generator::InitializeAndroid(cmMakefile* mf) return false; } +bool cmGlobalVisualStudio10Generator::InitializePlatform(cmMakefile* mf) +{ + if (this->SystemName == "Windows" || this->SystemName == "WindowsStore") { + if (!this->InitializePlatformWindows(mf)) { + return false; + } + } else if (!this->SystemName.empty() && + !this->VerifyNoGeneratorPlatformVersion(mf)) { + return false; + } + return this->cmGlobalVisualStudio8Generator::InitializePlatform(mf); +} + +bool cmGlobalVisualStudio10Generator::InitializePlatformWindows(cmMakefile*) +{ + return true; +} + +bool cmGlobalVisualStudio10Generator::VerifyNoGeneratorPlatformVersion( + cmMakefile*, cm::optional<std::string>) const +{ + return true; +} + bool cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset( std::string& toolset) const { diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index deed206..6917ffc 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -183,6 +183,11 @@ protected: virtual bool InitializeTegraAndroid(cmMakefile* mf); virtual bool InitializeAndroid(cmMakefile* mf); + 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 ProcessGeneratorToolsetField(std::string const& key, std::string const& value); diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index 7424ca3..4300d5c 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -12,6 +12,7 @@ #include "cmGlobalVisualStudioGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmPolicies.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmValue.h" @@ -137,12 +138,36 @@ bool cmGlobalVisualStudio14Generator::MatchesGeneratorName( return false; } -bool cmGlobalVisualStudio14Generator::InitializeWindows(cmMakefile* mf) +bool cmGlobalVisualStudio14Generator::InitializePlatformWindows(cmMakefile* mf) { if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) { - return this->SelectWindows10SDK(mf, false); + return this->SelectWindows10SDK(mf); } - return true; + return this->VerifyNoGeneratorPlatformVersion(mf); +} + +bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion( + cmMakefile* mf, cm::optional<std::string> reason) const +{ + if (!this->GeneratorPlatformVersion) { + return true; + } + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "given platform specification containing a\n" + " version=" << *this->GeneratorPlatformVersion << "\n" + "field. The version field is not supported when targeting\n" + " " << this->SystemName << " " << this->SystemVersion << "\n" + ; + /* clang-format on */ + if (reason) { + e << *reason << "."; + } + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return false; } bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf) @@ -162,9 +187,6 @@ bool cmGlobalVisualStudio14Generator::InitializeWindowsStore(cmMakefile* mf) mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); return false; } - if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) { - return this->SelectWindows10SDK(mf, true); - } return true; } @@ -173,19 +195,51 @@ bool cmGlobalVisualStudio14Generator::InitializeAndroid(cmMakefile*) return true; } -bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf, - bool required) +bool cmGlobalVisualStudio14Generator::ProcessGeneratorPlatformField( + std::string const& key, std::string const& value) +{ + if (key == "version") { + this->GeneratorPlatformVersion = value; + return true; + } + return false; +} + +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); - if (required && version.empty()) { - std::ostringstream e; - e << "Could not find an appropriate version of the Windows 10 SDK" - << " installed on this machine"; - mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return false; + if (version.empty()) { + if (this->GeneratorPlatformVersion) { + mf->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Generator\n ", this->GetName(), + "\ngiven platform specification with\n version=", + *this->GeneratorPlatformVersion, + "\nfield, but no Windows SDK with that version was found.")); + return false; + } + + if (this->SystemName == "WindowsStore") { + mf->IssueMessage( + MessageType::FATAL_ERROR, + "Could not find an appropriate version of the Windows 10 SDK" + " installed on this machine"); + return false; + } } + this->SetWindowsTargetPlatformVersion(version, mf); return true; } @@ -302,6 +356,16 @@ 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; { @@ -360,10 +424,35 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion( // Sort the results to make sure we select the most recent one. std::sort(sdks.begin(), sdks.end(), cmSystemTools::VersionCompareGreater); - // Look for a SDK exactly matching the requested target version. - for (std::string const& i : sdks) { - if (cmSystemTools::VersionCompareEqual(i, this->SystemVersion)) { - return i; + // Look for a SDK exactly matching the requested version, if any. + if (this->GeneratorPlatformVersion) { + for (std::string const& i : sdks) { + if (cmSystemTools::VersionCompareEqual( + i, *this->GeneratorPlatformVersion)) { + return i; + } + } + // An exact version was requested but not found. + // Our caller will issue the error message. + return std::string(); + } + + if (mf->GetPolicyStatus(cmPolicies::CMP0149) == cmPolicies::NEW) { + if (cm::optional<std::string> const envVer = + cmSystemTools::GetEnvVar("WindowsSDKVersion")) { + // Look for a SDK exactly matching the environment variable. + for (std::string const& i : sdks) { + if (cmSystemTools::VersionCompareEqual(i, *envVer)) { + return i; + } + } + } + } else { + // Look for a SDK exactly matching the target Windows version. + for (std::string const& i : sdks) { + if (cmSystemTools::VersionCompareEqual(i, this->SystemVersion)) { + return i; + } } } diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h index 7fb9b4b..f59a323 100644 --- a/Source/cmGlobalVisualStudio14Generator.h +++ b/Source/cmGlobalVisualStudio14Generator.h @@ -7,6 +7,8 @@ #include <memory> #include <string> +#include <cm/optional> + #include "cmGlobalVisualStudio12Generator.h" class cmGlobalGeneratorFactory; @@ -30,7 +32,6 @@ protected: cmGlobalVisualStudio14Generator(cmake* cm, const std::string& name, std::string const& platformInGeneratorName); - bool InitializeWindows(cmMakefile* mf) override; bool InitializeWindowsStore(cmMakefile* mf) override; bool InitializeAndroid(cmMakefile* mf) override; bool SelectWindowsStoreToolset(std::string& toolset) const override; @@ -39,6 +40,14 @@ protected: // of the toolset is installed bool IsWindowsStoreToolsetInstalled() const; + bool InitializePlatformWindows(cmMakefile* mf) override; + bool VerifyNoGeneratorPlatformVersion( + cmMakefile* mf, + cm::optional<std::string> reason = cm::nullopt) const override; + + bool ProcessGeneratorPlatformField(std::string const& key, + std::string const& value) override; + // Used to adjust the max-SDK-version calculation to accommodate user // configuration. std::string GetWindows10SDKMaxVersion(cmMakefile* mf) const; @@ -47,7 +56,7 @@ protected: // version of the toolset. virtual std::string GetWindows10SDKMaxVersionDefault(cmMakefile* mf) const; - virtual bool SelectWindows10SDK(cmMakefile* mf, bool required); + virtual bool SelectWindows10SDK(cmMakefile* mf); void SetWindowsTargetPlatformVersion(std::string const& version, cmMakefile* mf); @@ -61,4 +70,6 @@ protected: private: class Factory; friend class Factory; + + cm::optional<std::string> GeneratorPlatformVersion; }; diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 2e2c8b6..2aba46f 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -94,7 +94,9 @@ bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p, return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform(p, mf); } - this->GeneratorPlatform = p; + if (!this->ParseGeneratorPlatform(p, mf)) { + return false; + } // FIXME: Add CMAKE_GENERATOR_PLATFORM field to set the framework. // For now, just report the generator's default, if any. @@ -114,12 +116,100 @@ bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p, *targetFrameworkTargetsVersion); } + if (!this->InitializePlatform(mf)) { + return false; + } + // The generator name does not contain the platform name, and so supports // explicit platform specification. We handled that above, so pass an // empty platform name to our base class implementation so it does not error. return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf); } +bool cmGlobalVisualStudio8Generator::ParseGeneratorPlatform( + std::string const& p, cmMakefile* mf) +{ + this->GeneratorPlatform.clear(); + + std::vector<std::string> const fields = cmTokenize(p, ","); + auto fi = fields.begin(); + if (fi == fields.end()) { + return true; + } + + // The first field may be the VS platform. + if (fi->find('=') == fi->npos) { + this->GeneratorPlatform = *fi; + ++fi; + } + + std::set<std::string> handled; + + // The rest of the fields must be key=value pairs. + for (; fi != fields.end(); ++fi) { + std::string::size_type pos = fi->find('='); + if (pos == fi->npos) { + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "given platform specification\n" + " " << p << "\n" + "that contains a field after the first ',' with no '='." + ; + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return false; + } + std::string const key = fi->substr(0, pos); + std::string const value = fi->substr(pos + 1); + if (!handled.insert(key).second) { + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "given platform specification\n" + " " << p << "\n" + "that contains duplicate field key '" << key << "'." + ; + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return false; + } + if (!this->ProcessGeneratorPlatformField(key, value)) { + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "given platform specification\n" + " " << p << "\n" + "that contains invalid field '" << *fi << "'." + ; + /* clang-format on */ + mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return false; + } + } + + return true; +} + +bool cmGlobalVisualStudio8Generator::ProcessGeneratorPlatformField( + std::string const& key, std::string const& value) +{ + static_cast<void>(key); + static_cast<void>(value); + return false; +} + +bool cmGlobalVisualStudio8Generator::InitializePlatform(cmMakefile*) +{ + return true; +} + cm::optional<std::string> const& cmGlobalVisualStudio8Generator::GetTargetFrameworkVersion() const { diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index fe57c54..5555e9b 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -60,6 +60,11 @@ protected: cmGlobalVisualStudio8Generator(cmake* cm, const std::string& name, std::string const& platformInGeneratorName); + virtual bool InitializePlatform(cmMakefile* mf); + + virtual bool ProcessGeneratorPlatformField(std::string const& key, + std::string const& value); + void AddExtraIDETargets() override; std::string FindDevEnvCommand() override; @@ -96,4 +101,7 @@ protected: cm::optional<std::string> DefaultTargetFrameworkVersion; cm::optional<std::string> DefaultTargetFrameworkIdentifier; cm::optional<std::string> DefaultTargetFrameworkTargetsVersion; + +private: + bool ParseGeneratorPlatform(std::string const& is, cmMakefile* mf); }; diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index 415eb7c..f28419a 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -885,7 +885,8 @@ cmGlobalVisualStudioVersionedGenerator::FindAuxToolset( return AuxToolset::PropsMissing; } -bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf) +bool cmGlobalVisualStudioVersionedGenerator::InitializePlatformWindows( + cmMakefile* mf) { // If the Win 8.1 SDK is installed then we can select a SDK matching // the target Windows version. @@ -894,13 +895,14 @@ bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf) if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 && !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) { this->SetWindowsTargetPlatformVersion("8.1", mf); - return true; + return this->VerifyNoGeneratorPlatformVersion( + mf, "with the Windows 8.1 SDK installed"); } - return cmGlobalVisualStudio14Generator::InitializeWindows(mf); + return cmGlobalVisualStudio14Generator::InitializePlatformWindows(mf); } // Otherwise we must choose a Win 10 SDK even if we are not targeting // Windows 10. - return this->SelectWindows10SDK(mf, false); + return this->SelectWindows10SDK(mf); } bool cmGlobalVisualStudioVersionedGenerator::SelectWindowsStoreToolset( diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h index 45aca74..fb4b1d7 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.h +++ b/Source/cmGlobalVisualStudioVersionedGenerator.h @@ -61,7 +61,6 @@ protected: VSVersion version, cmake* cm, const std::string& name, std::string const& platformInGeneratorName); - bool InitializeWindows(cmMakefile* mf) override; bool SelectWindowsStoreToolset(std::string& toolset) const override; // Used to verify that the Desktop toolset for the current generator is @@ -72,6 +71,8 @@ protected: // of the toolset is installed bool IsWindowsStoreToolsetInstalled() const; + bool InitializePlatformWindows(cmMakefile* mf) override; + // Check for a Win 8 SDK known to the registry or VS installer tool. bool IsWin81SDKInstalled() const; diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 37d697f..fe88382 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -447,6 +447,9 @@ class cmMakefile; 27, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0148, \ "The FindPythonInterp and FindPythonLibs modules are removed.", 3, \ + 27, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0149, \ + "Visual Studio generators select latest Windows SDK by default.", 3, \ 27, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) |