C++ 带有运行路径的辅助依赖解析

2024-02-25

我有以下问题:

我正在尝试使用默认的 gnu 编译器 (gcc-7) 和可用的链接器版本在 Ubuntu18 上构建软件。

现在我们遇到这样的情况,一个可执行文件可以链接一个共享库,该共享库又链接另一个共享库。因此,可执行文件具有次要依赖性。但次要依赖项仅从 rpath 中获取,而不是从 runpath 中获取。因此,即使辅助依赖项放置在可执行文件的运行路径文件夹中,也不会找到它。

结合使用 googletest 和 cmake 时发现了该问题。由于未找到次要依赖项,因此无法编译测试。所以设置LD_LIBRARY_PATH可能不是一个选择,或者至少使一切变得更加复杂。

以下是 Ubuntu 18 系统上 gcc-7 出现问题的示例(但在 Ubuntu 16 上使用 gcc-5 工作正常):

二级.hpp

#include <string>

class World{
    public:
        std::string world();
};

次要.cpp

#include "secondary.hpp"

std::string World::world(){
    return "world";
}

初级.hpp

#include <string>

class Hello{
  public:
    std::string helloWorld();
};

主要.cpp

#include "primary.hpp"
#include "secondary.hpp"
#include <sstream>

std::string Hello::helloWorld(){
    std::stringstream strm;
    World world;

    strm << "hello ";
    strm << world.world();
    strm << "!";

    return strm.str();
}

并像这样编译两个库

mkdir build
cd build
gcc -shared -o libsecondary.so -fPIC ../secondary.cpp
gcc -shared -o libprimary.so -fPIC ../primary.cpp  -lsecondary -L$(pwd)

如果我现在从以下文件构建一个可执行文件

main.cpp

#include "primary.hpp"
#include <iostream>

int main(int argc, char** argv){
    Hello hello;
    std::cout << hello.helloWorld() << std::endl;
}

通过在新的构建目录中执行以下操作(与前一个目录平行)

cd ..
mkdir build_app
cd build_app
gcc -o app ../main.cpp -L../build -lstdc++ -lsecondary -lprimary  -Wl,-rpath=$(pwd)/../build

如果我现在这样做ldd app我看到libsecondary.so没有找到

    linux-vdso.so.1 (0x00007fff0cf8c000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9e86fe7000)
    libprimary.so => <some_path>/libprimary.so (0x00007f9e86de5000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9e86bcd000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9e867dc000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9e8643e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f9e87573000)
    libsecondary.so => not found

应用程序的运行路径是(通过运行readelf -d app)

Dynamic section at offset 0x1d40 contains 31 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libprimary.so]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000001d (RUNPATH)            Library runpath:[<some_path>/build]

问题是,为什么ld没有服用libsecondary.so从运行路径app? Both libprimary.so and libsecondary.so放在同一个文件夹中,但仅libprimary.so被发现。

该问题的一种解决方案是编译--disable-new-dtags它将使用 rpath 而不是 runpath,并且是 Ubuntu16 上 gcc-5 的默认设置。然而,ld 似乎已弃用 rpath 的使用。

那么将 runpath 与辅助依赖项一起使用的正确方法是什么?


libprimary负责装载libsecondary, not app。这意味着 DT_RUNPATH 条目app不适用。

