diff options
author | Clinton Stimpson <clinton@elemtech.com> | 2014-02-02 04:18:04 (GMT) |
---|---|---|
committer | Clinton Stimpson <clinton@elemtech.com> | 2014-02-03 14:04:54 (GMT) |
commit | 028a5285d8ff5053fc96ea9840cb341bdf636e24 (patch) | |
tree | bdf44e70945eb207b0f61f38ace628029fed8f5b | |
parent | 6385c7151631a4ac72490540fe75cb0b9ebbedf5 (diff) | |
download | CMake-028a5285d8ff5053fc96ea9840cb341bdf636e24.zip CMake-028a5285d8ff5053fc96ea9840cb341bdf636e24.tar.gz CMake-028a5285d8ff5053fc96ea9840cb341bdf636e24.tar.bz2 |
OS X: Make sure RPATHs are unique to avoid possible corruption.
When using link_directories() and including CMAKE_CFG_INTDIR,
one can end up with duplicate RPATHs in the binary which
install_name_tool cannot fix without corrupting the binary.
Also, the cmake_install.cmake file has been fixed to correctly
handle these generator specific variables.
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioGenerator.cxx | 17 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 40 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 3 | ||||
-rw-r--r-- | Source/cmInstallTargetGenerator.cxx | 30 |
7 files changed, 94 insertions, 11 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 03486d8..a61cab1 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -3032,3 +3032,10 @@ void cmGlobalGenerator::ProcessEvaluationFiles() } } } + +//---------------------------------------------------------------------------- +std::string cmGlobalGenerator::ExpandCFGIntDir(const std::string& str, + const std::string& /*config*/) const +{ + return str; +} diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index ebc2db5..753eebf 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -193,6 +193,10 @@ public: ///! What is the configurations directory variable called? virtual const char* GetCMakeCFGIntDir() const { return "."; } + ///! expand CFGIntDir for a configuration + virtual std::string ExpandCFGIntDir(const std::string& str, + const std::string& config) const; + /** Get whether the generator should use a script for link commands. */ bool GetUseLinkScript() const { return this->UseLinkScript; } diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 42492e6..0c5f35b 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -902,3 +902,20 @@ cmGlobalVisualStudioGenerator::OrderedTargetDependSet this->insert(*ti); } } + +std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir( + const std::string& str, + const std::string& config) const +{ + std::string replace = GetCMakeCFGIntDir(); + + std::string tmp = str; + for(std::string::size_type i = tmp.find(replace); + i != std::string::npos; + i = tmp.find(replace, i)) + { + tmp.replace(i, replace.size(), config); + i += config.size(); + } + return tmp; +} diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index eab613d..9186d65 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -84,6 +84,10 @@ public: virtual void FindMakeProgram(cmMakefile*); + + virtual std::string ExpandCFGIntDir(const std::string& str, + const std::string& config) const; + protected: // Does this VS version link targets to each other if there are // dependencies in the SLN file? This was done for VS versions diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 46c34d0..484b28f 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2272,14 +2272,24 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, std::string search_paths; std::vector<std::string> runtimeDirs; pcli->GetRPath(runtimeDirs, false); + // runpath dirs needs to be unique to prevent corruption + std::set<std::string> unique_dirs; + for(std::vector<std::string>::const_iterator i = runtimeDirs.begin(); i != runtimeDirs.end(); ++i) { - if(!search_paths.empty()) + std::string runpath = *i; + runpath = this->ExpandCFGIntDir(runpath, configName); + + if(unique_dirs.find(runpath) == unique_dirs.end()) { - search_paths += " "; + unique_dirs.insert(runpath); + if(!search_paths.empty()) + { + search_paths += " "; + } + search_paths += this->XCodeEscapePath(runpath.c_str()); } - search_paths += this->XCodeEscapePath((*i).c_str()); } if(!search_paths.empty()) { @@ -3675,6 +3685,30 @@ const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : "."; } +std::string cmGlobalXCodeGenerator::ExpandCFGIntDir(const std::string& str, + const std::string& config) const +{ + std::string replace1 = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + std::string replace2 = "$(CONFIGURATION)"; + + std::string tmp = str; + for(std::string::size_type i = tmp.find(replace1); + i != std::string::npos; + i = tmp.find(replace1, i)) + { + tmp.replace(i, replace1.size(), config); + i += config.size(); + } + for(std::string::size_type i = tmp.find(replace2); + i != std::string::npos; + i = tmp.find(replace2, i)) + { + tmp.replace(i, replace2.size(), config); + i += config.size(); + } + return tmp; +} + //---------------------------------------------------------------------------- void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry) { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index ae7f07e..c9d20c2 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -79,6 +79,9 @@ public: ///! What is the configurations directory variable called? virtual const char* GetCMakeCFGIntDir() const; + ///! expand CFGIntDir + virtual std::string ExpandCFGIntDir(const std::string& str, + const std::string& config) const; void SetCurrentLocalGenerator(cmLocalGenerator*); diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 68f45a6..7a39f45 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -669,22 +669,36 @@ cmInstallTargetGenerator cli->GetRPath(oldRuntimeDirs, false); cli->GetRPath(newRuntimeDirs, true); - // Note: These are separate commands to avoid install_name_tool - // corruption on 10.6. + // Note: These paths are kept unique to avoid install_name_tool corruption. + std::set<std::string> runpaths; for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin(); i != oldRuntimeDirs.end(); ++i) { - os << indent << "execute_process(COMMAND " << installNameTool << "\n"; - os << indent << " -delete_rpath \"" << *i << "\"\n"; - os << indent << " \"" << toDestDirPath << "\")\n"; + std::string runpath = this->Target->GetMakefile()->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<std::string>::const_iterator i = newRuntimeDirs.begin(); i != newRuntimeDirs.end(); ++i) { - os << indent << "execute_process(COMMAND " << installNameTool << "\n"; - os << indent << " -add_rpath \"" << *i << "\"\n"; - os << indent << " \"" << toDestDirPath << "\")\n"; + std::string runpath = this->Target->GetMakefile()->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"; + } } } else |