在Mac OS X中链接动态库(libjvm.dylib)(rpath问题) [英] Linking a dynamic library (libjvm.dylib) in Mac OS X (rpath issue)

查看:2884
本文介绍了在Mac OS X中链接动态库(libjvm.dylib)(rpath问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  dyld:库未加载:@ rpath / libjvm.dylib 
Referenced from:< my home directory> /./ mybinary
原因:image not found

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

  LD_LIBRARY_PATH =< libfolder安装路径> ./mybinary 

但我当然不希望这样。为什么我应该指定确切的位置呢?如果我必须在每次启动应用程序时都一次又一次地给出它!!

我还了解到,mac os上的动态库x确实得到一种告诉那里有位置的邮票。但是我不知道什么 rpath 是(对我来说看起来像是一个变量,但是我怎样才能在链接期间设置它?)。



应用程序使用haskell构建,但我也可以使用 ld 手动链接目标文件。然而,我被困在那个rpath的东西 - 这可能是特殊的JDK库?



这是我为了构建:

  ghc --make Main.hs mycbinding.o -ljvm -L< javahome> / jre / lib / server -o mybinary 


解决方案

从Apple's dyld手册页


@rpath /

  Dyld维护一个称为运行路径列表的路径的当前堆栈。 
当遇到@rpath时,它会被替换为
运行路径列表中的每个路径,直到找到可加载的dylib。运行路径堆栈
是根据导致当前dylib负载的依赖链
中的LC_RPATH加载命令构建的。您可以使用ld(1)的-rpath选项将LC_RPATH加载
命令添加到图像。您甚至可以添加
以@ loader_path /开头的LC_RPATH加载命令路径,并且
将在运行路径堆栈上推送相对于包含LC_RPATH的映像
的路径。当你
有一个复杂的程序目录结构和dylib可以在任何地方安装
,但保持其相对位置时,@rpath的使用是最有用的。这种情况
可以使用@loader_path来实现,但是每个dylib
的客户端可能需要不同的加载路径,因为它在
文件系统中的相对位置不同。 @rpath的使用引入了简化事物的
间接级别。您在目录
结构中选择一个位置作为定位点。然后每个dylib都会得到一个安装路径,
以@rpath开头,并且是dylib相对于
锚点的路径。每个主要可执行文件都与-rpath @ loader_path / zzz,
链接,其中zzz是从可执行文件到定位点的路径。在运行时
dyld将其运行路径作为定位点,然后相对于定位点找到每个dylib


您需要传递 -rpath路径在包含时,在链接二进制文件时告诉它在哪里搜索到 ld 共享库加载命令中的前缀。使用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 


I do have an application that requires linkage with libjvm (a library from the JDK needed to do JNI bindings). When I tell the location of libjvm.dylib using -L it successfully compiles and links. However when I run the binary I get:

dyld: Library not loaded: @rpath/libjvm.dylib
  Referenced from: <my home directory>/./mybinary
  Reason: image not found

So far I found out that I can run my binary specifying LD_LIBRARY_PATH like so:

LD_LIBRARY_PATH=<path to libfolder installation> ./mybinary

But of course I do not want that. Why should I specify the exact location anyway if I have to give it again and again each time I start the application?!

I also learned that dynamic libraries on mac os x do get a kind of stamp which tells there location. However I don't know what rpath is (seems like a variable to me, but how can I set it during linking?).

The application is built using haskell, but I can equally well link the object files manually using ld. However, I'm stuck on that rpath thing - is it maybe special to the JDK libraries?

Here is what I do in order to build:

ghc --make Main.hs mycbinding.o -ljvm -L<javahome>/jre/lib/server -o mybinary

解决方案

From Apple's 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.

You need to pass -rpath path/containing/the/library to ld when linking your binary to tell it where to search when expanding the @rpath/ prefix in the shared library load command. With GHC you can use the -optl-Wl argument to have it pass flags through to ld, so you'll want to invoke GHC like so:

ghc --make Main.hs mycbinding.o -ljvm -L<javahome>/jre/lib/server -optl-Wl,-rpath,<javahome>/jre/lib/server -o mybinary

这篇关于在Mac OS X中链接动态库(libjvm.dylib)(rpath问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