由于您可以控制所有库,因此您可以添加一个-Wl,-rpath=...到编译语句libprimary and libsecondary以及。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 带有运行路径的辅助依赖解析 的相关文章

  • 具有不同大小结构的结构数组的 malloc()

    如果每个结构都包含一个大小不同的字符串数组 那么如何正确地 malloc 一个结构数组 因此每个结构可能有不同的大小 并且不可能 realloc 结构体数量 sizeof 结构体名称 after malloc 初始大小 sizeof 结构名
  • 在 VS2017 下使用 Conan 和 CMake 项目进行依赖管理

    我正在尝试使用 CMake 与 VS2017 集成为 C 设置一个开发环境 以便在 Linux x64 下进行编译 为了更好地管理依赖关系 我选择使用 Conan 但我对这个软件还很陌生 我想知道让 VS2017 识别项目依赖关系的最佳方法
  • 从多线程程序中调用 system()

    我们正在开发一个用 C 编写的多线程内存消耗应用程序 我们必须执行大量的 shellscript linux 命令 并获取返回码 读完之后article http www linuxprogrammingblog com threads a
  • System.IO.IOException:由于意外>数据包格式,握手失败?

    有谁知道这意味着什么 System Net WebException 底层连接已关闭 发送时发生意外错误 gt System IO IOException 由于意外 握手失败 数据包格式 在 System Net Security SslS
  • ASP.NET Core 与现有的 IoC 容器和环境?

    我想运行ASP NET 核心网络堆栈以及MVC在已托管现有应用程序的 Windows 服务环境中 以便为其提供前端 该应用程序使用 Autofac 来处理 DI 问题 这很好 因为它已经有一个扩展Microsoft Extensions D
  • 为什么Apache MPM prefork.c 使用互斥体来保护accept()?

    我坐下来读书Apache 的 MPM prefork c http code metager de source xref apache httpd server mpm prefork prefork c这段代码使用了一个名为accept
  • 为什么大多数平台上没有“aligned_realloc”?

    MSVC有自己的非标准函数 aligned malloc aligned realloc and aligned free C 17和C11引入了 std aligned alloc 其结果可以是de分配有free or realloc B
  • CultureInfo 的实例(来自相同的文化)根据操作系统而变化

    我有一个网站 上面写着这样的日期 CultureInfo cultureInfo CultureInfo GetCultures CultureTypes AllCultures FirstOrDefault c gt string Equ
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • 获取尚未实例化的类的函数句柄

    我对 C 相当陌生 我想做的事情可能看起来很复杂 首先 我想获取一些函数的句柄以便稍后执行它们 我知道我可以通过以下方式实现这一目标 List
  • 将字符串转换为正确的 URI 格式?

    有没有简单的方法可以将电子邮件地址字符串转换为正确的 URI 格式 Input http mywebsite com validate email 3DE4ED727750215D957F8A1E4B117C38E7250C33 email
  • 如何生成 appsettings..json 文件?

    我有一个 ASP NET Core 2 WebAPI 它将部署在以下环境中 INT QA STAGE 生产环境 基于上述 我需要有appsettings
  • libxml2 xmlChar * 到 std::wstring

    libxml2似乎将所有字符串存储在 UTF 8 中 如xmlChar xmlChar This is a basic byte in an UTF 8 encoded string It s unsigned allowing to pi
  • 分配器感知容器和propagate_on_container_swap

    The std allocator traits模板定义了一些常量 例如propagate on container copy move assign让其他容器知道它们是否应该在复制或移动操作期间复制第二个容器的分配器 我们还有propag
  • 从 R 到 C 处理列表并访问它

    我想使用从 R 获得的 C 列表 我意识到这个问题与此非常相似 使用 call 在 R 和 C 之间传递数据帧 https stackoverflow com questions 6658168 passing a data frame f
  • .NET 客户端中 Google 表格中的条件格式请求

    我知道如何在 Google Sheets API 中对值和其他格式进行批量电子表格更新请求 但条件格式似乎有所不同 我已正确设置请求 AddConditionalFormatRuleRequest formatRequest new Add
  • WPF。如何从另一个窗口隐藏/显示主窗口

    我有两个窗口 MainWindow 和 Login 显示登录的按钮位于主窗口 this Hide Login li new Login li Show 登录窗口上有一个检查密码的按钮 如果密码正确 我如何显示主窗口 将参数传递给 MainW
  • 从 Delphi 调用 C# dll

    我用单一方法编写了 Net 3 5 dll 由Delphi exe调用 不幸的是它不起作用 步骤 1 使用以下代码创建 C 3 5 dll public class MyDllClass public static int MyDllMet
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne

