From e4055a6144c63c83fe2f39440ecfb9a0bcbfae0d Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 28 Jan 2015 13:31:18 -0500 Subject: Xcode: Add internal API to find xcodebuild Teach the Xcode generator to compute the location of this tool or the cmakexbuild wrapper. Add internal APIs to get the locations on demand. Use the "cmakexbuild" wrapper for Xcode < 4, and "xcodebuild" for modern Xcode. --- Source/cmGlobalXCodeGenerator.cxx | 31 +++++++++++++++++++++++++++++++ Source/cmGlobalXCodeGenerator.h | 5 +++++ 2 files changed, 36 insertions(+) diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index b6c428b..3b4dd17 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -143,6 +143,7 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version) this->ResourcesGroupChildren = 0; this->CurrentMakefile = 0; this->CurrentLocalGenerator = 0; + this->XcodeBuildCommandInitialized = false; } //---------------------------------------------------------------------------- @@ -202,6 +203,36 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory } //---------------------------------------------------------------------------- +std::string const& cmGlobalXCodeGenerator::GetXcodeBuildCommand() +{ + if(!this->XcodeBuildCommandInitialized) + { + this->XcodeBuildCommandInitialized = true; + this->XcodeBuildCommand = this->FindXcodeBuildCommand(); + } + return this->XcodeBuildCommand; +} + +//---------------------------------------------------------------------------- +std::string cmGlobalXCodeGenerator::FindXcodeBuildCommand() +{ + if (this->XcodeVersion >= 40) + { + std::string makeProgram = cmSystemTools::FindProgram("xcodebuild"); + if (makeProgram.empty()) + { + makeProgram = "xcodebuild"; + } + return makeProgram; + } + else + { + // Use cmakexbuild wrapper to suppress environment dump from output. + return cmSystemTools::GetCMakeCommand() + "xbuild"; + } +} + +//---------------------------------------------------------------------------- bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts, cmMakefile* mf) { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index a39c8c7..e54bb37 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -212,6 +212,11 @@ protected: std::vector XCodeObjects; cmXCodeObject* RootObject; private: + std::string const& GetXcodeBuildCommand(); + std::string FindXcodeBuildCommand(); + std::string XcodeBuildCommand; + bool XcodeBuildCommandInitialized; + void PrintCompilerAdvice(std::ostream&, std::string const&, const char*) const {} -- cgit v0.12 From 11e2e6cadf7f0ee36b7ccecaa11457949382b75f Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 28 Jan 2015 13:59:32 -0500 Subject: Xcode: Select make program at build time Extend the change made in commit v3.0.0-rc1~260^2~16 (Teach GenerateBuildCommand to find its own make program, 2013-11-13) to have the Xcode generator pick between "xcodebuild" and CMake's own copy of "cmakexbuild" at build time based on the version of Xcode. --- Source/cmGlobalXCodeGenerator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 3b4dd17..ebad7da 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -303,7 +303,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand( { // now build the test makeCommand.push_back( - this->SelectMakeProgram(makeProgram, "xcodebuild") + this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand()) ); makeCommand.push_back("-project"); -- cgit v0.12 From ab9fa54d4841e5b0eff8d241ad8edb47401b0394 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 28 Jan 2015 14:00:02 -0500 Subject: Xcode: Switch to internal CMAKE_MAKE_PROGRAM lookup by generator (#15324) The "cmakexbuild" wrapper is not needed for Xcode 4 and above, and the path to it may change when CMake moves. Avoid storing a specific path to a build program in CMakeCache.txt and instead compute the value for CMAKE_MAKE_PROGRAM on demand. However, if a user does set the value explicitly then honor it. This does for Xcode what commit v3.0.0-rc1~260^2~4 (VS: Switch to internal CMAKE_MAKE_PROGRAM lookup by generators, 2013-11-15) did for Visual Studio generators. --- Help/release/dev/xcode-revise-make-program.rst | 6 ++++++ Help/variable/CMAKE_MAKE_PROGRAM.rst | 11 +++++++++-- Modules/CMakeFindXCode.cmake | 8 ++------ Source/cmGlobalGenerator.cxx | 19 ------------------- Source/cmGlobalXCodeGenerator.cxx | 14 +++++++++++++- Source/cmGlobalXCodeGenerator.h | 2 ++ Tests/CMakeLists.txt | 2 +- 7 files changed, 33 insertions(+), 29 deletions(-) create mode 100644 Help/release/dev/xcode-revise-make-program.rst diff --git a/Help/release/dev/xcode-revise-make-program.rst b/Help/release/dev/xcode-revise-make-program.rst new file mode 100644 index 0000000..f50cf44 --- /dev/null +++ b/Help/release/dev/xcode-revise-make-program.rst @@ -0,0 +1,6 @@ +xcode-revise-make-program +------------------------- + +* The :generator:`Xcode` generator no longer requires a value for + the :variable:`CMAKE_MAKE_PROGRAM` variable to be located up front. + It now locates ``xcodebuild`` when needed at build time. diff --git a/Help/variable/CMAKE_MAKE_PROGRAM.rst b/Help/variable/CMAKE_MAKE_PROGRAM.rst index 97caa8a..f1d88a5 100644 --- a/Help/variable/CMAKE_MAKE_PROGRAM.rst +++ b/Help/variable/CMAKE_MAKE_PROGRAM.rst @@ -23,8 +23,15 @@ to configure the project: otherwise undocumented ``cmakexbuild`` wrapper implementing some workarounds). - This generator stores ``CMAKE_MAKE_PROGRAM`` in the CMake cache - so that it may be edited by the user. + This generator prefers to lookup the build tool at build time + rather than to store ``CMAKE_MAKE_PROGRAM`` in the CMake cache + ahead of time. This is because ``xcodebuild`` is easy to find, + the ``cmakexbuild`` wrapper is needed only for older Xcode versions, + and the path to ``cmakexbuild`` may be outdated if CMake itself moves. + + For compatibility with versions of CMake prior to 3.2, if + a user or project explicitly adds ``CMAKE_MAKE_PROGRAM`` to + the CMake cache then CMake will use the specified value. * The Visual Studio generators set this to the full path to ``MSBuild.exe`` (VS >= 10), ``devenv.com`` (VS 7,8,9), diff --git a/Modules/CMakeFindXCode.cmake b/Modules/CMakeFindXCode.cmake index 5c4f596..da0b97b 100644 --- a/Modules/CMakeFindXCode.cmake +++ b/Modules/CMakeFindXCode.cmake @@ -12,9 +12,5 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -find_program(CMAKE_MAKE_PROGRAM - NAMES xcodebuild - PATHS - /usr/bin - ) -mark_as_advanced(CMAKE_MAKE_PROGRAM) +# Empty placeholder for input dependencies in existing +# build trees produced by older versions of CMake. diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 4c95a9f..6d0fedc 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -315,25 +315,6 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) "make program", cmCacheManager::FILEPATH); } - - if(makeProgram.find("xcodebuild") != makeProgram.npos) - { - // due to the text file busy /bin/sh problem with xcodebuild - // use the cmakexbuild wrapper instead. This program - // will run xcodebuild and if it sees the error text file busy - // it will stop forwarding output, and let the build finish. - // Then it will retry the build. It will continue this - // until no text file busy errors occur. - std::string cmakexbuild = - this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND"); - cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5); - cmakexbuild += "cmakexbuild"; - - mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", - cmakexbuild.c_str(), - "make program", - cmCacheManager::FILEPATH); - } } // enable the given language diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index ebad7da..cd0dcc6 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -136,7 +136,6 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version) sscanf(this->VersionString.c_str(), "%u.%u", &v[0], &v[1]); this->XcodeVersion = 10*v[0] + v[1]; - this->FindMakeProgramFile = "CMakeFindXCode.cmake"; this->RootObject = 0; this->MainGroupChildren = 0; this->SourcesGroupChildren = 0; @@ -203,6 +202,19 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory } //---------------------------------------------------------------------------- +void cmGlobalXCodeGenerator::FindMakeProgram(cmMakefile* mf) +{ + // The Xcode generator knows how to lookup its build tool + // directly instead of needing a helper module to do it, so we + // do not actually need to put CMAKE_MAKE_PROGRAM into the cache. + if(cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) + { + mf->AddDefinition("CMAKE_MAKE_PROGRAM", + this->GetXcodeBuildCommand().c_str()); + } +} + +//---------------------------------------------------------------------------- std::string const& cmGlobalXCodeGenerator::GetXcodeBuildCommand() { if(!this->XcodeBuildCommandInitialized) diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index e54bb37..f513e28 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -70,6 +70,8 @@ public: const std::string& suffix, std::string& dir); + virtual void FindMakeProgram(cmMakefile*); + ///! What is the configurations directory variable called? virtual const char* GetCMakeCFGIntDir() const; ///! expand CFGIntDir diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 3aecd9b..035f161 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -51,7 +51,7 @@ if(BUILD_TESTING) set(CMake_TEST_DEVENV "${CMAKE_MAKE_PROGRAM}") endif() - if(CMAKE_GENERATOR MATCHES "Visual Studio") + if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode") set(CMake_TEST_EXPLICIT_MAKE_PROGRAM "") else() set(CMake_TEST_EXPLICIT_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM}") -- cgit v0.12