diff options
author | Brad King <brad.king@kitware.com> | 2017-02-08 20:25:23 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-02-15 13:15:37 (GMT) |
commit | f773933f2630a17ce6b3b2aa6f8d7d8b65eb336c (patch) | |
tree | 5efd0ff7844eadfdf37c045bba5c8ea09e967aa8 | |
parent | d9e2b9a909b5f5b51ef3a106ed1d60a8d4cb795a (diff) | |
download | CMake-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.
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) |