From 50e261ddb680f46e7011fe5173dc59d64b12c882 Mon Sep 17 00:00:00 2001 From: Clinton Stimpson Date: Mon, 6 Oct 2014 22:24:10 -0600 Subject: [PATCH] OSX: Warn when attempting to change runtime paths on OS X 10.5 Even though 10.5 supports @rpath, the support is not complete enough for CMake. For instance, install_name_tool doesn't support adding and removing rpaths. Also modifying BundleUtilities test to remove an undesirable cmake generated runtime path. The intent was to build with the install rpath as is done with the other cases in this test. --- Source/cmInstallTargetGenerator.cxx | 82 ++++++++++++++++++---------- Tests/BundleUtilities/CMakeLists.txt | 3 +- 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 8a1c53e27..d689c89ae 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -677,46 +677,72 @@ cmInstallTargetGenerator return; } - if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + cmMakefile* mf = this->Target->GetMakefile(); + + if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { // If using install_name_tool, set up the rules to modify the rpaths. std::string installNameTool = - this->Target->GetMakefile()-> - GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL"); + mf->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL"); std::vector oldRuntimeDirs, newRuntimeDirs; cli->GetRPath(oldRuntimeDirs, false); cli->GetRPath(newRuntimeDirs, true); - // Note: These paths are kept unique to avoid install_name_tool corruption. - std::set runpaths; - for(std::vector::const_iterator i = oldRuntimeDirs.begin(); - i != oldRuntimeDirs.end(); ++i) - { - std::string runpath = this->Target->GetMakefile()->GetLocalGenerator()-> - GetGlobalGenerator()->ExpandCFGIntDir(*i, config); + std::string darwin_major_version_s = + mf->GetSafeDefinition("DARWIN_MAJOR_VERSION"); - if(runpaths.find(runpath) == runpaths.end()) - { - runpaths.insert(runpath); - os << indent << "execute_process(COMMAND " << installNameTool << "\n"; - os << indent << " -delete_rpath \"" << runpath << "\"\n"; - os << indent << " \"" << toDestDirPath << "\")\n"; - } + std::stringstream ss(darwin_major_version_s); + int darwin_major_version; + ss >> darwin_major_version; + if(!ss.fail() && darwin_major_version <= 9 && + (!oldRuntimeDirs.empty() || !newRuntimeDirs.empty()) + ) + { + cmOStringStream msg; + msg << "WARNING: Target \"" << this->Target->GetName() + << "\" has runtime paths which cannot be changed during install. " + << "To change runtime paths, OS X version 10.6 or newer is required. " + << "Therefore, runtime paths will not be changed when installing. " + << "CMAKE_BUILD_WITH_INSTALL_RPATH may be used to work around" + " this limitation."; + mf->IssueMessage(cmake::WARNING, msg.str()); } - - runpaths.clear(); - for(std::vector::const_iterator i = newRuntimeDirs.begin(); - i != newRuntimeDirs.end(); ++i) + else { - std::string runpath = this->Target->GetMakefile()->GetLocalGenerator()-> - GetGlobalGenerator()->ExpandCFGIntDir(*i, config); - - if(runpaths.find(runpath) == runpaths.end()) + // Note: These paths are kept unique to avoid + // install_name_tool corruption. + std::set runpaths; + for(std::vector::const_iterator i = oldRuntimeDirs.begin(); + i != oldRuntimeDirs.end(); ++i) { - os << indent << "execute_process(COMMAND " << installNameTool << "\n"; - os << indent << " -add_rpath \"" << runpath << "\"\n"; - os << indent << " \"" << toDestDirPath << "\")\n"; + std::string runpath = + mf->GetLocalGenerator()-> + GetGlobalGenerator()->ExpandCFGIntDir(*i, config); + + if(runpaths.find(runpath) == runpaths.end()) + { + runpaths.insert(runpath); + os << indent << "execute_process(COMMAND " << installNameTool <<"\n"; + os << indent << " -delete_rpath \"" << runpath << "\"\n"; + os << indent << " \"" << toDestDirPath << "\")\n"; + } + } + + runpaths.clear(); + for(std::vector::const_iterator i = newRuntimeDirs.begin(); + i != newRuntimeDirs.end(); ++i) + { + std::string runpath = + mf->GetLocalGenerator()-> + GetGlobalGenerator()->ExpandCFGIntDir(*i, config); + + if(runpaths.find(runpath) == runpaths.end()) + { + os << indent << "execute_process(COMMAND " << installNameTool <<"\n"; + os << indent << " -add_rpath \"" << runpath << "\"\n"; + os << indent << " \"" << toDestDirPath << "\")\n"; + } } } } diff --git a/Tests/BundleUtilities/CMakeLists.txt b/Tests/BundleUtilities/CMakeLists.txt index 3a1cf552d..69ef53505 100644 --- a/Tests/BundleUtilities/CMakeLists.txt +++ b/Tests/BundleUtilities/CMakeLists.txt @@ -109,7 +109,8 @@ if(APPLE AND NOT CMAKE_SYSTEM_VERSION VERSION_LESS 9.0) target_link_libraries(testbundleutils3 shared-3 framework-3 ${CMAKE_DL_LIBS}) set_target_properties(testbundleutils3 module3 PROPERTIES - LINK_FLAGS "-Wl,-rpath,@loader_path/") + LINK_FLAGS "-Wl,-rpath,@loader_path/" + BUILD_WITH_INSTALL_RPATH 1) # add custom target to install and test the app add_custom_target(testbundleutils3_test ALL