mirror of
https://github.com/Kitware/CMake.git
synced 2026-03-01 12:18:36 -06:00
file(GET_RUNTIME_DEPENDENCIES): Check architecture of dependencies
Fixes: #22106
This commit is contained in:
@@ -18,6 +18,10 @@
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
#ifdef CMake_USE_ELF_PARSER
|
||||
# include "cmELF.h"
|
||||
#endif
|
||||
|
||||
static std::string ReplaceOrigin(const std::string& rpath,
|
||||
const std::string& origin)
|
||||
{
|
||||
@@ -86,6 +90,24 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies(
|
||||
std::string const& file, cmStateEnums::TargetType /* unused */)
|
||||
{
|
||||
std::vector<std::string> parentRpaths;
|
||||
|
||||
#ifdef CMake_USE_ELF_PARSER
|
||||
cmELF elf(file.c_str());
|
||||
if (!elf) {
|
||||
return false;
|
||||
}
|
||||
if (elf.GetMachine() != 0) {
|
||||
if (this->Machine != 0) {
|
||||
if (elf.GetMachine() != this->Machine) {
|
||||
this->SetError("All files must have the same architecture.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
this->Machine = elf.GetMachine();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return this->ScanDependencies(file, parentRpaths);
|
||||
}
|
||||
|
||||
@@ -150,13 +172,29 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies(
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool FileHasArchitecture(const char* filename, std::uint16_t machine)
|
||||
{
|
||||
#ifdef CMake_USE_ELF_PARSER
|
||||
cmELF elf(filename);
|
||||
if (!elf) {
|
||||
return false;
|
||||
}
|
||||
return machine == 0 || machine == elf.GetMachine();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool cmBinUtilsLinuxELFLinker::ResolveDependency(
|
||||
std::string const& name, std::vector<std::string> const& searchPaths,
|
||||
std::string& path, bool& resolved)
|
||||
{
|
||||
for (auto const& searchPath : searchPaths) {
|
||||
path = cmStrCat(searchPath, '/', name);
|
||||
if (cmSystemTools::PathExists(path)) {
|
||||
if (cmSystemTools::PathExists(path) &&
|
||||
FileHasArchitecture(path.c_str(), this->Machine)) {
|
||||
resolved = true;
|
||||
return true;
|
||||
}
|
||||
@@ -164,7 +202,8 @@ bool cmBinUtilsLinuxELFLinker::ResolveDependency(
|
||||
|
||||
for (auto const& searchPath : this->Archive->GetSearchDirectories()) {
|
||||
path = cmStrCat(searchPath, '/', name);
|
||||
if (cmSystemTools::PathExists(path)) {
|
||||
if (cmSystemTools::PathExists(path) &&
|
||||
FileHasArchitecture(path.c_str(), this->Machine)) {
|
||||
std::ostringstream warning;
|
||||
warning << "Dependency " << name << " found in search directory:\n "
|
||||
<< searchPath
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -29,6 +32,7 @@ private:
|
||||
std::unique_ptr<cmLDConfigTool> LDConfigTool;
|
||||
bool HaveLDConfigPaths = false;
|
||||
std::vector<std::string> LDConfigPaths;
|
||||
std::uint16_t Machine = 0;
|
||||
|
||||
bool ScanDependencies(std::string const& file,
|
||||
std::vector<std::string> const& parentRpaths);
|
||||
|
||||
@@ -168,6 +168,9 @@ public:
|
||||
// Return the recorded ELF type.
|
||||
cmELF::FileType GetFileType() const { return this->ELFType; }
|
||||
|
||||
// Return the recorded machine.
|
||||
std::uint16_t GetMachine() const { return this->Machine; }
|
||||
|
||||
protected:
|
||||
// Data common to all ELF class implementations.
|
||||
|
||||
@@ -183,6 +186,9 @@ protected:
|
||||
// The ELF file type.
|
||||
cmELF::FileType ELFType;
|
||||
|
||||
// The ELF architecture.
|
||||
std::uint16_t Machine;
|
||||
|
||||
// Whether we need to byte-swap structures read from the stream.
|
||||
bool NeedSwap;
|
||||
|
||||
@@ -478,6 +484,8 @@ cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external,
|
||||
}
|
||||
}
|
||||
|
||||
this->Machine = this->ELFHeader.e_machine;
|
||||
|
||||
// Load the section headers.
|
||||
this->SectionHeaders.resize(this->ELFHeader.e_shnum);
|
||||
for (ELF_Half i = 0; i < this->ELFHeader.e_shnum; ++i) {
|
||||
@@ -757,6 +765,14 @@ cmELF::FileType cmELF::GetFileType() const
|
||||
return FileTypeInvalid;
|
||||
}
|
||||
|
||||
std::uint16_t cmELF::GetMachine() const
|
||||
{
|
||||
if (this->Valid()) {
|
||||
return this->Internal->GetMachine();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int cmELF::GetNumberOfSections() const
|
||||
{
|
||||
if (this->Valid()) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -72,6 +73,9 @@ public:
|
||||
/** Get the type of the file opened. */
|
||||
FileType GetFileType() const;
|
||||
|
||||
/** Get the machine of the file opened. */
|
||||
std::uint16_t GetMachine() const;
|
||||
|
||||
/** Get the number of ELF sections present. */
|
||||
unsigned int GetNumberOfSections() const;
|
||||
|
||||
|
||||
@@ -1,5 +1,2 @@
|
||||
^CMake Error at cmake_install\.cmake:[0-9]+ \(file\):
|
||||
file Failed to run objdump on:
|
||||
|
||||
[^
|
||||
]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/linux-notfile-build/root-all/bin/\.\./lib/libtest\.so$
|
||||
file Could not resolve file libtest\.so$
|
||||
|
||||
Reference in New Issue
Block a user