
In commit 4ea3a88625
(MSVC: Add support for targeting ARM64EC,
2020-12-30, v3.20.0-rc1~121^2) the `ARM64EC` platform was accidentally
added to the list for VS 15 (2017) instead of VS 16 (2019). Its
omission from the list of platforms was then repeated for VS 17 (2022).
Issue: #21724
756 lines
22 KiB
C++
756 lines
22 KiB
C++
/* 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;
|
|
}
|