mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
Merge topic 'cmsystemtools-multiple-formats'
2e1149874d
cmSystemTools: Support multiple binary formats
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !6239
This commit is contained in:
@@ -48,6 +48,8 @@
|
||||
|
||||
#if defined(CMake_USE_ELF_PARSER)
|
||||
# include "cmELF.h"
|
||||
#else
|
||||
class cmELF;
|
||||
#endif
|
||||
|
||||
#if defined(CMake_USE_MACH_PARSER)
|
||||
@@ -2491,7 +2493,6 @@ bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath,
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(CMake_USE_ELF_PARSER) || defined(CMake_USE_XCOFF_PARSER)
|
||||
std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have,
|
||||
cm::string_view const& want)
|
||||
{
|
||||
@@ -2523,9 +2524,7 @@ std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have,
|
||||
// The desired rpath was not found.
|
||||
return std::string::npos;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CMake_USE_ELF_PARSER)
|
||||
namespace {
|
||||
struct cmSystemToolsRPathInfo
|
||||
{
|
||||
@@ -2539,11 +2538,19 @@ using EmptyCallback = std::function<bool(std::string*, const cmELF&)>;
|
||||
using AdjustCallback = std::function<bool(
|
||||
cm::optional<std::string>&, const std::string&, const char*, std::string*)>;
|
||||
|
||||
// FIXME: Dispatch if multiple formats are supported.
|
||||
bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
|
||||
const AdjustCallback& adjustCallback, std::string* emsg,
|
||||
bool* changed)
|
||||
cm::optional<bool> AdjustRPathELF(std::string const& file,
|
||||
const EmptyCallback& emptyCallback,
|
||||
const AdjustCallback& adjustCallback,
|
||||
std::string* emsg, bool* changed)
|
||||
{
|
||||
#if !defined(CMake_USE_ELF_PARSER)
|
||||
(void)file;
|
||||
(void)emptyCallback;
|
||||
(void)adjustCallback;
|
||||
(void)emsg;
|
||||
(void)changed;
|
||||
return cm::nullopt; // Cannot handle ELF files.
|
||||
#else
|
||||
if (changed) {
|
||||
*changed = false;
|
||||
}
|
||||
@@ -2553,6 +2560,9 @@ bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
|
||||
{
|
||||
// Parse the ELF binary.
|
||||
cmELF elf(file.c_str());
|
||||
if (!elf) {
|
||||
return cm::nullopt; // Not a valid ELF file.
|
||||
}
|
||||
|
||||
// Get the RPATH and RUNPATH entries from it.
|
||||
int se_count = 0;
|
||||
@@ -2668,6 +2678,7 @@ bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
|
||||
*changed = true;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback(
|
||||
@@ -2679,21 +2690,26 @@ std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback(
|
||||
// okay.
|
||||
return true;
|
||||
}
|
||||
#if defined(CMake_USE_ELF_PARSER)
|
||||
if (emsg) {
|
||||
*emsg =
|
||||
cmStrCat("No valid ELF RPATH or RUNPATH entry exists in the file; ",
|
||||
elf.GetErrorMessage());
|
||||
}
|
||||
#else
|
||||
static_cast<void>(emsg);
|
||||
static_cast<void>(elf);
|
||||
#endif
|
||||
return false;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||
std::string const& oldRPath,
|
||||
std::string const& newRPath,
|
||||
bool removeEnvironmentRPath, std::string* emsg,
|
||||
bool* changed)
|
||||
cm::optional<bool> ChangeRPathELF(std::string const& file,
|
||||
std::string const& oldRPath,
|
||||
std::string const& newRPath,
|
||||
bool removeEnvironmentRPath,
|
||||
std::string* emsg, bool* changed)
|
||||
{
|
||||
auto adjustCallback = [oldRPath, newRPath, removeEnvironmentRPath](
|
||||
cm::optional<std::string>& outRPath,
|
||||
@@ -2741,13 +2757,13 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||
return true;
|
||||
};
|
||||
|
||||
return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg,
|
||||
changed);
|
||||
return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
|
||||
emsg, changed);
|
||||
}
|
||||
|
||||
bool cmSystemTools::SetRPath(std::string const& file,
|
||||
std::string const& newRPath, std::string* emsg,
|
||||
bool* changed)
|
||||
static cm::optional<bool> SetRPathELF(std::string const& file,
|
||||
std::string const& newRPath,
|
||||
std::string* emsg, bool* changed)
|
||||
{
|
||||
auto adjustCallback = [newRPath](cm::optional<std::string>& outRPath,
|
||||
const std::string& inRPath,
|
||||
@@ -2759,22 +2775,31 @@ bool cmSystemTools::SetRPath(std::string const& file,
|
||||
return true;
|
||||
};
|
||||
|
||||
return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg,
|
||||
changed);
|
||||
return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
|
||||
emsg, changed);
|
||||
}
|
||||
#elif defined(CMake_USE_XCOFF_PARSER)
|
||||
bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||
std::string const& oldRPath,
|
||||
std::string const& newRPath,
|
||||
bool removeEnvironmentRPath, std::string* emsg,
|
||||
bool* changed)
|
||||
static cm::optional<bool> ChangeRPathXCOFF(std::string const& file,
|
||||
std::string const& oldRPath,
|
||||
std::string const& newRPath,
|
||||
bool removeEnvironmentRPath,
|
||||
std::string* emsg, bool* changed)
|
||||
{
|
||||
if (changed) {
|
||||
*changed = false;
|
||||
}
|
||||
|
||||
#if !defined(CMake_USE_XCOFF_PARSER)
|
||||
(void)file;
|
||||
(void)oldRPath;
|
||||
(void)newRPath;
|
||||
(void)removeEnvironmentRPath;
|
||||
(void)emsg;
|
||||
return cm::nullopt;
|
||||
#else
|
||||
bool chg = false;
|
||||
cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
|
||||
if (!xcoff) {
|
||||
return cm::nullopt; // Not a valid XCOFF file
|
||||
}
|
||||
if (cm::optional<cm::string_view> maybeLibPath = xcoff.GetLibPath()) {
|
||||
cm::string_view libPath = *maybeLibPath;
|
||||
// Make sure the current rpath contains the old rpath.
|
||||
@@ -2830,31 +2855,47 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||
*changed = chg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmSystemTools::SetRPath(std::string const& /*file*/,
|
||||
std::string const& /*newRPath*/,
|
||||
std::string* /*emsg*/, bool* /*changed*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
bool cmSystemTools::ChangeRPath(std::string const& /*file*/,
|
||||
std::string const& /*oldRPath*/,
|
||||
std::string const& /*newRPath*/,
|
||||
bool /*removeEnvironmentRPath*/,
|
||||
std::string* /*emsg*/, bool* /*changed*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmSystemTools::SetRPath(std::string const& /*file*/,
|
||||
std::string const& /*newRPath*/,
|
||||
std::string* /*emsg*/, bool* /*changed*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static cm::optional<bool> SetRPathXCOFF(std::string const& /*file*/,
|
||||
std::string const& /*newRPath*/,
|
||||
std::string* /*emsg*/,
|
||||
bool* /*changed*/)
|
||||
{
|
||||
return cm::nullopt; // Not implemented.
|
||||
}
|
||||
|
||||
bool cmSystemTools::ChangeRPath(std::string const& file,
|
||||
std::string const& oldRPath,
|
||||
std::string const& newRPath,
|
||||
bool removeEnvironmentRPath, std::string* emsg,
|
||||
bool* changed)
|
||||
{
|
||||
if (cm::optional<bool> result = ChangeRPathELF(
|
||||
file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
|
||||
return result.value();
|
||||
}
|
||||
if (cm::optional<bool> result = ChangeRPathXCOFF(
|
||||
file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
|
||||
return result.value();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmSystemTools::SetRPath(std::string const& file,
|
||||
std::string const& newRPath, std::string* emsg,
|
||||
bool* changed)
|
||||
{
|
||||
if (cm::optional<bool> result = SetRPathELF(file, newRPath, emsg, changed)) {
|
||||
return result.value();
|
||||
}
|
||||
if (cm::optional<bool> result =
|
||||
SetRPathXCOFF(file, newRPath, emsg, changed)) {
|
||||
return result.value();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
|
||||
const char* lhss, const char* rhss)
|
||||
@@ -2989,11 +3030,15 @@ int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs)
|
||||
return cm_strverscmp(lhs.c_str(), rhs.c_str());
|
||||
}
|
||||
|
||||
// FIXME: Dispatch if multiple formats are supported.
|
||||
#if defined(CMake_USE_ELF_PARSER)
|
||||
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
|
||||
bool* removed)
|
||||
static cm::optional<bool> RemoveRPathELF(std::string const& file,
|
||||
std::string* emsg, bool* removed)
|
||||
{
|
||||
#if !defined(CMake_USE_ELF_PARSER)
|
||||
(void)file;
|
||||
(void)emsg;
|
||||
(void)removed;
|
||||
return cm::nullopt; // Cannot handle ELF files.
|
||||
#else
|
||||
if (removed) {
|
||||
*removed = false;
|
||||
}
|
||||
@@ -3005,6 +3050,9 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
|
||||
{
|
||||
// Parse the ELF binary.
|
||||
cmELF elf(file.c_str());
|
||||
if (!elf) {
|
||||
return cm::nullopt; // Not a valid ELF file.
|
||||
}
|
||||
|
||||
// Get the RPATH and RUNPATH entries from it and sort them by index
|
||||
// in the dynamic section header.
|
||||
@@ -3130,16 +3178,24 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
|
||||
*removed = true;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#elif defined(CMake_USE_XCOFF_PARSER)
|
||||
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
|
||||
bool* removed)
|
||||
|
||||
static cm::optional<bool> RemoveRPathXCOFF(std::string const& file,
|
||||
std::string* emsg, bool* removed)
|
||||
{
|
||||
if (removed) {
|
||||
*removed = false;
|
||||
}
|
||||
|
||||
#if !defined(CMake_USE_XCOFF_PARSER)
|
||||
(void)file;
|
||||
(void)emsg;
|
||||
return cm::nullopt; // Cannot handle XCOFF files.
|
||||
#else
|
||||
cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
|
||||
if (!xcoff) {
|
||||
return cm::nullopt; // Not a valid XCOFF file.
|
||||
}
|
||||
bool rm = xcoff.RemoveLibPath();
|
||||
if (!xcoff) {
|
||||
if (emsg) {
|
||||
@@ -3152,55 +3208,62 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
|
||||
*removed = rm;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
bool cmSystemTools::RemoveRPath(std::string const& /*file*/,
|
||||
std::string* /*emsg*/, bool* /*removed*/)
|
||||
bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
|
||||
bool* removed)
|
||||
{
|
||||
if (cm::optional<bool> result = RemoveRPathELF(file, emsg, removed)) {
|
||||
return result.value();
|
||||
}
|
||||
if (cm::optional<bool> result = RemoveRPathXCOFF(file, emsg, removed)) {
|
||||
return result.value();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// FIXME: Dispatch if multiple formats are supported.
|
||||
bool cmSystemTools::CheckRPath(std::string const& file,
|
||||
std::string const& newRPath)
|
||||
{
|
||||
#if defined(CMake_USE_ELF_PARSER)
|
||||
// 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();
|
||||
}
|
||||
|
||||
// Make sure the current rpath contains the new rpath.
|
||||
if (newRPath.empty()) {
|
||||
if (elf) {
|
||||
// Get the RPATH or RUNPATH entry from it.
|
||||
cmELF::StringEntry const* se = elf.GetRPath();
|
||||
if (!se) {
|
||||
return true;
|
||||
se = elf.GetRunPath();
|
||||
}
|
||||
} else {
|
||||
if (se &&
|
||||
cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) {
|
||||
return true;
|
||||
|
||||
// Make sure the current rpath contains the new rpath.
|
||||
if (newRPath.empty()) {
|
||||
if (!se) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (se &&
|
||||
cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
#elif defined(CMake_USE_XCOFF_PARSER)
|
||||
#endif
|
||||
#if defined(CMake_USE_XCOFF_PARSER)
|
||||
// Parse the XCOFF binary.
|
||||
cmXCOFF xcoff(file.c_str());
|
||||
if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) {
|
||||
if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) {
|
||||
return true;
|
||||
if (xcoff) {
|
||||
if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) {
|
||||
if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
#endif
|
||||
(void)file;
|
||||
(void)newRPath;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir)
|
||||
|
Reference in New Issue
Block a user