mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-01 19:30:13 -06:00
VS: Support version specification in CMAKE_GENERATOR_INSTANCE
This commit is contained in:
@@ -37,7 +37,12 @@ of the VS installation.
|
||||
|
||||
The ``key=value`` pairs form a comma-separated list of options to
|
||||
specify details of the instance selection.
|
||||
There are no supported pairs: this syntax is reserved for future use.
|
||||
Supported pairs are:
|
||||
|
||||
``version=<major>.<minor>.<MMMDD>.<BBB>``
|
||||
.. versionadded:: 3.23
|
||||
|
||||
Specify the 4-component VS Build Version.
|
||||
|
||||
If the value of ``CMAKE_GENERATOR_INSTANCE`` is not specified explicitly
|
||||
by the user or a toolchain file, CMake queries the Visual Studio Installer
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
#include "cmsys/Glob.hxx"
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmDocumentationEntry.h"
|
||||
@@ -109,6 +110,30 @@ static const char* VSVersionToToolset(
|
||||
return "";
|
||||
}
|
||||
|
||||
static std::string VSVersionToMajorString(
|
||||
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 "";
|
||||
}
|
||||
|
||||
static const char* VSVersionToAndroidToolset(
|
||||
cmGlobalVisualStudioGenerator::VSVersion v)
|
||||
{
|
||||
@@ -445,8 +470,32 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->GeneratorInstance.empty()) {
|
||||
if (!this->vsSetupAPIHelper.SetVSInstance(this->GeneratorInstance)) {
|
||||
if (!this->GeneratorInstanceVersion.empty()) {
|
||||
std::string const majorStr = VSVersionToMajorString(this->Version);
|
||||
cmsys::RegularExpression versionRegex(
|
||||
cmStrCat("^", majorStr, "\\.[0-9]+\\.[0-9]+\\.[0-9]+$"));
|
||||
if (!versionRegex.find(this->GeneratorInstanceVersion)) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
"Generator\n"
|
||||
" " << this->GetName() << "\n"
|
||||
"given instance specification\n"
|
||||
" " << i << "\n"
|
||||
"but the version field is not 4 integer components"
|
||||
" starting in " << majorStr << "."
|
||||
;
|
||||
/* clang-format on */
|
||||
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string vsInstance;
|
||||
if (!i.empty()) {
|
||||
vsInstance = i;
|
||||
if (!this->vsSetupAPIHelper.SetVSInstance(
|
||||
this->GeneratorInstance, this->GeneratorInstanceVersion)) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
@@ -455,13 +504,17 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
|
||||
"could not find specified instance of Visual Studio:\n"
|
||||
" " << i;
|
||||
/* clang-format on */
|
||||
if (!this->GeneratorInstance.empty() &&
|
||||
this->GeneratorInstanceVersion.empty() &&
|
||||
cmSystemTools::FileIsDirectory(this->GeneratorInstance)) {
|
||||
e << "\n"
|
||||
"The directory exists, but the instance is not known to the "
|
||||
"Visual Studio Installer.";
|
||||
}
|
||||
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string vsInstance;
|
||||
if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) {
|
||||
} else if (!this->vsSetupAPIHelper.GetVSInstanceInfo(vsInstance)) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
@@ -493,6 +546,7 @@ bool cmGlobalVisualStudioVersionedGenerator::ParseGeneratorInstance(
|
||||
std::string const& is, cmMakefile* mf)
|
||||
{
|
||||
this->GeneratorInstance.clear();
|
||||
this->GeneratorInstanceVersion.clear();
|
||||
|
||||
std::vector<std::string> const fields = cmTokenize(is, ",");
|
||||
std::vector<std::string>::const_iterator fi = fields.begin();
|
||||
@@ -563,8 +617,10 @@ bool cmGlobalVisualStudioVersionedGenerator::ParseGeneratorInstance(
|
||||
bool cmGlobalVisualStudioVersionedGenerator::ProcessGeneratorInstanceField(
|
||||
std::string const& key, std::string const& value)
|
||||
{
|
||||
static_cast<void>(key);
|
||||
static_cast<void>(value);
|
||||
if (key == "version") {
|
||||
this->GeneratorInstanceVersion = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,5 +83,6 @@ private:
|
||||
bool ParseGeneratorInstance(std::string const& is, cmMakefile* mf);
|
||||
|
||||
std::string GeneratorInstance;
|
||||
std::string GeneratorInstanceVersion;
|
||||
cm::optional<std::string> LastGeneratorInstanceString;
|
||||
};
|
||||
|
||||
@@ -102,10 +102,12 @@ cmVSSetupAPIHelper::~cmVSSetupAPIHelper()
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
bool cmVSSetupAPIHelper::SetVSInstance(std::string const& vsInstallLocation)
|
||||
bool cmVSSetupAPIHelper::SetVSInstance(std::string const& vsInstallLocation,
|
||||
std::string const& vsInstallVersion)
|
||||
{
|
||||
this->SpecifiedVSInstallLocation = vsInstallLocation;
|
||||
cmSystemTools::ConvertToUnixSlashes(this->SpecifiedVSInstallLocation);
|
||||
this->SpecifiedVSInstallVersion = vsInstallVersion;
|
||||
chosenInstanceInfo = VSInstanceInfo();
|
||||
return this->EnumerateAndChooseVSInstance();
|
||||
}
|
||||
@@ -366,6 +368,15 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance()
|
||||
std::string currentVSLocation = instanceInfo.GetInstallLocation();
|
||||
if (cmSystemTools::ComparePath(currentVSLocation,
|
||||
this->SpecifiedVSInstallLocation)) {
|
||||
if (this->SpecifiedVSInstallVersion.empty() ||
|
||||
instanceInfo.Version == this->SpecifiedVSInstallVersion) {
|
||||
chosenInstanceInfo = instanceInfo;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (!this->SpecifiedVSInstallVersion.empty()) {
|
||||
// We are looking for a specific version.
|
||||
if (instanceInfo.Version == this->SpecifiedVSInstallVersion) {
|
||||
chosenInstanceInfo = instanceInfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,8 @@ public:
|
||||
cmVSSetupAPIHelper(unsigned int version);
|
||||
~cmVSSetupAPIHelper();
|
||||
|
||||
bool SetVSInstance(std::string const& vsInstallLocation);
|
||||
bool SetVSInstance(std::string const& vsInstallLocation,
|
||||
std::string const& vsInstallVersion);
|
||||
|
||||
bool IsVSInstalled();
|
||||
bool GetVSInstanceInfo(std::string& vsInstallLocation);
|
||||
@@ -132,4 +133,5 @@ private:
|
||||
bool IsEWDKEnabled();
|
||||
|
||||
std::string SpecifiedVSInstallLocation;
|
||||
std::string SpecifiedVSInstallVersion;
|
||||
};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,11 @@
|
||||
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
Visual Studio [^
|
||||
]+
|
||||
|
||||
given instance specification
|
||||
|
||||
Test Instance,version=1\.2\.3\.4,version=1\.2\.3\.4
|
||||
|
||||
that contains duplicate field key 'version'\.$
|
||||
1
Tests/RunCMake/GeneratorInstance/BadFieldDuplicate.cmake
Normal file
1
Tests/RunCMake/GeneratorInstance/BadFieldDuplicate.cmake
Normal file
@@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,11 @@
|
||||
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
Visual Studio [^
|
||||
]+
|
||||
|
||||
given instance specification
|
||||
|
||||
version=1\.2\.3
|
||||
|
||||
but the version field is not 4 integer components starting in [0-9]+\.$
|
||||
1
Tests/RunCMake/GeneratorInstance/BadVersionFormat1.cmake
Normal file
1
Tests/RunCMake/GeneratorInstance/BadVersionFormat1.cmake
Normal file
@@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,11 @@
|
||||
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
Visual Studio [^
|
||||
]+
|
||||
|
||||
given instance specification
|
||||
|
||||
version=1\.2\.3\.x
|
||||
|
||||
but the version field is not 4 integer components starting in [0-9]+\.$
|
||||
1
Tests/RunCMake/GeneratorInstance/BadVersionFormat2.cmake
Normal file
1
Tests/RunCMake/GeneratorInstance/BadVersionFormat2.cmake
Normal file
@@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,9 @@
|
||||
^CMake Error at CMakeLists.txt:[0-9] \(project\):
|
||||
Generator
|
||||
|
||||
Visual Studio [^
|
||||
]+
|
||||
|
||||
could not find specified instance of Visual Studio:
|
||||
|
||||
version=[0-9]+\.999\.99999\.999$
|
||||
1
Tests/RunCMake/GeneratorInstance/BadVersionNumber.cmake
Normal file
1
Tests/RunCMake/GeneratorInstance/BadVersionNumber.cmake
Normal file
@@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
||||
@@ -11,3 +11,4 @@ elseif(NOT IS_DIRECTORY "${CMAKE_GENERATOR_INSTANCE}")
|
||||
" ${CMAKE_GENERATOR_INSTANCE}\n"
|
||||
"which is not an existing directory.")
|
||||
endif()
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/instance.txt" "${CMAKE_GENERATOR_INSTANCE}")
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
include(RunCMake)
|
||||
|
||||
if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio 1[56789]")
|
||||
if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[56789])")
|
||||
set(vs_major "${CMAKE_MATCH_1}")
|
||||
|
||||
set(RunCMake_GENERATOR_INSTANCE "")
|
||||
run_cmake(DefaultInstance)
|
||||
set(instance_txt "${RunCMake_BINARY_DIR}/DefaultInstance-build/instance.txt")
|
||||
if(EXISTS "${instance_txt}")
|
||||
file(READ "${instance_txt}" default_instance)
|
||||
endif()
|
||||
|
||||
set(RunCMake_GENERATOR_INSTANCE "${RunCMake_SOURCE_DIR}/instance_does_not_exist")
|
||||
run_cmake(MissingInstance)
|
||||
@@ -14,6 +20,18 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio 1[56789]")
|
||||
run_cmake(BadFieldNoComma)
|
||||
set(RunCMake_GENERATOR_INSTANCE "Test Instance,unknown=")
|
||||
run_cmake(BadFieldUnknown)
|
||||
set(RunCMake_GENERATOR_INSTANCE "Test Instance,version=1.2.3.4,version=1.2.3.4")
|
||||
run_cmake(BadFieldDuplicate)
|
||||
set(RunCMake_GENERATOR_INSTANCE "version=1.2.3")
|
||||
run_cmake(BadVersionFormat1)
|
||||
set(RunCMake_GENERATOR_INSTANCE "version=1.2.3.x")
|
||||
run_cmake(BadVersionFormat2)
|
||||
set(RunCMake_GENERATOR_INSTANCE "version=${vs_major}.999.99999.999")
|
||||
run_cmake(BadVersionNumber)
|
||||
if(IS_DIRECTORY "${default_instance}")
|
||||
set(RunCMake_GENERATOR_INSTANCE "${default_instance},version=${vs_major}.999.99999.999")
|
||||
run_cmake(WrongVersion)
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_GENERATOR_INSTANCE "")
|
||||
run_cmake(NoInstance)
|
||||
|
||||
1
Tests/RunCMake/GeneratorInstance/WrongVersion-result.txt
Normal file
1
Tests/RunCMake/GeneratorInstance/WrongVersion-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
10
Tests/RunCMake/GeneratorInstance/WrongVersion-stderr.txt
Normal file
10
Tests/RunCMake/GeneratorInstance/WrongVersion-stderr.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
^CMake Error at CMakeLists.txt:[0-9] \(project\):
|
||||
Generator
|
||||
|
||||
Visual Studio [^
|
||||
]+
|
||||
|
||||
could not find specified instance of Visual Studio:
|
||||
|
||||
[^,
|
||||
]+,version=[0-9]+\.999\.99999\.999$
|
||||
1
Tests/RunCMake/GeneratorInstance/WrongVersion.cmake
Normal file
1
Tests/RunCMake/GeneratorInstance/WrongVersion.cmake
Normal file
@@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
||||
Reference in New Issue
Block a user