summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-03-01 17:51:07 (GMT)
committerBrad King <brad.king@kitware.com>2008-03-01 17:51:07 (GMT)
commit34c76d4304064d7d0e28ceaeee8ba4048497215a (patch)
tree1fe059dba6b66836c39b0e2b2c0d622a78b5c981 /Source/cmSystemTools.cxx
parent61178a0682a024e03e6fe41897b40bb096611f7a (diff)
downloadCMake-34c76d4304064d7d0e28ceaeee8ba4048497215a.zip
CMake-34c76d4304064d7d0e28ceaeee8ba4048497215a.tar.gz
CMake-34c76d4304064d7d0e28ceaeee8ba4048497215a.tar.bz2
ENH: Use builtin chrpath instead of relinking ELF targets
- Add cmSystemTools::ChangeRPath method - Add undocumented file(CHRPATH) command - When installing use file(CHRPATH) to change the rpath instead of relinking - Remove CMAKE_CHRPATH lookup from CMakeFindBinUtils - Remove CMAKE_USE_CHRPATH option since this should always work
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx83
1 files changed, 83 insertions, 0 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index aa4d1c2..1842317 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -2195,3 +2195,86 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
}
return false;
}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::ChangeRPath(std::string const& file,
+ std::string const& newRPath,
+ std::string* emsg)
+{
+#if defined(CMAKE_USE_ELF_PARSER)
+ unsigned long rpathPosition = 0;
+ unsigned long rpathSize = 0;
+ {
+ cmELF elf(file.c_str());
+ if(cmELF::StringEntry const* se = elf.GetRPath())
+ {
+ rpathPosition = se->Position;
+ rpathSize = se->Size;
+ }
+ else
+ {
+ if(emsg)
+ {
+ *emsg = "No valid ELF RPATH entry exists in the file.";
+ }
+ return false;
+ }
+ }
+ // Make sure there is enough room to store the new rpath and at
+ // least one null terminator.
+ if(rpathSize < newRPath.length()+1)
+ {
+ if(emsg)
+ {
+ *emsg = "The replacement RPATH is too long.";
+ }
+ return false;
+ }
+
+ // Open the file for update and seek to the RPATH position.
+ std::ofstream f(file.c_str(),
+ std::ios::in | std::ios::out | std::ios::binary);
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error opening file for update.";
+ }
+ return false;
+ }
+ if(!f.seekp(rpathPosition))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to RPATH position.";
+ }
+ return false;
+ }
+
+ // Write the new rpath. Follow it with enough null terminators to
+ // fill the string table entry.
+ f << newRPath;
+ for(unsigned long i=newRPath.length(); i < rpathSize; ++i)
+ {
+ f << '\0';
+ }
+
+ // Make sure everything was okay.
+ if(f)
+ {
+ return true;
+ }
+ else
+ {
+ if(emsg)
+ {
+ *emsg = "Error writing the new rpath to the file.";
+ }
+ return false;
+ }
+#else
+ (void)file;
+ (void)newRPath;
+ return false;
+#endif
+}