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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With