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

Nek*_*ios 21 linker gcc freebsd rpath

我有一个二进制"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.我错过了什么?

acm*_*acm 38

我假设你正在使用gcc和binutils.

如果你这样做

readelf -d CeeloPartyServer | grep ORIGIN
Run Code Online (Sandbox Code Playgroud)

您应该返回上面找到的RPATH行,但是您还应该看到有关标志的一些条目.以下是我建立的图书馆.

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

如果您没有看到某种FLAGS条目,您可能没有告诉链接器将对象标记为需要原始处理.使用binutils ld,您可以通过传递-z origin标志来完成此操作.

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


Mic*_*lon 11

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

  • 只是为了不熟悉RPATH的其他人(比如我自己)澄清:在编译期间设置RPATH时,请尝试`LDFLAGS =" - Wl,-rpath,'\ $\$ ORIGIN'-Wl,-z,origin" ; 其中`echo $ LDFLAGS`将给出:`-Wl,-rpath,'$$ ORIGIN'-Wl,-z,origin`.(```有一些Makefile魔法.) (4认同)