为依赖项的依赖项设置 rpath?

Setting rpath for dependencies of dependencies?

我有一个 Linux 可执行构建,我通过链接器标志 "-Wl,-rpath,./ -Wl,--disable-new-dtags" 设置了 rpath,并且我已经通过 readelf -d 验证了 RPATH 正在设置到./

这适用于直接依赖项,因为我的可执行文件在放置在同一目录中时能够找到它们。但是,这不适用于依赖关系:

46763:     find library=libpulsecommon-13.99.so [0]; searching
46763:     search path=/usr/lib/x86_64-linux-gnu/pulseaudio/tls/x86_64/x86_64:/usr/lib/x86_64-linux-gnu/pulseaudio/tls/x86_64:/usr/lib/x86_64-linux-gnu/pulseaudio/tls/x86_64:/usr/lib/x86_64-linux-gnu/pulseaudio/tls:/usr/lib/x86_64-linux-gnu/pulseaudio/x86_64/x86_64:/usr/lib/x86_64-linux-gnu/pulseaudio/x86_64:/usr/lib/x86_64-linux-gnu/pulseaudio/x86_64:/usr/lib/x86_64-linux-gnu/pulseaudio        
(RUNPATH from file ./libpulse.so.0)

此处,libpulse 正在使用其自己的运行路径查找 libpulsecommon,该运行路径不包含直接相对路径。我已经改用 rpath 而不是 runpath,因为我看到它提到 rpath 应该传播到依赖项(而 runpath 是 "every binary handles itself")。不过,情况似乎并非如此。

设置 Linux 可执行文件的正确方法是什么,以便我在同一目录中提供的任何依赖项都能被它及其依赖项找到?

我最终在构建时没有做任何事情,而是在我的 CMake 中添加了一个 post-构建步骤,我 运行 patchelf 将所有 rpaths 更改为 $ORIGIN:

if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
    add_custom_command(
            TARGET Client POST_BUILD
                COMMAND find ${OUTPUT_DIR} -type f -maxdepth 1 -exec patchelf --set-rpath '$$ORIGIN' {} \\;
    )
endif()

为了让任何阅读者更完整,更正常的路径是有一个安装步骤,您将文件放在适当的目录中并使用已安装的系统共享库。在我的情况下,安装步骤不合适,所以我在构建步骤之后添加自定义命令,以将我的依赖项复制到包含可执行文件的目录中并修改 rpath,以便它们正确加载。