summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClinton Stimpson <clinton@elemtech.com>2014-02-02 04:18:04 (GMT)
committerClinton Stimpson <clinton@elemtech.com>2014-02-03 14:04:54 (GMT)
commit028a5285d8ff5053fc96ea9840cb341bdf636e24 (patch)
treebdf44e70945eb207b0f61f38ace628029fed8f5b
parent6385c7151631a4ac72490540fe75cb0b9ebbedf5 (diff)
downloadCMake-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.cxx7
-rw-r--r--Source/cmGlobalGenerator.h4
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx17
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx40
-rw-r--r--Source/cmGlobalXCodeGenerator.h3
-rw-r--r--Source/cmInstallTargetGenerator.cxx30
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