我有一个二进制“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。我错过了什么?
答案 0 :(得分:37)
我假设你正在使用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链接行来通过编译器传递标记。
答案 1 :(得分:11)
根据此标记在链接器看到之前经过的层数,您可能需要使用$$ORIGIN
甚至\$$ORIGIN
。当readelf
显示看起来像$ORIGIN/../lib
或类似的RPATH标头时,您就会知道它是正确的。额外的$和反斜杠只是为了防止$被链中的其他工具处理。
答案 2 :(得分:1)
\ $ \ ORIGIN如果你使用chrpath和\ $ \ $ ORIGIN,如果你直接提供LDFLAGS