25

我有一个二进制“CeeloPartyServer”,它需要在运行时在 FreeBSD 机器上找到 libFoundation.so。它们都在同一个目录中。我使用链接器标志(在另一个平台上,使用交叉编译器)编译 CeeloPartyServer -rpath=$ORIGIN

> readelf -d CeeloPartyServer |grep -i rpath
 0x0000000f (RPATH)                      Library rpath: [$ORIGIN]
> ls
CeeloPartyServer    Contents        Foundation.framework    libFoundation.so
> ./CeeloPartyServer 
/libexec/ld-elf.so.1: Shared object "libFoundation.so" not found, required by "CeeloPartyServer"

为什么我尝试运行它时找不到库?

我的确切链接器行是:-lm -lmysql -rpath=$ORIGIN.

我很确定我不必转义 $ 或类似的东西,因为我的 readelf 分析确实表明库 rpath 设置为 $ORIGIN。我错过了什么?

4

3 回答 3

42

我假设您正在使用 gcc 和 binutils。

如果你这样做

readelf -d CeeloPartyServer | grep ORIGIN

您应该返回您在上面找到的 RPATH 行,但您还应该看到一些关于标志的条目。以下来自我构建的库。

0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../lib]
0x000000000000001e (FLAGS)              ORIGIN
0x000000006ffffffb (FLAGS_1)            Flags: ORIGIN

如果您没有看到某种 FLAGS 条目,您可能没有告诉链接器将该对象标记为需要原始处理。使用 binutils ld,您可以通过传递-z origin标志来做到这一点。

我猜你正在使用 gcc 来驱动链接,所以在这种情况下,你需要通过添加-Wl,-z,origin到你的 gcc 链接行来通过编译器传递标志。

于 2011-06-13T14:25:56.637 回答
16

根据这个标志在链接器看到它之前经过了多少层,您可能需要使用$$ORIGIN或什至\$$ORIGIN. readelf当显示一个看起来像$ORIGIN/../lib或相似的 RPATH 标头时,您将知道您是正确的。额外的 $ 和反斜杠只是为了防止 $ 被链中的其他工具处理。

于 2011-06-15T02:34:35.447 回答
3

\$\ORIGIN 如果您使用的是 chrpath 和 \$\$ORIGIN 如果您直接在 LDFLAGS 中提供

于 2016-06-28T10:43:41.897 回答