install: Do not remove compiler-defined RPATH entries
Some compilers may add their own RPATH entries when invoking the linker. For example, a GCC installation may contain the following definition in the specs file: *link_libgcc: %D -rpath <<some specific rpath in which libstdc++.so can be found>> In this case binaries may contain RPATH entries that CMake did not add. When we update the RPATH on installation we must preserve these entries even if CMake thinks the INSTALL_RPATH value should be empty. Fix this by always using file(RPATH_CHANGE) and teach it to behave as file(RPATH_REMOVE) if the actual RPATH in the file is empty after replacing the build-tree RPATH with the install-tree RPATH. This will preserve any compiler-added RPATH value instead of removing it.
This commit is contained in:
parent
b8d002af1a
commit
3ec9226779
|
@ -791,18 +791,10 @@ cmInstallTargetGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a rule to run chrpath to set the install-tree RPATH
|
// Write a rule to run chrpath to set the install-tree RPATH
|
||||||
if(newRpath.empty())
|
os << indent << "file(RPATH_CHANGE\n"
|
||||||
{
|
<< indent << " FILE \"" << toDestDirPath << "\"\n"
|
||||||
os << indent << "file(RPATH_REMOVE\n"
|
<< indent << " OLD_RPATH \"" << oldRpath << "\"\n"
|
||||||
<< indent << " FILE \"" << toDestDirPath << "\")\n";
|
<< indent << " NEW_RPATH \"" << newRpath << "\")\n";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
os << indent << "file(RPATH_CHANGE\n"
|
|
||||||
<< indent << " FILE \"" << toDestDirPath << "\"\n"
|
|
||||||
<< indent << " OLD_RPATH \"" << oldRpath << "\"\n"
|
|
||||||
<< indent << " NEW_RPATH \"" << newRpath << "\")\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2565,6 +2565,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||||
*changed = false;
|
*changed = false;
|
||||||
}
|
}
|
||||||
int rp_count = 0;
|
int rp_count = 0;
|
||||||
|
bool remove_rpath = true;
|
||||||
cmSystemToolsRPathInfo rp[2];
|
cmSystemToolsRPathInfo rp[2];
|
||||||
{
|
{
|
||||||
// Parse the ELF binary.
|
// Parse the ELF binary.
|
||||||
|
@ -2622,6 +2623,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||||
// If it contains the new rpath instead then it is okay.
|
// If it contains the new rpath instead then it is okay.
|
||||||
if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
|
if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
|
||||||
{
|
{
|
||||||
|
remove_rpath = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(emsg)
|
if(emsg)
|
||||||
|
@ -2642,13 +2644,30 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||||
rp[rp_count].Size = se[i]->Size;
|
rp[rp_count].Size = se[i]->Size;
|
||||||
rp[rp_count].Name = se_name[i];
|
rp[rp_count].Name = se_name[i];
|
||||||
|
|
||||||
|
std::string::size_type prefix_len = pos;
|
||||||
|
|
||||||
|
// If oldRPath was at the end of the file's RPath, and newRPath is empty,
|
||||||
|
// we should remove the unnecessary ':' at the end.
|
||||||
|
if (newRPath.empty() &&
|
||||||
|
pos > 0 &&
|
||||||
|
se[i]->Value[pos - 1] == ':' &&
|
||||||
|
pos + oldRPath.length() == se[i]->Value.length())
|
||||||
|
{
|
||||||
|
prefix_len--;
|
||||||
|
}
|
||||||
|
|
||||||
// Construct the new value which preserves the part of the path
|
// Construct the new value which preserves the part of the path
|
||||||
// not being changed.
|
// not being changed.
|
||||||
rp[rp_count].Value = se[i]->Value.substr(0, pos);
|
rp[rp_count].Value = se[i]->Value.substr(0, prefix_len);
|
||||||
rp[rp_count].Value += newRPath;
|
rp[rp_count].Value += newRPath;
|
||||||
rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
|
rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
|
||||||
oldRPath.npos);
|
oldRPath.npos);
|
||||||
|
|
||||||
|
if (!rp[rp_count].Value.empty())
|
||||||
|
{
|
||||||
|
remove_rpath = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure there is enough room to store the new rpath and at
|
// Make sure there is enough room to store the new rpath and at
|
||||||
// least one null terminator.
|
// least one null terminator.
|
||||||
if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
|
if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
|
||||||
|
@ -2673,6 +2692,12 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the resulting rpath is empty, just remove the entire entry instead.
|
||||||
|
if (remove_rpath)
|
||||||
|
{
|
||||||
|
return cmSystemTools::RemoveRPath(file, emsg, changed);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Open the file for update.
|
// Open the file for update.
|
||||||
cmsys::ofstream f(file.c_str(),
|
cmsys::ofstream f(file.c_str(),
|
||||||
|
|
Loading…
Reference in New Issue