2013-02-01 14 views
10

Ho un'applicazione che richiede il collegamento con libjvm (una libreria dal JDK necessaria per eseguire i binding JNI). Quando dico la posizione di libjvm.dylib usando -L compila con successo e collegamenti. Tuttavia quando ho eseguito il binario ottengo:Collegamento di una libreria dinamica (libjvm.dylib) in Mac OS X (problema rpath)

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

Finora ho scoperto che posso correre il mio binario LD_LIBRARY_PATH specificando in questo modo:

LD_LIBRARY_PATH=<path to libfolder installation> ./mybinary 

Ma naturalmente io non voglio questo. Perché dovrei specificare la posizione esatta in ogni caso se devo darlo ancora e ancora ogni volta che avvio l'applicazione ?!

Ho anche imparato che le librerie dinamiche su mac os x ottengono un tipo di timbro che indica la posizione. Comunque non so cosa sia rpath (mi sembra una variabile, ma come posso impostarlo durante il collegamento?).

L'applicazione viene creata utilizzando haskell, ma posso ugualmente collegare i file oggetto manualmente utilizzando ld. Tuttavia, io sono bloccato su quella cosa rpath - è forse speciale per le librerie JDK?

Ecco quello che faccio al fine di costruire:

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

risposta

10

Da dyld man page di 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. 

È necessario passare -rpath path/containing/the/library-ld quando colleghi il tuo binario per dirgli dove arch quando si espande il prefisso @rpath/ nel comando di caricamento della libreria condivisa. Con GHC è possibile utilizzare l'argomento -optl-Wl avere passare bandiere fino al ld, quindi ti consigliamo di richiamare GHC in questo modo:

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