rpath=$ORIGIN 没有达到预期的效果?

发布于 2024-11-15 05:37:57 字数 660 浏览 8 评论 0原文

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

> 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。我缺少什么?

I've got a binary "CeeloPartyServer" that needs to find libFoundation.so at runtime, on a FreeBSD machine. They're both in the same directory. I compile (on another platform, using a cross compiler) CeeloPartyServer using linker flag -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"

Why isn't it finding the library when I try to run it?

My exact linker line is: -lm -lmysql -rpath=$ORIGIN.

I am pretty sure I don't have to escape $ or anything like that since my readelf analysis does in fact show that library rpath is set to $ORIGIN. What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

淡笑忘祈一世凡恋 2024-11-22 05:37:57

我假设您正在使用 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 链接行来通过编译器传递标志。

I'm assuming you are using gcc and binutils.

If you do

readelf -d CeeloPartyServer | grep ORIGIN

You should get back the RPATH line you found above, but you should also see some entries about flags. The following is from a library that I built.

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

If you aren't seeing some sort of FLAGS entries, you probably haven't told the linker to mark the object as requiring origin processing. With binutils ld, you do this by passing the -z origin flag.

I'm guessing you are using gcc to drive the link though, so in that case you will need to pass flag through the compiler by adding -Wl,-z,origin to your gcc link line.

守望孤独 2024-11-22 05:37:57

根据链接器看到该标志之前经过的层数,您可能需要使用 $$ORIGIN 甚至 \$$ORIGIN。当 readelf 显示看起来像 $ORIGIN/../lib 或类似的 RPATH 标头时,您就会知道您的选择是正确的。额外的 $ 和反斜杠只是为了防止 $ 被链中的其他工具处理。

Depending on how many layers this flag passes through before the linker sees it, you may need to use $$ORIGIN or even \$$ORIGIN. You will know that you have it right when readelf shows an RPATH header that looks like $ORIGIN/../lib or similar. The extra $ and the backslash are just to prevent the $ from being processed by other tools in the chain.

但可醉心 2024-11-22 05:37:57

如果您使用 chrpath,则为 \$\ORIGIN;如果您直接在 LDFLAGS 中提供,则为 \$\$ORIGIN

\$\ORIGIN if you are using chrpath and \$\$ORIGIN if you are providing directly in LDFLAGS

浅浅 2024-11-22 05:37:57
  1. 使用ldd CeeloPartyServer检查依赖关系.so是否以./开头。 (例如libFoundation.so./libFoundation.so
    对于常见情况,它应该是 libFoundation.so 并且没有前缀 ./

  2. 如果某些不常见情况需要 ./ 前缀,确保 CWD 与 libFoundation.so 位于同一文件夹,否则 $ORIGIN 无效。

=======
例如:
g++ --shared -Wl,--rpath="\$ORIGIN" ./libFoundation.so -o lib2.so
将获得一个库 lib2.so./libFoundation.so
g++ --shared -Wl,--rpath="\$ORIGIN" libFoundation.so -o lib2.so
将会得到 libFoundation.so

  1. using ldd CeeloPartyServer to check the dependency .so is starting with ./ or not. (e.g. libFoundation.so and ./libFoundation.so)
    For common situation it should be libFoundation.so and without the prefix ./

  2. if ./ prefix is necessary for some uncommon case, make sure the CWD is the same folder with libFoundation.so, and the $ORIGIN would be invalid.

=======
For example:
g++ --shared -Wl,--rpath="\$ORIGIN" ./libFoundation.so -o lib2.so
would got a library lib2.so with ./libFoundation.so
g++ --shared -Wl,--rpath="\$ORIGIN" libFoundation.so -o lib2.so
would got libFoundation.so instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文