问题描述
|
我有一个二进制文件“ CeeloPartyServer”,需要在FreeBSD机器上的运行时找到libFoundation.so。它们都在同一目录中。我使用链接程序标记\“-rpath = $ ORIGIN \”编译(在另一个平台上,使用交叉编译器)CeeloPartyServer。
> readelf -d CeeloPartyServer | grep -i rpath
0x0000000f(RPATH)库rpath:[$ ORIGIN]
> ls
CeeloPartyServer Contents Foundation.framework libFoundation.so
> ./CeeloPartyServer
/libexec/ld-elf.so.1:找不到共享对象\“ CeeloPartyServer \”所需的对象\“ libFoundation.so \”
当我尝试运行它时,为什么找不到库?我的确切链接器行是:-lm -lMysqL -rpath = $ ORIGIN。我很确定我不必转义\\ $或类似的东西,因为我的readelf分析确实表明库rpath设置为$ ORIGIN。我想念什么?
解决方法
我假设您正在使用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驱动链接,因此在这种情况下,您需要通过在gcc链接行中添加-Wl,-z,origin
来通过编译器传递标志。
, 根据链接器看到它之前该标记经过的层数,您可能需要使用$$ORIGIN
甚至\\$$ORIGIN
。当readelf
显示看起来像$ORIGIN/../lib
或类似的RPATH标头时,您将知道它正确。多余的$和反斜杠只是为了防止$被链中其他工具处理。
, 如果使用的是chrpath,则为\\ $ \\ ORIGIN;如果直接使用LDFLAGS提供,则为\\ $ \\ $ ORIGIN