ENH: Update cmSystemTools::ChangeRPath to support replacing rpath values from the middle of the string.

This commit is contained in:
Brad King 2008-04-08 13:42:30 -04:00
parent fb62f79163
commit 871d80696b
1 changed files with 61 additions and 9 deletions

View File

@ -2198,6 +2198,52 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
return false;
}
//----------------------------------------------------------------------------
#if defined(CMAKE_USE_ELF_PARSER)
std::string::size_type cmSystemToolsFindRPath(std::string const& have,
std::string const& want)
{
// Search for the desired rpath.
std::string::size_type pos = have.find(want);
// If the path is not present we are done.
if(pos == std::string::npos)
{
return pos;
}
// Build a regex to match a properly separated path instance.
std::string regex_str = "(^|:)(";
for(std::string::const_iterator i = want.begin(); i != want.end(); ++i)
{
int ch = *i;
if(!(('a' <= ch && ch <= 'z') ||
('A' <= ch && ch <= 'Z') ||
('0' <= ch && ch <= '9')))
{
// Escape the non-alphanumeric character.
regex_str += "\\";
}
// Store the character.
regex_str.append(1, static_cast<char>(ch));
}
regex_str += ")(:|$)";
// Look for the separated path.
cmsys::RegularExpression regex(regex_str.c_str());
if(regex.find(have))
{
// Return the position of the path portion.
return regex.start(2);
}
else
{
// The desired rpath was not found.
return std::string::npos;
}
}
#endif
//----------------------------------------------------------------------------
bool cmSystemTools::ChangeRPath(std::string const& file,
std::string const& oldRPath,
@ -2207,23 +2253,27 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
#if defined(CMAKE_USE_ELF_PARSER)
unsigned long rpathPosition = 0;
unsigned long rpathSize = 0;
std::string rpathPrefix;
std::string rpathSuffix;
{
// Parse the ELF binary.
cmELF elf(file.c_str());
// Get the RPATH or RUNPATH entry from it.
cmELF::StringEntry const* se = elf.GetRPath();
if(!se)
{
se = elf.GetRunPath();
}
if(se)
{
// Make sure the current rpath begins with the old rpath.
if(se->Value.length() < oldRPath.length() ||
se->Value.substr(0, oldRPath.length()) != oldRPath)
// Make sure the current rpath contains the old rpath.
std::string::size_type pos = cmSystemToolsFindRPath(se->Value, oldRPath);
if(pos == std::string::npos)
{
// If it begins with the new rpath instead then it is okay.
if(se->Value.length() >= newRPath.length() &&
se->Value.substr(0, newRPath.length()) == newRPath)
// If it contains the new rpath instead then it is okay.
if(cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
{
return true;
}
@ -2232,7 +2282,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
cmOStringStream e;
e << "The current RPATH is:\n"
<< " " << se->Value << "\n"
<< "which does not begin with:\n"
<< "which does not contain:\n"
<< " " << oldRPath << "\n"
<< "as was expected.";
*emsg = e.str();
@ -2245,7 +2295,8 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
rpathSize = se->Size;
// Store the part of the path we must preserve.
rpathSuffix = se->Value.substr(oldRPath.length(), oldRPath.npos);
rpathPrefix = se->Value.substr(0, pos);
rpathSuffix = se->Value.substr(pos+oldRPath.length(), oldRPath.npos);
}
else if(newRPath.empty())
{
@ -2264,7 +2315,8 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
}
}
// Compute the full new rpath.
std::string rpath = newRPath;
std::string rpath = rpathPrefix;
rpath += newRPath;
rpath += rpathSuffix;
// Make sure there is enough room to store the new rpath and at