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?
|
///! What is the configurations directory variable called?
|
||||||
virtual const char* GetCMakeCFGIntDir() const { return "."; }
|
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. */
|
/** Get whether the generator should use a script for link commands. */
|
||||||
bool GetUseLinkScript() const { return this->UseLinkScript; }
|
bool GetUseLinkScript() const { return this->UseLinkScript; }
|
||||||
|
|
||||||
|
|
|
@ -902,3 +902,20 @@ cmGlobalVisualStudioGenerator::OrderedTargetDependSet
|
||||||
this->insert(*ti);
|
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 void FindMakeProgram(cmMakefile*);
|
||||||
|
|
||||||
|
|
||||||
|
virtual std::string ExpandCFGIntDir(const std::string& str,
|
||||||
|
const std::string& config) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Does this VS version link targets to each other if there are
|
// Does this VS version link targets to each other if there are
|
||||||
// dependencies in the SLN file? This was done for VS versions
|
// 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::string search_paths;
|
||||||
std::vector<std::string> runtimeDirs;
|
std::vector<std::string> runtimeDirs;
|
||||||
pcli->GetRPath(runtimeDirs, false);
|
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();
|
for(std::vector<std::string>::const_iterator i = runtimeDirs.begin();
|
||||||
i != runtimeDirs.end(); ++i)
|
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())
|
if(!search_paths.empty())
|
||||||
{
|
{
|
||||||
search_paths += " ";
|
search_paths += " ";
|
||||||
}
|
}
|
||||||
search_paths += this->XCodeEscapePath((*i).c_str());
|
search_paths += this->XCodeEscapePath(runpath.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!search_paths.empty())
|
if(!search_paths.empty())
|
||||||
{
|
{
|
||||||
|
@ -3675,6 +3685,30 @@ const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
|
||||||
"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : ".";
|
"$(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)
|
void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,9 @@ public:
|
||||||
|
|
||||||
///! What is the configurations directory variable called?
|
///! What is the configurations directory variable called?
|
||||||
virtual const char* GetCMakeCFGIntDir() const;
|
virtual const char* GetCMakeCFGIntDir() const;
|
||||||
|
///! expand CFGIntDir
|
||||||
|
virtual std::string ExpandCFGIntDir(const std::string& str,
|
||||||
|
const std::string& config) const;
|
||||||
|
|
||||||
void SetCurrentLocalGenerator(cmLocalGenerator*);
|
void SetCurrentLocalGenerator(cmLocalGenerator*);
|
||||||
|
|
||||||
|
|
|
@ -669,24 +669,38 @@ cmInstallTargetGenerator
|
||||||
cli->GetRPath(oldRuntimeDirs, false);
|
cli->GetRPath(oldRuntimeDirs, false);
|
||||||
cli->GetRPath(newRuntimeDirs, true);
|
cli->GetRPath(newRuntimeDirs, true);
|
||||||
|
|
||||||
// Note: These are separate commands to avoid install_name_tool
|
// Note: These paths are kept unique to avoid install_name_tool corruption.
|
||||||
// corruption on 10.6.
|
std::set<std::string> runpaths;
|
||||||
for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
|
for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
|
||||||
i != oldRuntimeDirs.end(); ++i)
|
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 << "execute_process(COMMAND " << installNameTool << "\n";
|
||||||
os << indent << " -delete_rpath \"" << *i << "\"\n";
|
os << indent << " -delete_rpath \"" << runpath << "\"\n";
|
||||||
os << indent << " \"" << toDestDirPath << "\")\n";
|
os << indent << " \"" << toDestDirPath << "\")\n";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runpaths.clear();
|
||||||
for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
|
for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
|
||||||
i != newRuntimeDirs.end(); ++i)
|
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 << "execute_process(COMMAND " << installNameTool << "\n";
|
||||||
os << indent << " -add_rpath \"" << *i << "\"\n";
|
os << indent << " -add_rpath \"" << runpath << "\"\n";
|
||||||
os << indent << " \"" << toDestDirPath << "\")\n";
|
os << indent << " \"" << toDestDirPath << "\")\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Construct the original rpath string to be replaced.
|
// Construct the original rpath string to be replaced.
|
||||||
|
|
Loading…
Reference in New Issue