随机推荐

  • 索引键列 VS 索引包含列

    谁能解释一下这两个 索引Key列 VS 索引Included Column 目前 我的索引有 4 个索引键列和 0 个包含列 我想知道两者之间的区别 索引键列是索引 B 树的一部分 包含的列不是 取两个索引 CREATE INDEX ind
  • Codesandbox.io 中的 React-Testing-Library 问题

    我对 React 来说是一个相对菜鸟 想在这个沙盒中练习一些 tdd基本反应沙箱 https codesandbox io s 93yp98knx4 测试代码似乎正在影响应用程序组件状态 如果您在浏览器和测试之间切换 您将看到测试项目被添加
  • SQL Select 包括数据类型和数据值

    如何从表中选择数据并将数据类型包含在值中 例如 我有一个名为 EMPLOYEE 的表 其中包含 fname lastname phone 等 如果我做 SELECT FROM EMPLOYEE 我得到了所有的列 如果我做 SELECT CO
  • 如何定位 UIView?

    我花了几个小时尝试定位 UIView 最终发现我需要修改视图框架 所以我向 UIViewController 子类添加了一个 setPosition 方法 如下所示 void setPosition CGPoint position CGR
  • 将 YYYYMMDD 字符串日期转换为日期时间值[重复]

    这个问题在这里已经有答案了 可能的重复 在 C 中将字符串转换为日期时间 https stackoverflow com questions 1592653 convert string to datetime in c sharp 一个问
  • UIViewController PresentViewController 在 ios 8 上崩溃

    刚刚在我们的错误记录系统中收到此错误 一直在高低搜索 似乎找不到任何解决方案 任何帮助表示赞赏 这里是堆栈跟踪 https gist github com hermanccw 2a9264fd77d46e0e7279 可能在您的 XCODE
  • RESTful 破坏 Rails 中的多态关联?

    如何销毁关联本身并保留关联的对象 同时保持 RESTful 具体来说 我有这些模型 class Event lt ActiveRecord Base has many model surveys as gt surveyable depen
  • 对于表单中的每个控件,如何对表单中的所有文本框执行某些操作?

    如何使用 Foreach 语句对我的文本框执行某些操作 foreach Control X in this Controls Check if the controls is a TextBox if it is delete it s T
  • 命名空间 system.windows 中不存在“Forms”

    我刚刚开始研究 c 并且正在摆弄从某个论坛获得的一些代码示例 此代码使用命名空间using system windows forms我收到错误 命名空间 system windows 中不存在 Forms 我还收到一些与未定义函数相关的错误
  • 如何使用 Azure 移动服务 API 功能

    An APIWAMS 中添加了功能 我可以在其中定义自定义脚本 这似乎反对以前创建脚本表的做法 但是 我找不到任何有关如何使用它的描述 哪些客户端可以使用此功能 可以在 iOS 或 Javascript 中使用吗 还有关于这个主题的更多帖子
  • 我可以让 valgrind 告诉我哪个值未初始化吗?

    I ran valgrind一些代码如下 valgrind tool memcheck leak check full track origins yes test 它返回以下错误 24860 Conditional jump or mov
  • 删除 Safari/Chrome 文本输入/文本区域发光

    我想知道当我使用 CSS 单击文本输入 文本区域时是否可以删除默认的蓝色和黄色发光 编辑 11 年后 不要这样做 除非您要提供后备来指示哪个元素处于活动状态 否则 这会损害可访问性 因为它本质上删除了显示文档中哪个元素具有焦点的指示 想象一
  • mysql json vs mongo - 存储空间

    我遇到了一个有趣的情况 虽然不是一个实际的问题 但我不明白为什么会发生这种情况 我们有一个 mongo 数据库 主要由存储在数组中的一些批量数据组成 由于团队中超过 90 的人熟悉 mysql 而只有少数人熟悉 mongo 再加上这不是关键
  • 钻石继承 (C++)

    我知道拥有钻石继承被认为是不好的做法 然而 我有两个案例 我觉得钻石继承非常适合 我想问 在这些情况下你会建议我使用钻石继承 还是有其他设计可以更好 Case 1 我想创建代表系统中不同类型 操作 的类 这些动作按几个参数分类 该操作可以是
  • StackExchange.Redis - LockTake / LockRelease 用法

    我将 Redis 与 StackExchange Redis 一起使用 我有多个线程 它们会在某个时刻访问和编辑同一键的值 因此我需要同步数据的操作 查看可用的函数 我发现有两个函数 TakeLock 和 ReleaseLock 但是 这些
  • Apache mod 重写简单重定向

    我希望对我的网站的请求按如下方式工作 http example com http example com 理想情况下会拉出index php文件 当前默认行为 而不显示index php http example com foo php h
  • 读取和写入长时间运行的 std::process::Child

    我有一个长时间运行的子进程 我需要读取和写入大量数据 我有一个读取器线程和一个写入器线程来操纵child stdout and child stdin分别 extern crate scoped threadpool fn main run
  • 如何通过 VBA 将选择范围扩展到整个段落

    我正在使用此代码将选择范围扩展到Word文档中的整行 现在我想将选择范围扩展到整个段落 Selection Expand wdLine 尝试使用不同的 WdUnit 例如 wdParagraph Selection Expand wdPar
  • PHP - 使图像背景透明并具有容差

    所以我将三个图像设为透明并将它们相互叠加 我按照这篇文章中的示例代码进行操作 用php删除图像背景并保存透明png https stackoverflow com questions 10751227 remove image backgr
  • C++ 带有运行路径的辅助依赖解析

    我有以下问题 我正在尝试使用默认的 gnu 编译器 gcc 7 和可用的链接器版本在 Ubuntu18 上构建软件 现在我们遇到这样的情况 一个可执行文件可以链接一个共享库 该共享库又链接另一个共享库 因此 可执行文件具有次要依赖性 但次要