Объединение файлов .dylib с исполняемым файлом mono

У меня есть приложение, и я хочу связать с ним определенный дилиб. Я использую «dylibbundler», чтобы скопировать dylib вместе с зависимостями в исполняемую папку. Вот команда, которую я использую:

dylibbundler -od -b -x /opt/local/lib/libil.dylib -d ./libs/ -p @executable_path/libs/

dylibbundler находится в том же каталоге, что и исполняемый файл. Инструмент рекурсивно запускает install_name_tool для библиотеки и всех ее зависимостей (и копирует их в указанный каталог). Запуск otool -L на ./libs/libil.1.dylib возвращает:

@executable_path/libs/libIL.1.dylib (compatibility version 3.0.0, current version 3.0.0)
@executable_path/libs/libtiff.5.dylib (compatibility version 8.0.0, current version 8.0.0)
@executable_path/libs/liblzma.5.dylib (compatibility version 6.0.0, current version 6.4.0)
@executable_path/libs/libpng15.15.dylib (compatibility version 30.0.0, current version 30.0.0)
@executable_path/libs/libmng.1.dylib (compatibility version 2.0.0, current version 2.0.0)
@executable_path/libs/liblcms.1.dylib (compatibility version 2.0.0, current version 2.19.0)
@executable_path/libs/libjasper.1.dylib (compatibility version 2.0.0, current version 2.0.0)
@executable_path/libs/libjpeg.9.dylib (compatibility version 10.0.0, current version 10.0.0)
@executable_path/libs/libIlmImf.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libImath.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libHalf.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libIlmThread.6.dylib (compatibility version 7.0.0, current version 7.0.0)
@executable_path/libs/libIex.6.dylib (compatibility version 7.0.0, current version 7.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
@executable_path/libs/libz.1.dylib (compatibility version 1.0.0, current version 1.2.7)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)

Мне кажется, он все скопировал правильно. Но когда я запускаю свое приложение, я получаю то же исключение:

Unhandled Exception: System.DllNotFoundException: ./libs/libIL.1.dylib
Unhandled Exception: System.DllNotFoundException: @executable_path/libs/libIL.1.dylib
Unhandled Exception: System.DllNotFoundException: libs/libIL.1.dylib

Как видите, я пробовал 3 разных способа обращения к библиотеке, но всегда не находил ее.

Любая помощь будет принята с благодарностью, я уже несколько месяцев пытаюсь решить эту проблему.

ОБНОВЛЕНИЕ: если я укажу абсолютный путь к dylib, он найдет его, но затем пожалуется на зависимости:

Mono: DllImport error loading library 'dlopen(/Users/me/myapp/libs/libil.1.dylib, 9): Library not loaded: @executable_path/libs/libtiff.5.dylib
  Referenced from: /Users/me/myapp/libs/libil.1.dylib
  Reason: image not found'.

Мне кажется, что @executable_path не заменяется фактическим абсолютным исполняемым путем.


person Ilya Suzdalnitski    schedule 22.10.2013    source источник


Ответы (2)


Имейте в виду, что собственный исполняемый файл - это не myapp.exe, это монобинарный файл.

Попробуйте установить DYLD_LIBRARY_PATH, как указано в другом ответе (обратите внимание, что вы должны установить его перед выполнением приложения, поскольку загрузчик динамической библиотеки считывает это значение, когда приложение загружается в память, задолго до выполнения вашего метода Main).

person Rolf Bjarne Kvinge    schedule 23.10.2013
comment
Еще у меня была мысль, что @executable_path указывает на монобинарный файл. Однако следующий вопрос говорит, что исполняемый_путь отлично работает с моно-приложениями: stackoverflow.com/questions/14536843/ есть идеи? - person Ilya Suzdalnitski; 23.10.2013
comment
Я зависит от того, как вы создали и выполнили свое приложение. Если вы используете проект MonoMac / Xamarin.Mac, то этот ответ правильный (поскольку в процессе сборки будет создана настраиваемая программа запуска и привязана к нему libmono, а не сам монобинарный двоичный файл), в противном случае это не так. - person Rolf Bjarne Kvinge; 25.10.2013

Поскольку я на самом деле парень Linux и не знаю, каковы точные результаты с учетом динамических библиотек OSX, а также инструмента dylibbundler, я не могу сказать что-то наверняка. Однако в Linux поиск библиотек (среди прочего) осуществляется по путям, указанным в переменной LD_LIBRARY_PATH. Эквивалент OSX - DYLD_LIBRARY_PATH. Вы можете попробовать установить эту переменную в каталог, содержащий библиотеку.

person konrad.kruczynski    schedule 22.10.2013