mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-22 14:23:10 -05:00
VS: Parse comma-separated fields from CMAKE_GENERATOR_INSTANCE
This commit is contained in:
@@ -26,7 +26,18 @@ Visual Studio Instance Selection
|
|||||||
:ref:`Visual Studio Generators` support instance specification for
|
:ref:`Visual Studio Generators` support instance specification for
|
||||||
Visual Studio 2017 and above. The ``CMAKE_GENERATOR_INSTANCE`` variable
|
Visual Studio 2017 and above. The ``CMAKE_GENERATOR_INSTANCE`` variable
|
||||||
may be set as a cache entry selecting an instance of Visual Studio
|
may be set as a cache entry selecting an instance of Visual Studio
|
||||||
via the absolute path to the top-level directory of the VS installation.
|
via one of the following forms:
|
||||||
|
|
||||||
|
* ``location``
|
||||||
|
* ``location[,key=value]*``
|
||||||
|
* ``key=value[,key=value]*``
|
||||||
|
|
||||||
|
The ``location`` specifies the absolute path to the top-level directory
|
||||||
|
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.
|
||||||
|
|
||||||
If the value of ``CMAKE_GENERATOR_INSTANCE`` is not specified explicitly
|
If the value of ``CMAKE_GENERATOR_INSTANCE`` is not specified explicitly
|
||||||
by the user or a toolchain file, CMake queries the Visual Studio Installer
|
by the user or a toolchain file, CMake queries the Visual Studio Installer
|
||||||
|
|||||||
@@ -441,8 +441,12 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i.empty()) {
|
if (!this->ParseGeneratorInstance(i, mf)) {
|
||||||
if (!this->vsSetupAPIHelper.SetVSInstance(i)) {
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->GeneratorInstance.empty()) {
|
||||||
|
if (!this->vsSetupAPIHelper.SetVSInstance(this->GeneratorInstance)) {
|
||||||
std::ostringstream e;
|
std::ostringstream e;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
e <<
|
e <<
|
||||||
@@ -485,6 +489,85 @@ bool cmGlobalVisualStudioVersionedGenerator::SetGeneratorInstance(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cmGlobalVisualStudioVersionedGenerator::ParseGeneratorInstance(
|
||||||
|
std::string const& is, cmMakefile* mf)
|
||||||
|
{
|
||||||
|
this->GeneratorInstance.clear();
|
||||||
|
|
||||||
|
std::vector<std::string> const fields = cmTokenize(is, ",");
|
||||||
|
std::vector<std::string>::const_iterator fi = fields.begin();
|
||||||
|
if (fi == fields.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first field may be the VS instance.
|
||||||
|
if (fi->find('=') == fi->npos) {
|
||||||
|
this->GeneratorInstance = *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 instance specification\n"
|
||||||
|
" " << is << "\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 instance specification\n"
|
||||||
|
" " << is << "\n"
|
||||||
|
"that contains duplicate field key '" << key << "'."
|
||||||
|
;
|
||||||
|
/* clang-format on */
|
||||||
|
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!this->ProcessGeneratorInstanceField(key, value)) {
|
||||||
|
std::ostringstream e;
|
||||||
|
/* clang-format off */
|
||||||
|
e <<
|
||||||
|
"Generator\n"
|
||||||
|
" " << this->GetName() << "\n"
|
||||||
|
"given instance specification\n"
|
||||||
|
" " << is << "\n"
|
||||||
|
"that contains invalid field '" << *fi << "'."
|
||||||
|
;
|
||||||
|
/* clang-format on */
|
||||||
|
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmGlobalVisualStudioVersionedGenerator::ProcessGeneratorInstanceField(
|
||||||
|
std::string const& key, std::string const& value)
|
||||||
|
{
|
||||||
|
static_cast<void>(key);
|
||||||
|
static_cast<void>(value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool cmGlobalVisualStudioVersionedGenerator::GetVSInstance(
|
bool cmGlobalVisualStudioVersionedGenerator::GetVSInstance(
|
||||||
std::string& dir) const
|
std::string& dir) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ protected:
|
|||||||
|
|
||||||
std::string GetWindows10SDKMaxVersionDefault(cmMakefile*) const override;
|
std::string GetWindows10SDKMaxVersionDefault(cmMakefile*) const override;
|
||||||
|
|
||||||
|
virtual bool ProcessGeneratorInstanceField(std::string const& key,
|
||||||
|
std::string const& value);
|
||||||
|
|
||||||
std::string FindMSBuildCommand() override;
|
std::string FindMSBuildCommand() override;
|
||||||
std::string FindDevEnvCommand() override;
|
std::string FindDevEnvCommand() override;
|
||||||
|
|
||||||
@@ -76,5 +79,9 @@ private:
|
|||||||
class Factory17;
|
class Factory17;
|
||||||
friend class Factory17;
|
friend class Factory17;
|
||||||
mutable cmVSSetupAPIHelper vsSetupAPIHelper;
|
mutable cmVSSetupAPIHelper vsSetupAPIHelper;
|
||||||
|
|
||||||
|
bool ParseGeneratorInstance(std::string const& is, cmMakefile* mf);
|
||||||
|
|
||||||
|
std::string GeneratorInstance;
|
||||||
cm::optional<std::string> LastGeneratorInstanceString;
|
cm::optional<std::string> LastGeneratorInstanceString;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||||
|
Generator
|
||||||
|
|
||||||
|
Visual Studio [^
|
||||||
|
]+
|
||||||
|
|
||||||
|
given instance specification
|
||||||
|
|
||||||
|
Test Instance,nocomma
|
||||||
|
|
||||||
|
that contains a field after the first ',' with no '='\.$
|
||||||
@@ -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
|
||||||
|
|
||||||
|
Test Instance,unknown=
|
||||||
|
|
||||||
|
that contains invalid field 'unknown='\.$
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
message(FATAL_ERROR "This should not be reached!")
|
||||||
@@ -9,6 +9,11 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio 1[56789]")
|
|||||||
set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/MissingInstance-toolchain.cmake)
|
set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/MissingInstance-toolchain.cmake)
|
||||||
run_cmake(MissingInstanceToolchain)
|
run_cmake(MissingInstanceToolchain)
|
||||||
unset(RunCMake_TEST_OPTIONS)
|
unset(RunCMake_TEST_OPTIONS)
|
||||||
|
|
||||||
|
set(RunCMake_GENERATOR_INSTANCE "Test Instance,nocomma")
|
||||||
|
run_cmake(BadFieldNoComma)
|
||||||
|
set(RunCMake_GENERATOR_INSTANCE "Test Instance,unknown=")
|
||||||
|
run_cmake(BadFieldUnknown)
|
||||||
else()
|
else()
|
||||||
set(RunCMake_GENERATOR_INSTANCE "")
|
set(RunCMake_GENERATOR_INSTANCE "")
|
||||||
run_cmake(NoInstance)
|
run_cmake(NoInstance)
|
||||||
|
|||||||
Reference in New Issue
Block a user