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.
This commit is contained in:
parent
6385c71516
commit
028a5285d8
|
@ -3032,3 +3032,10 @@ void cmGlobalGenerator::ProcessEvaluationFiles()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmGlobalGenerator::ExpandCFGIntDir(const std::string& str,
|
||||
const std::string& /*config*/) const
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
std::string runpath = *i;
|
||||
runpath = this->ExpandCFGIntDir(runpath, configName);
|
||||
|
||||
if(unique_dirs.find(runpath) == unique_dirs.end())
|
||||
{
|
||||
unique_dirs.insert(runpath);
|
||||
if(!search_paths.empty())
|
||||
{
|
||||
search_paths += " ";
|
||||
}
|
||||
search_paths += this->XCodeEscapePath((*i).c_str());
|
||||
search_paths += this->XCodeEscapePath(runpath.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)
|
||||
{
|
||||
|
|
|
@ -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*);
|
||||
|
||||
|
|
|
@ -669,24 +669,38 @@ 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)
|
||||
{
|
||||
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 \"" << *i << "\"\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)
|
||||
{
|
||||
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 \"" << *i << "\"\n";
|
||||
os << indent << " -add_rpath \"" << runpath << "\"\n";
|
||||
os << indent << " \"" << toDestDirPath << "\")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct the original rpath string to be replaced.
|
||||
|
|
Loading…
Reference in New Issue