2013-02-01 178 views
10

我確實有一個應用程序需要與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 

回答

10

從蘋果公司的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/libraryld當鏈接你的二進制文件告訴它在哪裏在擴展共享庫加載命令中的@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