共享库路径作为可执行文件目录

13

我有一个应用程序,为了代码重用而分成几个库。在 Windows 上,我只需将 .dll 文件放在可执行文件相同的路径下,它就会自动找到它们。但在 Linux 上(因为它硬编码了路径),我必须指定环境变量 LD_LIBRARY_PATH 或在可执行文件之前预加载这些库。

我看到一些关于使用链接器选项 -Wl,-rpath=<PATH> 嵌入路径的内容,我尝试使用 . 作为路径。但那只是查找当前工作目录,而不是可执行文件的目录。

是否有一种方法可以在链接器中默认查找可执行文件目录中的共享库(就像在 Windows 上)?

谢谢! Matt

2个回答

19
你需要在RPATH中使用$ORIGIN,可以通过用适当的选项传递给ld或其他Darwin工具来实现。请参见这里这里
记住,$符号必须真正出现在路径中,因此您需要在链接命令行中进行引用或转义。
更新: 您可以使用以下命令查看链接器实际放入可执行文件中的内容:
readelf -d /path/to/exe | grep RPATH

这是输出应该看起来的样子:

 0x0000000f (RPATH)              Library rpath: [$ORIGIN]

4
使用 $ORIGIN 时,需要确保 $ 被正确引用,以便链接器能够正确识别它。从命令行中,您需要使用 "-rpath $ORIGIN",从Makefile中,您需要使用 "-rpath $$ORIGIN"。 - R Samuel Klatchko
我正在使用Eclipse和CDT,并将选项放在杂项链接器标志下。我正在放置-Wl,-rpath = $$ ORIGIN,并且在输出窗口中,它显示为单个$。但是似乎不起作用。我尝试了几种变化,但没有任何反应。就像链接器忽略了该标志一样。我尝试过: -Wl,-rpath = $ ORIGIN -Wl,--rpath = $ ORIGIN -Wl,-rpath = / $ ORIGIN -Wl,-rpath = $ ORIGIN / -Wl,-rpath = / $ ORIGIN / 等等。 - CuppM
使用elfdump或本地等效工具查看其中的内容?使用ldd并查看它所说的内容? - bmargulies
2
如上所述,-rpath \$$ORIGIN 怎么样? - John Zwinck
3
搞定了,我只是没有正确转义$符号。使用readelf命令检查参数字符串有助于确保我输入了正确的内容。在Eclipse中可行的标志字符串是“-Wl,-rpath=$$ORIGIN”。 - CuppM
所以$ORIGIN实际上是可执行文件的路径,无论您将可执行文件放在哪里。 - Baiyan Huang

2

将您的程序封装在一个shell脚本中:

#!/bin/sh

PROGRAM_DIRECTORY="`dirname "$0"`"
export LD_LIBRARY_PATH="$PROGRAM_DIRECTORY"

"$PROGRAM_DIRECTORY/program_executable" "$@"

如果您运行此脚本(而不是您的可执行文件),您的程序将链接成功。

是的,这就是我一直在做的事情,而且它很有效。该应用程序有一个使用OpenMPI的并行化版本,并且它有一种共享LD_LIBRARY_PATH的方法。因此,我们目前正在使用该解决方法,但我们希望有更简单的方法来处理事情,因为该应用程序(以及MPI运行程序)需要多个标志来处理内容。 - CuppM
你可以使用 "$@" 将脚本中的所有参数传递给程序。 - Roger Pate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接