Forráskód Böngészése

VS: Parse comma-separated fields from CMAKE_GENERATOR_PLATFORM

Brad King 2 éve
szülő
commit
f0a67b6291

+ 14 - 2
Help/variable/CMAKE_GENERATOR_PLATFORM.rst

@@ -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.

+ 82 - 1
Source/cmGlobalVisualStudio8Generator.cxx

@@ -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;

+ 6 - 0
Source/cmGlobalVisualStudio8Generator.h

@@ -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);
 };

+ 1 - 0
Tests/RunCMake/GeneratorPlatform/BadFieldNoComma-result.txt

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

+ 11 - 0
Tests/RunCMake/GeneratorPlatform/BadFieldNoComma-stderr.txt

@@ -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 '='\.$

+ 1 - 0
Tests/RunCMake/GeneratorPlatform/BadFieldNoComma.cmake

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

+ 1 - 0
Tests/RunCMake/GeneratorPlatform/BadFieldUnknown-result.txt

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

+ 11 - 0
Tests/RunCMake/GeneratorPlatform/BadFieldUnknown-stderr.txt

@@ -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='\.$

+ 1 - 0
Tests/RunCMake/GeneratorPlatform/BadFieldUnknown.cmake

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

+ 7 - 0
Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake

@@ -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()