在Mac OS X中链接动态库(libjvm.dylib)(rpath问题)

scr*_*avy 11 macos java-native-interface linker haskell ghc

我确实有一个需要链接的应用程序libjvm(来自JDK的库需要进行JNI绑定).当我告诉libjvm.dylib使用-L它的位置成功编译和链接.但是,当我运行二进制文件时,我得到:

dyld: Library not loaded: @rpath/libjvm.dylib
  Referenced from: <my home directory>/./mybinary
  Reason: image not found
Run Code Online (Sandbox Code Playgroud)

到目前为止,我发现我可以像我这样运行指定LD_LIBRARY_PATH的二进制文件:

LD_LIBRARY_PATH=<path to libfolder installation> ./mybinary
Run Code Online (Sandbox Code Playgroud)

但我当然不希望这样.如果每次启动应用程序时必须一次又一次地给它,我为什么还要指定确切的位置?!

我还了解到mac os x上的动态库确实得到了一种说明位置的印章.但是我不知道是什么rpath(对我来说似乎是变量,但如何在链接期间设置它?).

该应用程序是使用haskell构建的,但我同样可以手动链接目标文件ld.但是,我坚持使用那个rpath的东西 - 这对JDK库来说可能是特殊的吗?

这是我为了构建而做的事情:

ghc --make Main.hs mycbinding.o -ljvm -L<javahome>/jre/lib/server -o mybinary
Run Code Online (Sandbox Code Playgroud)

bda*_*ash 12

来自Apple的dyld手册页:

@ rpath的/

  Dyld maintains a current stack of paths called the run path list.
  When @rpath is encountered it is substituted with each path in the
  run path list until a loadable dylib if found. The run path stack
  is built from the LC_RPATH load commands in the depencency chain
  that lead to the current dylib load. You can add an LC_RPATH load
  command to an image with the -rpath option to ld(1). You can even add
  a LC_RPATH load command path that starts with @loader_path/, and it
  will push a path on the run path stack that relative to the image
  containing the LC_RPATH. The use of @rpath is most useful when you
  have a complex directory structure of programs and dylibs which can be
  installed anywhere, but keep their relative positions. This scenario
  could be implemented using @loader_path, but every client of a dylib
  could need a different load path because its relative position in the
  file system is different. The use of @rpath introduces a level of
  indirection that simplies things. You pick a location in your directory
  structure as an anchor point. Each dylib then gets an install path that
  starts with @rpath and is the path to the dylib relative to the anchor
  point. Each main executable is linked with -rpath @loader_path/zzz,
  where zzz is the path from the executable to the anchor point. At runtime
  dyld sets it run path to be the anchor point, then each dylib is found
  relative to the anchor point.
Run Code Online (Sandbox Code Playgroud)

在扩展共享库装入命令中的前缀时,您需要在链接二进制文件时传递-rpath path/containing/the/libraryld它以告诉它在哪里搜索@rpath/.使用GHC,您可以使用-optl-Wl参数将标志传递给ld,因此您需要像这样调用GHC:

ghc --make Main.hs mycbinding.o -ljvm -L<javahome>/jre/lib/server -optl-Wl,-rpath,<javahome>/jre/lib/server -o mybinary
Run Code Online (Sandbox Code Playgroud)