From 0f1f1271e6ddcea9074afe79685a731d4295c1f5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 5 Sep 2014 14:25:27 -0400 Subject: [PATCH] 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. --- Help/manual/cmake-variables.7.rst | 1 + Help/variable/CMAKE_GENERATOR_PLATFORM.rst | 13 +++++++++ Source/cmGlobalGenerator.cxx | 29 +++++++++++++++++++ Source/cmGlobalGenerator.h | 4 +++ Source/cmMakefile.cxx | 1 + Source/cmake.cxx | 28 ++++++++++++++++++ Source/cmake.h | 9 ++++++ Tests/RunCMake/CMakeLists.txt | 1 + .../GeneratorPlatform/BadPlatform-result.txt | 1 + .../GeneratorPlatform/BadPlatform-stderr.txt | 10 +++++++ .../GeneratorPlatform/BadPlatform.cmake | 1 + .../RunCMake/GeneratorPlatform/CMakeLists.txt | 3 ++ .../GeneratorPlatform/NoPlatform-result.txt | 1 + .../GeneratorPlatform/NoPlatform-stderr.txt | 4 +++ .../GeneratorPlatform/NoPlatform.cmake | 7 +++++ .../GeneratorPlatform/RunCMakeTest.cmake | 7 +++++ 16 files changed, 120 insertions(+) create mode 100644 Help/variable/CMAKE_GENERATOR_PLATFORM.rst create mode 100644 Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt create mode 100644 Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt create mode 100644 Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake create mode 100644 Tests/RunCMake/GeneratorPlatform/CMakeLists.txt create mode 100644 Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt create mode 100644 Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt create mode 100644 Tests/RunCMake/GeneratorPlatform/NoPlatform.cmake create mode 100644 Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 4d77edad4..149e4acea 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/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 diff --git a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst new file mode 100644 index 000000000..44d7fc41e --- /dev/null +++ b/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. diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 42efec278..90fd3f347 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/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::vectorconst& 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)) diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index f80c3c7bd..f16678906 100644 --- a/Source/cmGlobalGenerator.h +++ b/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); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 04b2d2786..efdaeec64 100644 --- a/Source/cmMakefile.cxx +++ b/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()) diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 6cc3b8152..c9c63c714 100644 --- a/Source/cmake.cxx +++ b/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")) { diff --git a/Source/cmake.h b/Source/cmake.h index 2d04902aa..919fc249a 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -191,6 +191,14 @@ class cmake ///! Get the names of the current registered generators void GetRegisteredGenerators(std::vector& 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 diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 3cd9947c1..d52a2b640 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/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) diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt b/Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/BadPlatform-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt b/Tests/RunCMake/GeneratorPlatform/BadPlatform-stderr.txt new file mode 100644 index 000000000..e31571451 --- /dev/null +++ b/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.$ diff --git a/Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake b/Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake new file mode 100644 index 000000000..2fc38e5c5 --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/BadPlatform.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This should not be reached!") diff --git a/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt new file mode 100644 index 000000000..12cd3c775 --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8.4) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt b/Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/NoPlatform-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt b/Tests/RunCMake/GeneratorPlatform/NoPlatform-stderr.txt new file mode 100644 index 000000000..e1c0da4c5 --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/GeneratorPlatform/NoPlatform.cmake b/Tests/RunCMake/GeneratorPlatform/NoPlatform.cmake new file mode 100644 index 000000000..1e0ca6deb --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake new file mode 100644 index 000000000..60217bcaf --- /dev/null +++ b/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)