Связывание динамической библиотеки (libjvm.dylib) в Mac OS X (проблема rpath)
у меня есть приложение, которое требует увязки с libjvm
(библиотека из JDK, необходимая для Привязок JNI). Когда я скажу местоположение libjvm.dylib
используя -L
он успешно компилируется и ссылки. Однако, когда я запускаю двоичный файл, я получаю:
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
is (кажется мне переменной, но как я могу установить ее во время связывания?).
приложение построено с помощью haskell, но я также могу связать объектные файлы вручную с помощью ld
. Тем не менее, я застрял на этой вещи rpath - это может быть особенным для библиотек JDK?
здесь это то, что я делаю, чтобы построить:
ghc --make Main.hs mycbinding.o -ljvm -L<javahome>/jre/lib/server -o mybinary
1 ответов
от 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.
вам нужно пройти -rpath path/containing/the/library
to ld
при связывании вашего двоичного файла, чтобы сообщить ему, где искать при расширении @rpath/
префикс в команде загрузки общей библиотеки. С 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