mirror of
https://github.com/reactos/CMake.git
synced 2024-11-24 12:09:48 +00:00
VS: Refactor generator toolset parsing
We parse `CMAKE_GENERATOR_TOOLSET` values of the forms: * `toolset` * `toolset,host=x64` * `host=x64` Generalize the parsing to support the forms: * `toolset` * `toolset[,key=value]*` * `key=value[,key=value]*` Disallow duplicate keys. Require all but the first field to be of `key=value` form.
This commit is contained in:
parent
d9e2b9a909
commit
f773933f26
@ -182,24 +182,80 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
|
||||
bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
|
||||
std::string const& ts, cmMakefile* mf)
|
||||
{
|
||||
if (ts.find_first_of(",=") != ts.npos) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
"Generator\n"
|
||||
" " << this->GetName() << "\n"
|
||||
"does not recognize the toolset\n"
|
||||
" " << ts << "\n"
|
||||
"that was specified.";
|
||||
/* clang-format on */
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return false;
|
||||
std::vector<std::string> const fields = cmSystemTools::tokenize(ts, ",");
|
||||
std::vector<std::string>::const_iterator fi = fields.begin();
|
||||
if (fi == fields.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The first field may be the VS platform toolset.
|
||||
if (fi->find('=') == fi->npos) {
|
||||
this->GeneratorToolset = *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 toolset specification\n"
|
||||
" " << ts << "\n"
|
||||
"that contains a field after the first ',' with no '='."
|
||||
;
|
||||
/* clang-format on */
|
||||
mf->IssueMessage(cmake::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 toolset specification\n"
|
||||
" " << ts << "\n"
|
||||
"that contains duplicate field key '" << key << "'."
|
||||
;
|
||||
/* clang-format on */
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return false;
|
||||
}
|
||||
if (!this->ProcessGeneratorToolsetField(key, value)) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
e <<
|
||||
"Generator\n"
|
||||
" " << this->GetName() << "\n"
|
||||
"given toolset specification\n"
|
||||
" " << ts << "\n"
|
||||
"that contains invalid field '" << *fi << "'."
|
||||
;
|
||||
/* clang-format on */
|
||||
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this->GeneratorToolset = ts;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
|
||||
std::string const& key, std::string const& value)
|
||||
{
|
||||
static_cast<void>(key);
|
||||
static_cast<void>(value);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf)
|
||||
{
|
||||
if (this->SystemName == "Windows") {
|
||||
|
@ -23,7 +23,6 @@ public:
|
||||
virtual bool SetSystemName(std::string const& s, cmMakefile* mf);
|
||||
virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
|
||||
virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
|
||||
virtual bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
|
||||
|
||||
virtual void GenerateBuildCommand(
|
||||
std::vector<std::string>& makeCommand, const std::string& makeProgram,
|
||||
@ -106,6 +105,9 @@ protected:
|
||||
virtual bool InitializeWindowsPhone(cmMakefile* mf);
|
||||
virtual bool InitializeWindowsStore(cmMakefile* mf);
|
||||
|
||||
virtual bool ProcessGeneratorToolsetField(std::string const& key,
|
||||
std::string const& value);
|
||||
|
||||
virtual std::string SelectWindowsCEToolset() const;
|
||||
virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
|
||||
virtual bool SelectWindowsStoreToolset(std::string& toolset) const;
|
||||
@ -156,6 +158,8 @@ private:
|
||||
virtual std::string FindDevEnvCommand();
|
||||
virtual std::string GetVSMakeProgram() { return this->GetMSBuildCommand(); }
|
||||
|
||||
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
|
||||
|
||||
// We do not use the reload macros for VS >= 10.
|
||||
virtual std::string GetUserMacrosDirectory() { return ""; }
|
||||
};
|
||||
|
@ -109,19 +109,15 @@ bool cmGlobalVisualStudio12Generator::MatchesGeneratorName(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmGlobalVisualStudio12Generator::ParseGeneratorToolset(
|
||||
std::string const& ts, cmMakefile* mf)
|
||||
bool cmGlobalVisualStudio12Generator::ProcessGeneratorToolsetField(
|
||||
std::string const& key, std::string const& value)
|
||||
{
|
||||
std::string::size_type ts_end = ts.size();
|
||||
if (cmHasLiteralSuffix(ts, ",host=x64")) {
|
||||
if (key == "host" && value == "x64") {
|
||||
this->GeneratorToolsetHostArchitecture = "x64";
|
||||
ts_end -= 9;
|
||||
} else if (ts == "host=x64") {
|
||||
this->GeneratorToolsetHostArchitecture = "x64";
|
||||
ts_end = 0;
|
||||
return true;
|
||||
}
|
||||
return this->cmGlobalVisualStudio11Generator::ParseGeneratorToolset(
|
||||
ts.substr(0, ts_end), mf);
|
||||
return this->cmGlobalVisualStudio11Generator::ProcessGeneratorToolsetField(
|
||||
key, value);
|
||||
}
|
||||
|
||||
bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf)
|
||||
|
@ -31,8 +31,8 @@ public:
|
||||
// version number
|
||||
virtual const char* GetToolsVersion() { return "12.0"; }
|
||||
protected:
|
||||
bool ParseGeneratorToolset(std::string const& ts,
|
||||
cmMakefile* mf) CM_OVERRIDE;
|
||||
bool ProcessGeneratorToolsetField(std::string const& key,
|
||||
std::string const& value) CM_OVERRIDE;
|
||||
|
||||
virtual bool InitializeWindowsPhone(cmMakefile* mf);
|
||||
virtual bool InitializeWindowsStore(cmMakefile* mf);
|
||||
|
@ -0,0 +1 @@
|
||||
1
|
10
Tests/RunCMake/GeneratorToolset/BadToolsetFormat-stderr.txt
Normal file
10
Tests/RunCMake/GeneratorToolset/BadToolsetFormat-stderr.txt
Normal file
@ -0,0 +1,10 @@
|
||||
CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
.*
|
||||
|
||||
given toolset specification
|
||||
|
||||
Test Toolset,not_a_key
|
||||
|
||||
that contains a field after the first ',' with no '='\.$
|
1
Tests/RunCMake/GeneratorToolset/BadToolsetFormat.cmake
Normal file
1
Tests/RunCMake/GeneratorToolset/BadToolsetFormat.cmake
Normal file
@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
@ -3,8 +3,8 @@ CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
|
||||
.*
|
||||
|
||||
does not recognize the toolset
|
||||
given toolset specification
|
||||
|
||||
Test Toolset,host=x6[45]
|
||||
|
||||
that was specified\.$
|
||||
that contains invalid field 'host=x6[45]'\.$
|
||||
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,10 @@
|
||||
CMake Error at CMakeLists.txt:[0-9]+ \(project\):
|
||||
Generator
|
||||
|
||||
.*
|
||||
|
||||
given toolset specification
|
||||
|
||||
Test Toolset,host=x64,host=x64
|
||||
|
||||
that contains duplicate field key 'host'\.$
|
@ -0,0 +1 @@
|
||||
message(FATAL_ERROR "This should not be reached!")
|
@ -17,10 +17,14 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]")
|
||||
run_cmake(TestToolsetHostArchNone)
|
||||
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x65")
|
||||
run_cmake(BadToolsetHostArch)
|
||||
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x64")
|
||||
run_cmake(BadToolsetHostArchTwice)
|
||||
else()
|
||||
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
|
||||
run_cmake(BadToolsetHostArch)
|
||||
endif()
|
||||
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,not_a_key")
|
||||
run_cmake(BadToolsetFormat)
|
||||
elseif("${RunCMake_GENERATOR}" STREQUAL "Xcode" AND NOT XCODE_BELOW_3)
|
||||
set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
|
||||
run_cmake(TestToolset)
|
||||
|
Loading…
Reference in New Issue
Block a user