Связывание с динамической библиотекой на Mac с полным путем
Я связываю библиотеку расширений (Python), в которую встроен механизм Matlab со следующей командой (сгенерированной с помощью cmake)
c++ -mmacosx-version-min=10.6 -bundle -headerpad_max_install_names -o library.so library.o /Applications/MATLAB_R2009b.app/bin/maci64/libeng.dylib /Applications/MATLAB_R2009b.app/bin/maci64/libmx.dylib -framework Python
в результате чего
$ otool -L library.so
library.so:
@loader_path/libeng.dylib (compatibility version 0.0.0, current version 0.0.0)
@loader_path/libmx.dylib (compatibility version 0.0.0, current version 0.0.0)
/System/Library/Frameworks/Python.framework/Versions/2.6/Python (compatibility version 2.6.0, current version 2.6.1)
/opt/local/lib/gcc44/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.13.0)
/opt/local/lib/gcc44/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)
Однако, когда я пытаюсь использовать библиотеку, я получаю сообщение об ошибке:
ImportError: dlopen(./library.so, 2): Library not loaded: @loader_path/libmex.dylib
Referenced from: ./library.so
Reason: image not found
Я считаю, что проблема связана с тем фактом, что компоновщик включает в себя файлы dylib matlab в форме @loader_path/libeng.dylib
вместо того, чтобы использовать полный путь, хотя я даю полный путь к g++
. Как заставить компоновщика использовать полный путь?
Я знаю, что одним из решений является использование
export DYLD_LIBRARY_PATH=/Applications/MATLAB_R2009b.app/bin/maci64:$DYLD_LIBRARY_PATH
где находятся эти файлы библиотеки, но я хотел бы избежать этого, поскольку это вызывает некоторые другие проблемы.
Ответы
Ответ 1
Вручную изменить файлы с помощью install_name_tool
install_name_tool -change "@loader_path/libeng.dylib" "/Applications/MATLAB_R2009b.app/bin/maci64/libeng.dylib" library.so
install_name_tool -change "@loader_path/libmx.dylib" "/Applications/MATLAB_R2009b.app/bin/maci64/libmx.dylib" library.so
Я мог бы использовать это как временное исправление, но мне интересно, нет ли лучшего решения, где компоновщику задан параметр для использования полных путей.
Ответ 2
Обратите внимание, что некоторые проблемы с DYLD_LIBRARY_PATH
можно предотвратить, используя вместо этого DYLD_FALLBACK_LIBRARY_PATH
. Это будет использоваться, только если lib не может быть найден в пути по умолчанию.
Ответ 3
Посмотрите на параметр -rpath на команду ld, чтобы управлять этим. Вы также можете быть заинтересованы в содержании https://github.com/bimargulies/jni-origin-testbed, что является демонстрацией некоторых соответствующих технологий.
Критический метод здесь:
install_name_tool -change libsl2.so "@loader_path/libsl2.so" libsl1.so
Ответ 4
Вы также можете использовать символическую ссылку!