diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 03486d821..a61cab11d 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 ebc2db54d..753eebfea 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 42492e6cf..0c5f35b61 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 eab613d30..9186d6594 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 46c34d05b..484b28fe8 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2272,14 +2272,24 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, std::string search_paths; std::vector runtimeDirs; pcli->GetRPath(runtimeDirs, false); + // runpath dirs needs to be unique to prevent corruption + std::set unique_dirs; + for(std::vector::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 ae7f07e2d..c9d20c2e3 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 68f45a62f..7a39f457d 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 runpaths; for(std::vector::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::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