在Mac OS X(rpath问题)中链接动态库(libjvm.dylib)
问题描述:
我确实有一个应用程序需要与libjvm
(需要执行JNI绑定的JDK库)链接。当我使用-L
告诉libjvm.dylib
的位置时,它成功编译和链接。然而,当我运行的二进制我得到:在Mac OS X(rpath问题)中链接动态库(libjvm.dylib)
dyld: Library not loaded: @rpath/libjvm.dylib
Referenced from: <my home directory>/./mybinary
Reason: image not found
到目前为止,我发现我可以运行我的二进制指定LD_LIBRARY_PATH像这样:
LD_LIBRARY_PATH=<path to libfolder installation> ./mybinary
但我当然不希望这样。为什么我应该指定确切的位置?如果我每次开始应用程序时必须一次又一次地提供它!
我还了解到,在mac os x上的动态库确实会得到一种告诉那里位置的邮票。但是我不知道rpath
是什么(对我来说好像是一个变量,但是我怎样才能在连接过程中设置它?)。
该应用程序使用haskell构建,但我同样可以使用ld
手动链接目标文件。然而,我被困在那个rpath的东西 - 这可能是特殊的JDK库?
这是我为了打造这样做:
ghc --make Main.hs mycbinding.o -ljvm -L<javahome>/jre/lib/server -o mybinary
答
从苹果公司的dyld man page:
@是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.
你需要传递-rpath path/containing/the/library
到ld
当链接你的二进制文件告诉它在哪里在扩展共享库加载命令中的@rpath/
前缀时使用arch。使用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