summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
authorLior Goldberg <liorgol.dev@gmail.com>2015-12-25 13:08:51 (GMT)
committerBrad King <brad.king@kitware.com>2016-01-15 19:53:24 (GMT)
commit3ec9226779776811240bde88a3f173c29aa935b5 (patch)
tree1458dd0e28c4da13fe58e03bfc65f717566e10b2 /Source/cmSystemTools.cxx
parentb8d002af1aeefb435a9560b056f081e5d8dff734 (diff)
downloadCMake-3ec9226779776811240bde88a3f173c29aa935b5.zip
CMake-3ec9226779776811240bde88a3f173c29aa935b5.tar.gz
CMake-3ec9226779776811240bde88a3f173c29aa935b5.tar.bz2
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.
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx27
1 files changed, 26 insertions, 1 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 008272c..a89a6e0b 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2565,6 +2565,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
*changed = false;
}
int rp_count = 0;
+ bool remove_rpath = true;
cmSystemToolsRPathInfo rp[2];
{
// 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(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
{
+ remove_rpath = false;
continue;
}
if(emsg)
@@ -2642,13 +2644,30 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
rp[rp_count].Size = se[i]->Size;
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
// 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 += se[i]->Value.substr(pos+oldRPath.length(),
oldRPath.npos);
+ if (!rp[rp_count].Value.empty())
+ {
+ remove_rpath = false;
+ }
+
// Make sure there is enough room to store the new rpath and at
// least one null terminator.
if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
@@ -2673,6 +2692,12 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
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.
cmsys::ofstream f(file.c_str(),