rpath=$ORIGIN 没有达到预期的效果?
我有一个二进制“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我假设您正在使用 gcc 和 binutils。
如果这样做,
您应该返回上面找到的 RPATH 行,但您还应该看到一些有关标志的条目。以下内容来自我构建的库。
如果您没有看到某种 FLAGS 条目,则您可能没有告诉链接器将对象标记为需要原始处理。使用 binutils ld,您可以通过传递
-z origin
标志来完成此操作。我猜您正在使用 gcc 来驱动链接,因此在这种情况下,您需要通过将
-Wl,-z,origin
添加到 gcc 链接行来通过编译器传递标志。I'm assuming you are using gcc and binutils.
If you do
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.
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.根据链接器看到该标志之前经过的层数,您可能需要使用
$$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 whenreadelf
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.如果您使用 chrpath,则为 \$\ORIGIN;如果您直接在 LDFLAGS 中提供,则为 \$\$ORIGIN
\$\ORIGIN if you are using chrpath and \$\$ORIGIN if you are providing directly in LDFLAGS
使用
ldd CeeloPartyServer
检查依赖关系.so是否以./
开头。 (例如libFoundation.so
和./libFoundation.so
)对于常见情况,它应该是
libFoundation.so
并且没有前缀./
如果某些不常见情况需要
./
前缀,确保 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
。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./
if
./
prefix is necessary for some uncommon case, make sure the CWD is the same folder withlibFoundation.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.