2013-02-01 39 views
10

Tôi có một ứng dụng yêu cầu liên kết với libjvm (thư viện từ JDK cần thực hiện các kết buộc JNI). Khi tôi nói với vị trí của libjvm.dylib sử dụng -L, nó biên dịch và liên kết thành công. Tuy nhiên khi tôi chạy nhị phân tôi nhận được:Liên kết thư viện động (libjvm.dylib) trong Mac OS X (vấn đề rpath)

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

Cho đến nay tôi phát hiện ra rằng tôi có thể chạy nêu rõ LD_LIBRARY_PATH nhị phân của tôi như vậy:

LD_LIBRARY_PATH=<path to libfolder installation> ./mybinary 

Nhưng tất nhiên tôi không muốn điều đó. Tại sao tôi nên chỉ định chính xác vị trí nếu tôi phải cung cấp lại nó mỗi lần tôi khởi động ứng dụng ?!

Tôi cũng đã học được rằng thư viện động trên mac os x có được một loại tem cho biết vị trí đó. Tuy nhiên tôi không biết những gì rpath là (có vẻ như một biến cho tôi, nhưng làm thế nào tôi có thể thiết lập nó trong quá trình liên kết?).

Ứng dụng được xây dựng bằng haskell, nhưng tôi cũng có thể liên kết tốt các tệp đối tượng theo cách thủ công bằng cách sử dụng ld. Tuy nhiên, tôi đang bị mắc kẹt trên điều đó rpath - là nó có thể đặc biệt cho các thư viện JDK?

Dưới đây là những gì tôi làm để xây dựng:

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

Trả lời

10

Từ dyld man page của Apple:

@ 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. 

Bạn cần phải vượt qua -rpath path/containing/the/library-ld khi liên kết nhị phân của bạn để cho nó biết nơi cần vòm khi mở rộng tiền tố @rpath/ trong lệnh tải thư viện được chia sẻ. Với GHC, bạn có thể sử dụng đối số -optl-Wl để chuyển nó qua cờ ld, vì vậy bạn sẽ muốn gọi GHC như sau:

ghc --make Main.hs mycbinding.o -ljvm -L<javahome>/jre/lib/server -optl-Wl,-rpath,<javahome>/jre/lib/server -o mybinary 
Các vấn đề liên quan