VS: Parse comma-separated fields from CMAKE_GENERATOR_PLATFORM

This commit is contained in:
Brad King
2023-03-31 12:41:52 -04:00
parent e259063b0a
commit f0a67b6291
10 changed files with 135 additions and 3 deletions

View File

@@ -29,5 +29,17 @@ See native build system documentation for allowed platform names.
Visual Studio Platform Selection
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
On :ref:`Visual Studio Generators` the selected platform name
is provided in the :variable:`CMAKE_VS_PLATFORM_NAME` variable.
The :ref:`Visual Studio Generators` support platform specification
using one of these forms:
* ``platform``
* ``platform[,key=value]*``
* ``key=value[,key=value]*``
The ``platform`` specifies the target platform (VS target architecture),
such as ``x64``, ``ARM64``, or ``Win32``. The selected platform
name is provided in the :variable:`CMAKE_VS_PLATFORM_NAME` variable.
The ``key=value`` pairs form a comma-separated list of options to
specify generator-specific details of the platform selection.
There are no supported pairs: this syntax is reserved for future use.

View File

@@ -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.
@@ -124,6 +126,85 @@ bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p,
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;

View File

@@ -62,6 +62,9 @@ protected:
virtual bool InitializePlatform(cmMakefile* mf);
virtual bool ProcessGeneratorPlatformField(std::string const& key,
std::string const& value);
void AddExtraIDETargets() override;
std::string FindDevEnvCommand() override;
@@ -98,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);
};

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,11 @@
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
Generator
Visual Studio [^
]+
given platform specification
Test Platform,nocomma
that contains a field after the first ',' with no '='\.$

View File

@@ -0,0 +1 @@
message(FATAL_ERROR "This should not be reached!")

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,11 @@
^CMake Error at CMakeLists.txt:[0-9]+ \(project\):
Generator
Visual Studio [^
]+
given platform specification
Test Platform,unknown=
that contains invalid field 'unknown='\.$

View File

@@ -0,0 +1 @@
message(FATAL_ERROR "This should not be reached!")

View File

@@ -26,3 +26,10 @@ else()
run_cmake(BadPlatformToolchain)
unset(RunCMake_TEST_OPTIONS)
endif()
if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$")
set(RunCMake_GENERATOR_PLATFORM "Test Platform,nocomma")
run_cmake(BadFieldNoComma)
set(RunCMake_GENERATOR_PLATFORM "Test Platform,unknown=")
run_cmake(BadFieldUnknown)
endif()