瀏覽代碼

CMake: Add CMAKE_GENERATOR_PLATFORM option

Reject the option by default.  It will be implemented on a per-generator
basis.  Pass the setting into try_compile project generation.  Add cache
entry CMAKE_GENERATOR_PLATFORM and associated variable documentation to
hold the value persistently.

Add a RunCMake.GeneratorPlatform test to cover basic use cases for the
option.  Verify that CMAKE_GENERATOR_PLATFORM is empty by default, and
that it is rejected when the generator does not support a user setting.
Brad King 11 年之前
父節點
當前提交
0f1f1271e6

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -37,6 +37,7 @@ Variables that Provide Information
    /variable/CMAKE_EXTRA_GENERATOR
    /variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
    /variable/CMAKE_GENERATOR
+   /variable/CMAKE_GENERATOR_PLATFORM
    /variable/CMAKE_GENERATOR_TOOLSET
    /variable/CMAKE_HOME_DIRECTORY
    /variable/CMAKE_IMPORT_LIBRARY_PREFIX

+ 13 - 0
Help/variable/CMAKE_GENERATOR_PLATFORM.rst

@@ -0,0 +1,13 @@
+CMAKE_GENERATOR_PLATFORM
+------------------------
+
+Generator-specific target platform name specified by user.
+
+Some CMake generators support a target platform name to be given
+to the native build system to choose a compiler toolchain.
+
+The value of this variable should never be modified by project code.
+A toolchain file specified by the :variable:`CMAKE_TOOLCHAIN_FILE`
+variable may initialize ``CMAKE_GENERATOR_PLATFORM``.  Once a given
+build tree has been initialized with a particular value for this
+variable, changing the value has undefined behavior.

+ 29 - 0
Source/cmGlobalGenerator.cxx

@@ -76,6 +76,27 @@ cmGlobalGenerator::~cmGlobalGenerator()
     }
 }
 
+bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
+                                             cmMakefile* mf)
+{
+  if(p.empty())
+    {
+    return true;
+    }
+  else
+    {
+    cmOStringStream e;
+    e <<
+      "Generator\n"
+      "  " << this->GetName() << "\n"
+      "does not support platform specification, but platform\n"
+      "  " << p << "\n"
+      "was specified.";
+    mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+    return false;
+    }
+}
+
 bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
                                             cmMakefile* mf)
 {
@@ -459,6 +480,14 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
     return;
     }
 
+  // Tell the generator about the platform, if any.
+  std::string platform = mf->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM");
+  if(!this->SetGeneratorPlatform(platform, mf))
+    {
+    cmSystemTools::SetFatalErrorOccured();
+    return;
+    }
+
   // Tell the generator about the toolset, if any.
   std::string toolset = mf->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET");
   if(!this->SetGeneratorToolset(toolset, mf))

+ 4 - 0
Source/cmGlobalGenerator.h

@@ -65,6 +65,10 @@ public:
   virtual bool SetSystemName(std::string const&, cmMakefile*)
     { return true; }
 
+  /** Set the generator-specific platform name.  Returns true if platform
+      is supported and false otherwise.  */
+  virtual bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf);
+
   /** Set the generator-specific toolset name.  Returns true if toolset
       is supported and false otherwise.  */
   virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);

+ 1 - 0
Source/cmMakefile.cxx

@@ -3548,6 +3548,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
   cm.SetHomeOutputDirectory(bindir);
   cm.SetStartDirectory(srcdir);
   cm.SetStartOutputDirectory(bindir);
+  cm.SetGeneratorPlatform(this->GetCMakeInstance()->GetGeneratorPlatform());
   cm.SetGeneratorToolset(this->GetCMakeInstance()->GetGeneratorToolset());
   cm.LoadCache();
   if(!gg->IsMultiConfig())

+ 28 - 0
Source/cmake.cxx

@@ -1445,6 +1445,34 @@ int cmake::ActualConfigure()
                         cmCacheManager::INTERNAL);
     }
 
+  if(const char* platformName =
+     this->CacheManager->GetCacheValue("CMAKE_GENERATOR_PLATFORM"))
+    {
+    if(this->GeneratorPlatform.empty())
+      {
+      this->GeneratorPlatform = platformName;
+      }
+    else if(this->GeneratorPlatform != platformName)
+      {
+      std::string message = "Error: generator platform: ";
+      message += this->GeneratorPlatform;
+      message += "\nDoes not match the platform used previously: ";
+      message += platformName;
+      message +=
+        "\nEither remove the CMakeCache.txt file and CMakeFiles "
+        "directory or choose a different binary directory.";
+      cmSystemTools::Error(message.c_str());
+      return -2;
+      }
+    }
+  else
+    {
+    this->CacheManager->AddCacheEntry("CMAKE_GENERATOR_PLATFORM",
+                                      this->GeneratorPlatform.c_str(),
+                                      "Name of generator platform.",
+                                      cmCacheManager::INTERNAL);
+    }
+
   if(const char* tsName =
      this->CacheManager->GetCacheValue("CMAKE_GENERATOR_TOOLSET"))
     {

+ 9 - 0
Source/cmake.h

@@ -191,6 +191,14 @@ class cmake
   ///! Get the names of the current registered generators
   void GetRegisteredGenerators(std::vector<std::string>& names);
 
+  ///! Set the name of the selected generator-specific platform.
+  void SetGeneratorPlatform(std::string const& ts)
+    { this->GeneratorPlatform = ts; }
+
+  ///! Get the name of the selected generator-specific platform.
+  std::string const& GetGeneratorPlatform() const
+    { return this->GeneratorPlatform; }
+
   ///! Set the name of the selected generator-specific toolset.
   void SetGeneratorToolset(std::string const& ts)
     { this->GeneratorToolset = ts; }
@@ -403,6 +411,7 @@ protected:
   std::string StartOutputDirectory;
   bool SuppressDevWarnings;
   bool DoSuppressDevWarnings;
+  std::string GeneratorPlatform;
   std::string GeneratorToolset;
 
   ///! read in a cmake list file to initialize the cache

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -58,6 +58,7 @@ add_RunCMake_test(ExternalData)
 add_RunCMake_test(FeatureSummary)
 add_RunCMake_test(FPHSA)
 add_RunCMake_test(GeneratorExpression)
+add_RunCMake_test(GeneratorPlatform)
 add_RunCMake_test(GeneratorToolset)
 add_RunCMake_test(TargetPropertyGeneratorExpressions)
 add_RunCMake_test(Languages)

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

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

+ 10 - 0
Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt

@@ -0,0 +1,10 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(project\):
+  Generator
+
+    .*
+
+  does not support platform specification, but platform
+
+    Bad Platform
+
+  was specified.$

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

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

+ 3 - 0
Tests/RunCMake/GeneratorPlatform/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

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

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

+ 4 - 0
Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt

@@ -0,0 +1,4 @@
+CMake Error at NoPlatform.cmake:2 \(message\):
+  CMAKE_GENERATOR_PLATFORM is empty as expected.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

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

@@ -0,0 +1,7 @@
+if("x${CMAKE_GENERATOR_PLATFORM}" STREQUAL "x")
+  message(FATAL_ERROR "CMAKE_GENERATOR_PLATFORM is empty as expected.")
+else()
+  message(FATAL_ERROR
+    "CMAKE_GENERATOR_PLATFORM is \"${CMAKE_GENERATOR_PLATFORM}\" "
+    "but should be empty!")
+endif()

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

@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(NoPlatform)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_GENERATOR_PLATFORM=Bad Platform")
+run_cmake(BadPlatform)
+unset(RunCMake_TEST_OPTIONS)