2013-02-01 6 views
10

Mam aplikację, która wymaga powiązania z libjvm (biblioteka z pakietu JDK potrzebna do tworzenia powiązań JNI). Kiedy mówię o lokalizacji libjvm.dylib przy użyciu -L, to z powodzeniem kompiluje i łączy. Jednakże gdy uruchomię binarny uzyskać:Łączenie biblioteki dynamicznej (libjvm.dylib) w systemie Mac OS X (wydanie rpath)

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

tej pory dowiedziałem się, że mogę uruchomić mój binarny Określanie LD_LIBRARY_PATH tak:

LD_LIBRARY_PATH=<path to libfolder installation> ./mybinary 

Ale oczywiście nie chcę tego. Dlaczego powinienem podać dokładną lokalizację, czy muszę ją powtarzać za każdym razem, gdy uruchamiam aplikację ?!

Dowiedziałem się również, że biblioteki dynamiczne na Mac OS X otrzymują rodzaj znaczka, który określa lokalizację. Jednak nie wiem, co to jest rpath (wydaje mi się, że to zmienna, ale jak mogę ją ustawić podczas łączenia?).

Aplikacja jest zbudowana przy użyciu haskell, ale równie dobrze mogę połączyć pliki obiektów ręcznie przy użyciu ld. Jednak utknąłem na tym rpath rzecz - czy to może być specjalne do bibliotek JDK?

Oto co zrobić w celu zbudowania:

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

Odpowiedz

10

Od Apple 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. 

Trzeba zdać -rpath path/containing/the/library do ld kiedy łączę twój plik binarny, aby powiedzieć mu, gdzie se arch przy rozszerzaniu prefiksu @rpath/ we współużytkowaniu biblioteki współdzielonej. Z GHC możesz użyć argumentu -optl-Wl, aby przekazać flagi do ld, więc będziesz chciał wywołać GHC w następujący sposób:

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