diff options
author | Brad King <brad.king@kitware.com> | 2008-03-01 17:51:07 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2008-03-01 17:51:07 (GMT) |
commit | 34c76d4304064d7d0e28ceaeee8ba4048497215a (patch) | |
tree | 1fe059dba6b66836c39b0e2b2c0d622a78b5c981 /Source | |
parent | 61178a0682a024e03e6fe41897b40bb096611f7a (diff) | |
download | CMake-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')
-rw-r--r-- | Source/cmComputeLinkInformation.cxx | 6 | ||||
-rw-r--r-- | Source/cmComputeLinkInformation.h | 1 | ||||
-rw-r--r-- | Source/cmFileCommand.cxx | 32 | ||||
-rw-r--r-- | Source/cmFileCommand.h | 1 | ||||
-rw-r--r-- | Source/cmInstallTargetGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 83 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 5 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 14 | ||||
-rw-r--r-- | Source/cmTarget.h | 2 |
9 files changed, 133 insertions, 18 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index cd671d9..554d8de 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1476,9 +1476,3 @@ std::string cmComputeLinkInformation::GetChrpathString() return this->GetRPathString(true); } - -//---------------------------------------------------------------------------- -std::string cmComputeLinkInformation::GetChrpathTool() -{ - return this->Makefile->GetSafeDefinition("CMAKE_CHRPATH"); -} diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index c0f8b5c..df22d53 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -58,7 +58,6 @@ public: void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install); std::string GetRPathString(bool for_install); std::string GetChrpathString(); - std::string GetChrpathTool(); std::set<cmTarget*> const& GetSharedLibrariesLinked(); std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index ec61a59..0128135 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -112,6 +112,10 @@ bool cmFileCommand { return this->HandleInstallCommand(args); } + else if ( subCommand == "CHRPATH" ) + { + return this->HandleChrpathCommand(args); + } else if ( subCommand == "RELATIVE_PATH" ) { return this->HandleRelativePathCommand(args); @@ -1327,6 +1331,34 @@ bool cmFileCommand::HandleInstallDestination(cmFileInstaller& installer, } //---------------------------------------------------------------------------- +bool cmFileCommand::HandleChrpathCommand(std::vector<std::string> const& args) +{ + if(args.size() != 3) + { + this->SetError("CHRPATH must be given a file and a new rpath."); + return false; + } + if(!cmSystemTools::FileExists(args[1].c_str(), true)) + { + this->SetError("CHRPATH given file that does not exist."); + return false; + } + std::string emsg; + if(cmSystemTools::ChangeRPath(args[1], args[2], &emsg)) + { + return true; + } + else + { + cmOStringStream e; + e << "CHRPATH could not write new RPATH to the file: " + << emsg; + this->SetError(e.str().c_str()); + return false; + } +} + +//---------------------------------------------------------------------------- bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args) { if ( args.size() < 6 ) diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 18f4c8f..85bdc32 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -171,6 +171,7 @@ protected: bool HandleRelativePathCommand(std::vector<std::string> const& args); bool HandleCMakePathCommand(std::vector<std::string> const& args, bool nativePath); + bool HandleChrpathCommand(std::vector<std::string> const& args); // file(INSTALL ...) related functions bool HandleInstallCommand(std::vector<std::string> const& args); diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index c8e00d5..c2d606e 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -576,12 +576,9 @@ cmInstallTargetGenerator // Get the install RPATH from the link information. std::string newRpath = cli->GetChrpathString(); - // Fix the RPATH in installed ELF binaries using chrpath. - std::string chrpathTool = cli->GetChrpathTool(); - // Write a rule to run chrpath to set the install-tree RPATH - os << indent << "EXECUTE_PROCESS(COMMAND \"" << chrpathTool; - os << "\" -r \"" << newRpath << "\" \"" << toDestDirPath << "\")\n"; + os << indent + << "FILE(CHRPATH \"" << toDestDirPath << "\" \"" << newRpath << "\")\n"; } //---------------------------------------------------------------------------- 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 +} diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index e03c24c..42282d3 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -381,6 +381,11 @@ public: static bool GuessLibrarySOName(std::string const& fullPath, std::string& soname); + /** Try to set the RPATH in an ELF binary. */ + static bool ChangeRPath(std::string const& file, + std::string const& newRPath, + std::string* emsg = 0); + private: static bool s_ForceUnixPaths; static bool s_RunCommandHideConsole; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index b4c36c6..880c370 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -3006,8 +3006,9 @@ void cmTarget::GetLanguages(std::set<cmStdString>& languages) const //---------------------------------------------------------------------------- bool cmTarget::IsChrpathUsed() { - // Enable use of "chrpath" if it is available, the user has turned - // on the feature, and the rpath flag uses a separator. +#if defined(CMAKE_USE_ELF_PARSER) + // Enable if the rpath flag uses a separator and the target uses ELF + // binaries. if(const char* ll = this->GetLinkerLanguage( this->Makefile->GetLocalGenerator()->GetGlobalGenerator())) { @@ -3017,13 +3018,16 @@ bool cmTarget::IsChrpathUsed() const char* sep = this->Makefile->GetDefinition(sepVar.c_str()); if(sep && *sep) { - if(this->Makefile->IsSet("CMAKE_CHRPATH") && - this->Makefile->IsOn("CMAKE_USE_CHRPATH")) + // TODO: Add ELF check to ABI detection and get rid of + // CMAKE_EXECUTABLE_FORMAT. + if(const char* fmt = + this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT")) { - return true; + return strcmp(fmt, "ELF") == 0; } } } +#endif return false; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 95c49da..1b430e6 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -335,7 +335,7 @@ public: bool HaveBuildTreeRPATH(); bool HaveInstallTreeRPATH(); - /** Return true if chrpath might work for this target */ + /** Return true if builtin chrpath will work for this target */ bool IsChrpathUsed(); std::string GetInstallNameDirForBuildTree(const char* config); |