summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-02-08 20:25:23 (GMT)
committerBrad King <brad.king@kitware.com>2017-02-15 13:15:37 (GMT)
commitf773933f2630a17ce6b3b2aa6f8d7d8b65eb336c (patch)
tree5efd0ff7844eadfdf37c045bba5c8ea09e967aa8
parentd9e2b9a909b5f5b51ef3a106ed1d60a8d4cb795a (diff)
downloadCMake-f773933f2630a17ce6b3b2aa6f8d7d8b65eb336c.zip
CMake-f773933f2630a17ce6b3b2aa6f8d7d8b65eb336c.tar.gz
CMake-f773933f2630a17ce6b3b2aa6f8d7d8b65eb336c.tar.bz2
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.
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx82
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h6
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx16
-rw-r--r--Source/cmGlobalVisualStudio12Generator.h4
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetFormat-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetFormat-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetFormat.cmake1
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetHostArch-stderr.txt4
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice.cmake1
-rw-r--r--Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake4
12 files changed, 112 insertions, 28 deletions
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index b64ae26..b1285ac 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -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") {
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 3fc62ec..c5e4bcd 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -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 ""; }
};
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index 2656dcc..de62ff0 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -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)
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index 79efe52..3453628 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -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);
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetFormat-result.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetFormat-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetFormat-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetFormat-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetFormat-stderr.txt
new file mode 100644
index 0000000..ab3a98f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetFormat-stderr.txt
@@ -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 '='\.$
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetFormat.cmake b/Tests/RunCMake/GeneratorToolset/BadToolsetFormat.cmake
new file mode 100644
index 0000000..2fc38e5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetFormat.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetHostArch-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArch-stderr.txt
index 5737e95..bd0063a 100644
--- a/Tests/RunCMake/GeneratorToolset/BadToolsetHostArch-stderr.txt
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArch-stderr.txt
@@ -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]'\.$
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-result.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-stderr.txt b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-stderr.txt
new file mode 100644
index 0000000..164d3aa
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-stderr.txt
@@ -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'\.$
diff --git a/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice.cmake b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice.cmake
new file mode 100644
index 0000000..2fc38e5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This should not be reached!")
diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
index 3c3d974..44c67a2 100644
--- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
@@ -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)