| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file Copyright.txt or https://cmake.org/licensing for details. */ | |
| #include "cmGlobalVisualStudioVersionedGenerator.h" | |
| #include <cmext/string_view> | |
| #include "cmsys/FStream.hxx" | |
| #include "cmsys/Glob.hxx" | |
| #include "cmAlgorithms.h" | |
| #include "cmDocumentationEntry.h" | |
| #include "cmLocalVisualStudio10Generator.h" | |
| #include "cmMakefile.h" | |
| #include "cmStringAlgorithms.h" | |
| #include "cmVSSetupHelper.h" | |
| #include "cmake.h" | |
| #if defined(_M_ARM64) | |
| # define HOST_PLATFORM_NAME "ARM64" | |
| # define HOST_TOOLS_ARCH "" | |
| #elif defined(_M_ARM) | |
| # define HOST_PLATFORM_NAME "ARM" | |
| # define HOST_TOOLS_ARCH "" | |
| #elif defined(_M_IA64) | |
| # define HOST_PLATFORM_NAME "Itanium" | |
| # define HOST_TOOLS_ARCH "" | |
| #elif defined(_WIN64) | |
| # define HOST_PLATFORM_NAME "x64" | |
| # define HOST_TOOLS_ARCH "x64" | |
| #else | |
| static bool VSIsWow64() | |
| { | |
| BOOL isWow64 = false; | |
| return IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64; | |
| } | |
| #endif | |
| static std::string VSHostPlatformName() | |
| { | |
| #ifdef HOST_PLATFORM_NAME | |
| return HOST_PLATFORM_NAME; | |
| #else | |
| if (VSIsWow64()) { | |
| return "x64"; | |
| } else { | |
| return "Win32"; | |
| } | |
| #endif | |
| } | |
| static std::string VSHostArchitecture() | |
| { | |
| #ifdef HOST_TOOLS_ARCH | |
| return HOST_TOOLS_ARCH; | |
| #else | |
| if (VSIsWow64()) { | |
| return "x64"; | |
| } else { | |
| return "x86"; | |
| } | |
| #endif | |
| } | |
| static unsigned int VSVersionToMajor( | |
| cmGlobalVisualStudioGenerator::VSVersion v) | |
| { | |
| switch (v) { | |
| case cmGlobalVisualStudioGenerator::VS9: | |
| return 9; | |
| case cmGlobalVisualStudioGenerator::VS10: | |
| return 10; | |
| case cmGlobalVisualStudioGenerator::VS11: | |
| return 11; | |
| case cmGlobalVisualStudioGenerator::VS12: | |
| return 12; | |
| case cmGlobalVisualStudioGenerator::VS14: | |
| return 14; | |
| case cmGlobalVisualStudioGenerator::VS15: | |
| return 15; | |
| case cmGlobalVisualStudioGenerator::VS16: | |
| return 16; | |
| case cmGlobalVisualStudioGenerator::VS17: | |
| return 17; | |
| } | |
| return 0; | |
| } | |
| static const char* VSVersionToToolset( | |
| cmGlobalVisualStudioGenerator::VSVersion v) | |
| { | |
| switch (v) { | |
| case cmGlobalVisualStudioGenerator::VS9: | |
| return "v90"; | |
| case cmGlobalVisualStudioGenerator::VS10: | |
| return "v100"; | |
| case cmGlobalVisualStudioGenerator::VS11: | |
| return "v110"; | |
| case cmGlobalVisualStudioGenerator::VS12: | |
| return "v120"; | |
| case cmGlobalVisualStudioGenerator::VS14: | |
| return "v140"; | |
| case cmGlobalVisualStudioGenerator::VS15: | |
| return "v141"; | |
| case cmGlobalVisualStudioGenerator::VS16: | |
| return "v142"; | |
| case cmGlobalVisualStudioGenerator::VS17: | |
| // FIXME: VS 2022 Preview 1 uses v142. Will it be v143 later? | |
| return "v142"; | |
| } | |
| return ""; | |
| } | |
| static const char* VSVersionToAndroidToolset( | |
| cmGlobalVisualStudioGenerator::VSVersion v) | |
| { | |
| switch (v) { | |
| case cmGlobalVisualStudioGenerator::VS9: | |
| case cmGlobalVisualStudioGenerator::VS10: | |
| case cmGlobalVisualStudioGenerator::VS11: | |
| case cmGlobalVisualStudioGenerator::VS12: | |
| return ""; | |
| case cmGlobalVisualStudioGenerator::VS14: | |
| return "Clang_3_8"; | |
| case cmGlobalVisualStudioGenerator::VS15: | |
| case cmGlobalVisualStudioGenerator::VS16: | |
| case cmGlobalVisualStudioGenerator::VS17: | |
| return "Clang_5_0"; | |
| } | |
| return ""; | |
| } | |
| static const char vs15generatorName[] = "Visual Studio 15 2017"; | |
| // Map generator name without year to name with year. | |
| static const char* cmVS15GenName(const std::string& name, std::string& genName) | |
| { | |
| if (strncmp(name.c_str(), vs15generatorName, | |
| sizeof(vs15generatorName) - 6) != 0) { | |
| return 0; | |
| } | |
| const char* p = name.c_str() + sizeof(vs15generatorName) - 6; | |
| if (cmHasLiteralPrefix(p, " 2017")) { | |
| p += 5; | |
| } | |
| genName = std::string(vs15generatorName) + p; | |
| return p; | |
| } | |
| class cmGlobalVisualStudioVersionedGenerator::Factory15 | |
| : public cmGlobalGeneratorFactory | |
| { | |
| public: | |
| std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( | |
| const std::string& name, bool allowArch, cmake* cm) const override | |
| { | |
| std::string genName; | |
| const char* p = cmVS15GenName(name, genName); | |
| if (!p) { | |
| return std::unique_ptr<cmGlobalGenerator>(); | |
| } | |
| if (!*p) { | |
| return std::unique_ptr<cmGlobalGenerator>( | |
| new cmGlobalVisualStudioVersionedGenerator( | |
| cmGlobalVisualStudioGenerator::VS15, cm, genName, "")); | |
| } | |
| if (!allowArch || *p++ != ' ') { | |
| return std::unique_ptr<cmGlobalGenerator>(); | |
| } | |
| if (strcmp(p, "Win64") == 0) { | |
| return std::unique_ptr<cmGlobalGenerator>( | |
| new cmGlobalVisualStudioVersionedGenerator( | |
| cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64")); | |
| } | |
| if (strcmp(p, "ARM") == 0) { | |
| return std::unique_ptr<cmGlobalGenerator>( | |
| new cmGlobalVisualStudioVersionedGenerator( | |
| cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM")); | |
| } | |
| return std::unique_ptr<cmGlobalGenerator>(); | |
| } | |
| void GetDocumentation(cmDocumentationEntry& entry) const override | |
| { | |
| entry.Name = std::string(vs15generatorName) + " [arch]"; | |
| entry.Brief = "Generates Visual Studio 2017 project files. " | |
| "Optional [arch] can be \"Win64\" or \"ARM\"."; | |
| } | |
| std::vector<std::string> GetGeneratorNames() const override | |
| { | |
| std::vector<std::string> names; | |
| names.push_back(vs15generatorName); | |
| return names; | |
| } | |
| std::vector<std::string> GetGeneratorNamesWithPlatform() const override | |
| { | |
| std::vector<std::string> names; | |
| names.push_back(vs15generatorName + std::string(" ARM")); | |
| names.push_back(vs15generatorName + std::string(" Win64")); | |
| return names; | |
| } | |
| bool SupportsToolset() const override { return true; } | |
| bool SupportsPlatform() const override { return true; } | |
| std::vector<std::string> GetKnownPlatforms() const override | |
| { | |
| std::vector<std::string> platforms; | |
| platforms.emplace_back("x64"); | |
| platforms.emplace_back("Win32"); | |
| platforms.emplace_back("ARM"); | |
| platforms.emplace_back("ARM64"); | |
| return platforms; | |
| } | |
| std::string GetDefaultPlatformName() const override { return "Win32"; } | |
| }; | |
| std::unique_ptr<cmGlobalGeneratorFactory> | |
| cmGlobalVisualStudioVersionedGenerator::NewFactory15() | |
| { | |
| return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory15); | |
| } | |
| static const char vs16generatorName[] = "Visual Studio 16 2019"; | |
| static const char vs17generatorName[] = "Visual Studio 17 2022"; | |
| // Map generator name without year to name with year. | |
| static const char* cmVS16GenName(const std::string& name, std::string& genName) | |
| { | |
| if (strncmp(name.c_str(), vs16generatorName, | |
| sizeof(vs16generatorName) - 6) != 0) { | |
| return 0; | |
| } | |
| const char* p = name.c_str() + sizeof(vs16generatorName) - 6; | |
| if (cmHasLiteralPrefix(p, " 2019")) { | |
| p += 5; | |
| } | |
| genName = std::string(vs16generatorName) + p; | |
| return p; | |
| } | |
| static const char* cmVS17GenName(const std::string& name, std::string& genName) | |
| { | |
| if (strncmp(name.c_str(), vs17generatorName, | |
| sizeof(vs17generatorName) - 6) != 0) { | |
| return 0; | |
| } | |
| const char* p = name.c_str() + sizeof(vs17generatorName) - 6; | |
| if (cmHasLiteralPrefix(p, " 2022")) { | |
| p += 5; | |
| } | |
| genName = std::string(vs17generatorName) + p; | |
| return p; | |
| } | |
| class cmGlobalVisualStudioVersionedGenerator::Factory16 | |
| : public cmGlobalGeneratorFactory | |
| { | |
| public: | |
| std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( | |
| const std::string& name, bool /*allowArch*/, cmake* cm) const override | |
| { | |
| std::string genName; | |
| const char* p = cmVS16GenName(name, genName); | |
| if (!p) { | |
| return std::unique_ptr<cmGlobalGenerator>(); | |
| } | |
| if (!*p) { | |
| return std::unique_ptr<cmGlobalGenerator>( | |
| new cmGlobalVisualStudioVersionedGenerator( | |
| cmGlobalVisualStudioGenerator::VS16, cm, genName, "")); | |
| } | |
| return std::unique_ptr<cmGlobalGenerator>(); | |
| } | |
| void GetDocumentation(cmDocumentationEntry& entry) const override | |
| { | |
| entry.Name = std::string(vs16generatorName); | |
| entry.Brief = "Generates Visual Studio 2019 project files. " | |
| "Use -A option to specify architecture."; | |
| } | |
| std::vector<std::string> GetGeneratorNames() const override | |
| { | |
| std::vector<std::string> names; | |
| names.push_back(vs16generatorName); | |
| return names; | |
| } | |
| std::vector<std::string> GetGeneratorNamesWithPlatform() const override | |
| { | |
| return std::vector<std::string>(); | |
| } | |
| bool SupportsToolset() const override { return true; } | |
| bool SupportsPlatform() const override { return true; } | |
| std::vector<std::string> GetKnownPlatforms() const override | |
| { | |
| std::vector<std::string> platforms; | |
| platforms.emplace_back("x64"); | |
| platforms.emplace_back("Win32"); | |
| platforms.emplace_back("ARM"); | |
| platforms.emplace_back("ARM64"); | |
| platforms.emplace_back("ARM64EC"); | |
| return platforms; | |
| } | |
| std::string GetDefaultPlatformName() const override | |
| { | |
| return VSHostPlatformName(); | |
| } | |
| }; | |
| std::unique_ptr<cmGlobalGeneratorFactory> | |
| cmGlobalVisualStudioVersionedGenerator::NewFactory16() | |
| { | |
| return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory16); | |
| } | |
| class cmGlobalVisualStudioVersionedGenerator::Factory17 | |
| : public cmGlobalGeneratorFactory | |
| { | |
| public: | |
| std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator( | |
| const std::string& name, bool /*allowArch*/, cmake* cm) const override | |
| { | |
| std::string genName; | |
| const char* p = cmVS17GenName(name, genName); | |
| if (!p) { | |
| return std::unique_ptr<cmGlobalGenerator>(); | |
| } | |
| if (!*p) { | |
| return std::unique_ptr<cmGlobalGenerator>( | |
| new cmGlobalVisualStudioVersionedGenerator( | |
| cmGlobalVisualStudioGenerator::VS17, cm, genName, "")); | |
| } | |
| return std::unique_ptr<cmGlobalGenerator>(); | |
| } | |
| void GetDocumentation(cmDocumentationEntry& entry) const override | |
| { | |
| entry.Name = std::string(vs17generatorName); | |
| entry.Brief = "Generates Visual Studio 2022 project files. " | |
| "Use -A option to specify architecture."; | |
| } | |
| std::vector<std::string> GetGeneratorNames() const override | |
| { | |
| std::vector<std::string> names; | |
| names.push_back(vs17generatorName); | |
| return names; | |
| } | |
| std::vector<std::string> GetGeneratorNamesWithPlatform() const override | |
| { | |
| return std::vector<std::string>(); | |
| } | |
| bool SupportsToolset() const override { return true; } | |
| bool SupportsPlatform() const override { return true; } | |
| std::vector<std::string> GetKnownPlatforms() const override | |
| { | |
| std::vector<std::string> platforms; | |
| platforms.emplace_back("x64"); | |
| platforms.emplace_back("Win32"); | |
| platforms.emplace_back("ARM"); | |
| platforms.emplace_back("ARM64"); | |
| platforms.emplace_back("ARM64EC"); | |
| return platforms; | |
| } | |
| std::string GetDefaultPlatformName() const override | |
| { | |
| return VSHostPlatformName(); | |
| } | |
| }; | |
| std::unique_ptr<cmGlobalGeneratorFactory> | |
| cmGlobalVisualStudioVersionedGenerator::NewFactory17() | |
| { | |
| return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory17); | |
| } | |
| cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator( | |
| VSVersion version, cmake* cm, const std::string& name, | |
| std::string const& platformInGeneratorName) | |
| : cmGlobalVisualStudio14Generator(cm, name, platformInGeneratorName) | |
| , vsSetupAPIHelper(VSVersionToMajor(version)) | |
| { | |
| this->Version = version; | |
| this->ExpressEdition = false; | |
| this->DefaultPlatformToolset = VSVersionToToolset(this->Version); | |
| this->DefaultAndroidToolset = VSVersionToAndroidToolset(this->Version); | |
| this->DefaultCLFlagTableName = VSVersionToToolset(this->Version); | |
| this->DefaultCSharpFlagTableName = VSVersionToToolset(this->Version); | |
| this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version); | |
| if (this->Version >= cmGlobalVisualStudioGenerator::VS16) { | |
| this->DefaultPlatformName = VSHostPlatformName(); | |
| this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture(); | |
| } | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName( | |
| const std::string& name) const | |
| { | |
| std::string genName; | |
| switch (this->Version) { | |
| case cmGlobalVisualStudioGenerator::VS9: | |
| case cmGlobalVisualStudioGenerator::VS10: | |
| case cmGlobalVisualStudioGenerator::VS11: | |
| case cmGlobalVisualStudioGenerator::VS12: | |
| case cmGlobalVisualStudioGenerator::VS14: | |
| break; | |
| case cmGlobalVisualStudioGenerator::VS15: | |
| if (cmVS15GenName(name, genName)) { | |
| return genName == this->GetName(); | |
| } | |
| break; | |
| case cmGlobalVisualStudioGenerator::VS16: | |
| if (cmVS16GenName(name, genName)) { | |
| return genName == this->GetName(); | |
| } | |
| break; | |
| case cmGlobalVisualStudioGenerator::VS17: | |
| if (cmVS17GenName(name, genName)) { | |
| return genName == this->GetName(); | |
| } | |
| break; | |
| } | |
| return false; | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance( | |
| std::string const& i, cmMakefile* mf) | |
| { | |
| if (!i.empty()) { | |
| if (!this->vsSetupAPIHelper.SetVSInstance(i)) { | |
| std::ostringstream e; | |
| /* clang-format off */ | |
| e << | |
| "Generator\n" | |
| " " << this->GetName() << "\n" | |
| "could not find specified instance of Visual Studio:\n" | |
| " " << i; | |
| /* clang-format on */ | |
| mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); | |
| return false; | |
| } | |
| } | |
| std::string vsInstance; | |
| if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) { | |
| std::ostringstream e; | |
| /* clang-format off */ | |
| e << | |
| "Generator\n" | |
| " " << this->GetName() << "\n" | |
| "could not find any instance of Visual Studio.\n"; | |
| /* clang-format on */ | |
| mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); | |
| return false; | |
| } | |
| // Save the selected instance persistently. | |
| std::string genInstance = mf->GetSafeDefinition("CMAKE_GENERATOR_INSTANCE"); | |
| if (vsInstance != genInstance) { | |
| this->CMakeInstance->AddCacheEntry( | |
| "CMAKE_GENERATOR_INSTANCE", vsInstance.c_str(), | |
| "Generator instance identifier.", cmStateEnums::INTERNAL); | |
| } | |
| return true; | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::GetVSInstance( | |
| std::string& dir) const | |
| { | |
| return vsSetupAPIHelper.GetVSInstanceInfo(dir); | |
| } | |
| cm::optional<std::string> | |
| cmGlobalVisualStudioVersionedGenerator::GetVSInstanceVersion() const | |
| { | |
| cm::optional<std::string> result; | |
| std::string vsInstanceVersion; | |
| if (vsSetupAPIHelper.GetVSInstanceVersion(vsInstanceVersion)) { | |
| result = vsInstanceVersion; | |
| } | |
| return result; | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::IsStdOutEncodingSupported() const | |
| { | |
| // Supported from Visual Studio 16.7 Preview 3. | |
| if (this->Version > cmGlobalVisualStudioGenerator::VSVersion::VS16) { | |
| return true; | |
| } | |
| if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS16) { | |
| return false; | |
| } | |
| static std::string const vsVer16_7_P2 = "16.7.30128.36"; | |
| cm::optional<std::string> vsVer = this->GetVSInstanceVersion(); | |
| return (vsVer && | |
| cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer16_7_P2)); | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::IsUtf8EncodingSupported() const | |
| { | |
| // Supported from Visual Studio 16.10 Preview 2. | |
| if (this->Version > cmGlobalVisualStudioGenerator::VSVersion::VS16) { | |
| return true; | |
| } | |
| if (this->Version < cmGlobalVisualStudioGenerator::VSVersion::VS16) { | |
| return false; | |
| } | |
| static std::string const vsVer16_10_P2 = "16.10.31213.239"; | |
| cm::optional<std::string> vsVer = this->GetVSInstanceVersion(); | |
| return (vsVer && | |
| cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer16_10_P2)); | |
| } | |
| const char* | |
| cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision() | |
| const | |
| { | |
| switch (this->Version) { | |
| case cmGlobalVisualStudioGenerator::VS9: | |
| case cmGlobalVisualStudioGenerator::VS10: | |
| case cmGlobalVisualStudioGenerator::VS11: | |
| case cmGlobalVisualStudioGenerator::VS12: | |
| return ""; | |
| case cmGlobalVisualStudioGenerator::VS14: | |
| return "2.0"; | |
| case cmGlobalVisualStudioGenerator::VS15: | |
| case cmGlobalVisualStudioGenerator::VS16: | |
| case cmGlobalVisualStudioGenerator::VS17: | |
| return "3.0"; | |
| } | |
| return ""; | |
| } | |
| cmGlobalVisualStudioVersionedGenerator::AuxToolset | |
| cmGlobalVisualStudioVersionedGenerator::FindAuxToolset( | |
| std::string& version, std::string& props) const | |
| { | |
| if (version.empty()) { | |
| return AuxToolset::None; | |
| } | |
| std::string instancePath; | |
| this->GetVSInstance(instancePath); | |
| cmSystemTools::ConvertToUnixSlashes(instancePath); | |
| // Translate three-component format accepted by "vcvarsall -vcvars_ver=". | |
| cmsys::RegularExpression threeComponent( | |
| "^([0-9]+\\.[0-9]+)\\.[0-9][0-9][0-9][0-9][0-9]$"); | |
| if (threeComponent.find(version)) { | |
| // Load "VC/Auxiliary/Build/*/Microsoft.VCToolsVersion.*.txt" files | |
| // with two matching components to check their three-component version. | |
| std::string const& twoComponent = threeComponent.match(1); | |
| std::string pattern = | |
| cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, twoComponent, | |
| "*/Microsoft.VCToolsVersion."_s, twoComponent, "*.txt"_s); | |
| cmsys::Glob glob; | |
| glob.SetRecurseThroughSymlinks(false); | |
| if (glob.FindFiles(pattern)) { | |
| for (std::string const& txt : glob.GetFiles()) { | |
| std::string ver; | |
| cmsys::ifstream fin(txt.c_str()); | |
| if (fin && std::getline(fin, ver)) { | |
| // Strip trailing whitespace. | |
| ver = ver.substr(0, ver.find_first_not_of("0123456789.")); | |
| // If the three-component version matches, translate it to | |
| // that used by the "Microsoft.VCToolsVersion.*.txt" file name. | |
| if (ver == version) { | |
| cmsys::RegularExpression extractVersion( | |
| "VCToolsVersion\\.([0-9.]+)\\.txt$"); | |
| if (extractVersion.find(txt)) { | |
| version = extractVersion.match(1); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (cmSystemTools::VersionCompareGreaterEq(version, "14.20")) { | |
| props = cmStrCat(instancePath, "/VC/Auxiliary/Build."_s, version, | |
| "/Microsoft.VCToolsVersion."_s, version, ".props"_s); | |
| if (cmSystemTools::PathExists(props)) { | |
| return AuxToolset::PropsExist; | |
| } | |
| } | |
| props = cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, version, | |
| "/Microsoft.VCToolsVersion."_s, version, ".props"_s); | |
| if (cmSystemTools::PathExists(props)) { | |
| return AuxToolset::PropsExist; | |
| } | |
| // Accept the toolset version that is default in the current VS version | |
| // by matching the name later VS versions will use for the SxS props files. | |
| std::string vcToolsetVersion; | |
| if (this->vsSetupAPIHelper.GetVCToolsetVersion(vcToolsetVersion)) { | |
| // Accept an exact-match (three-component version). | |
| if (version == vcToolsetVersion) { | |
| return AuxToolset::Default; | |
| } | |
| // Accept known SxS props file names using four version components | |
| // in VS versions later than the current. | |
| if (version == "14.28.16.9" && vcToolsetVersion == "14.28.29910") { | |
| return AuxToolset::Default; | |
| } | |
| if (version == "14.29.16.10" && vcToolsetVersion == "14.29.30037") { | |
| return AuxToolset::Default; | |
| } | |
| // The first two components of the default toolset version typically | |
| // match the name used by later VS versions for the SxS props files. | |
| cmsys::RegularExpression twoComponent("^([0-9]+\\.[0-9]+)"); | |
| if (twoComponent.find(version)) { | |
| std::string const versionPrefix = cmStrCat(twoComponent.match(1), '.'); | |
| if (cmHasPrefix(vcToolsetVersion, versionPrefix)) { | |
| return AuxToolset::Default; | |
| } | |
| } | |
| } | |
| return AuxToolset::PropsMissing; | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf) | |
| { | |
| // If the Win 8.1 SDK is installed then we can select a SDK matching | |
| // the target Windows version. | |
| if (this->IsWin81SDKInstalled()) { | |
| // VS 2019 does not default to 8.1 so specify it explicitly when needed. | |
| if (this->Version >= cmGlobalVisualStudioGenerator::VS16 && | |
| !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) { | |
| this->SetWindowsTargetPlatformVersion("8.1", mf); | |
| return true; | |
| } | |
| return cmGlobalVisualStudio14Generator::InitializeWindows(mf); | |
| } | |
| // Otherwise we must choose a Win 10 SDK even if we are not targeting | |
| // Windows 10. | |
| return this->SelectWindows10SDK(mf, false); | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::SelectWindowsStoreToolset( | |
| std::string& toolset) const | |
| { | |
| if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) { | |
| if (this->IsWindowsStoreToolsetInstalled() && | |
| this->IsWindowsDesktopToolsetInstalled()) { | |
| toolset = VSVersionToToolset(this->Version); | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| return this->cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset( | |
| toolset); | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::IsWindowsDesktopToolsetInstalled() | |
| const | |
| { | |
| return vsSetupAPIHelper.IsVSInstalled(); | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::IsWindowsStoreToolsetInstalled() | |
| const | |
| { | |
| return vsSetupAPIHelper.IsWin10SDKInstalled(); | |
| } | |
| bool cmGlobalVisualStudioVersionedGenerator::IsWin81SDKInstalled() const | |
| { | |
| // Does the VS installer tool know about one? | |
| if (vsSetupAPIHelper.IsWin81SDKInstalled()) { | |
| return true; | |
| } | |
| // Does the registry know about one (e.g. from VS 2015)? | |
| std::string win81Root; | |
| if (cmSystemTools::ReadRegistryValue( | |
| "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" | |
| "Windows Kits\\Installed Roots;KitsRoot81", | |
| win81Root, cmSystemTools::KeyWOW64_32) || | |
| cmSystemTools::ReadRegistryValue( | |
| "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\" | |
| "Windows Kits\\Installed Roots;KitsRoot81", | |
| win81Root, cmSystemTools::KeyWOW64_32)) { | |
| return cmSystemTools::FileExists(win81Root + "/include/um/windows.h", | |
| true); | |
| } | |
| return false; | |
| } | |
| std::string | |
| cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersionDefault( | |
| cmMakefile*) const | |
| { | |
| return std::string(); | |
| } | |
| std::string cmGlobalVisualStudioVersionedGenerator::FindMSBuildCommand() | |
| { | |
| std::string msbuild; | |
| // Ask Visual Studio Installer tool. | |
| std::string vs; | |
| if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) { | |
| if (this->Version >= cmGlobalVisualStudioGenerator::VS17) { | |
| msbuild = vs + "/MSBuild/Current/Bin/amd64/MSBuild.exe"; | |
| if (cmSystemTools::FileExists(msbuild)) { | |
| return msbuild; | |
| } | |
| } | |
| msbuild = vs + "/MSBuild/Current/Bin/MSBuild.exe"; | |
| if (cmSystemTools::FileExists(msbuild)) { | |
| return msbuild; | |
| } | |
| msbuild = vs + "/MSBuild/15.0/Bin/MSBuild.exe"; | |
| if (cmSystemTools::FileExists(msbuild)) { | |
| return msbuild; | |
| } | |
| } | |
| msbuild = "MSBuild.exe"; | |
| return msbuild; | |
| } | |
| std::string cmGlobalVisualStudioVersionedGenerator::FindDevEnvCommand() | |
| { | |
| std::string devenv; | |
| // Ask Visual Studio Installer tool. | |
| std::string vs; | |
| if (vsSetupAPIHelper.GetVSInstanceInfo(vs)) { | |
| devenv = vs + "/Common7/IDE/devenv.com"; | |
| if (cmSystemTools::FileExists(devenv)) { | |
| return devenv; | |
| } | |
| } | |
| devenv = "devenv.com"; | |
| return devenv; | |
| } |