Browse Source

Merge topic 'vs-refactor-toolset-parsing'

f773933f VS: Refactor generator toolset parsing
d9e2b9a9 Tests: Split out RunCMake.GeneratorToolset Xcode checks
Brad King 8 years ago
parent
commit
160083b04d

+ 69 - 13
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") {

+ 5 - 1
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 ""; }
 };

+ 6 - 10
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)

+ 2 - 2
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);

+ 1 - 0
Tests/RunCMake/GeneratorToolset/BadToolsetFormat-result.txt

@@ -0,0 +1 @@
+1

+ 10 - 0
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 '='\.$

+ 1 - 0
Tests/RunCMake/GeneratorToolset/BadToolsetFormat.cmake

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

+ 2 - 2
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]'\.$

+ 1 - 0
Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice-result.txt

@@ -0,0 +1 @@
+1

+ 10 - 0
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'\.$

+ 1 - 0
Tests/RunCMake/GeneratorToolset/BadToolsetHostArchTwice.cmake

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

+ 1 - 0
Tests/RunCMake/GeneratorToolset/BadToolsetHostArchXcode-result.txt

@@ -0,0 +1 @@
+1

+ 10 - 0
Tests/RunCMake/GeneratorToolset/BadToolsetHostArchXcode-stderr.txt

@@ -0,0 +1,10 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
+  Generator
+
+    .*
+
+  does not recognize the toolset
+
+    Test Toolset,host=x6[45]
+
+  that was specified\.$

+ 1 - 0
Tests/RunCMake/GeneratorToolset/BadToolsetHostArchXcode.cmake

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

+ 10 - 1
Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake

@@ -3,7 +3,7 @@ include(RunCMake)
 set(RunCMake_GENERATOR_TOOLSET "")
 run_cmake(NoToolset)
 
-if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]|Xcode" AND NOT XCODE_BELOW_3)
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]")
   set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
   run_cmake(TestToolset)
   if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[245]")
@@ -17,10 +17,19 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[01245]|Xcode" AND NOT XCODE_
     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)
+  set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
+  run_cmake(BadToolsetHostArchXcode)
 else()
   set(RunCMake_GENERATOR_TOOLSET "Bad Toolset")
   run_cmake(BadToolset)