Альтернатива для трюка DYLD_LIBRARY_PATH, начиная с Mac OS 10.11 El Capitan с защитой целостности системы
Вот что у меня есть:
- Mac OS 10.11 El Capitan
- python 2.7.12, установленный с python.org под
/Library/Frameworks/Python.framework/
- PyCharm 2016.2.3
- vtk 7.1.0
Вот что я делаю:
Создайте модуль Python локально. В моем случае это vtk. Для краткого изложения смотрите вызов CMake, с которым я настраиваю vtk.
cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release -DVTK_WRAP_PYTHON=ON -DBUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX="/opt/dev/versions/vtk/vtk-7.1.0-shared" -DPYTHON_INCLUDE_DIR="/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/" -DPYTHON_LIBRARY="/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib"
Установите пакет python в месте, где он может его найти. В моем случае это
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages
Обратите внимание, что я обязан продлитьDYLD_LIBRARY_PATH
по месту нахождения библиотеки:/opt/dev/versions/vtk/vtk-7.1.0-shared/lib/
,Если я запускаю python из терминала, я могу успешно импортировать vtk.
import vtk v = vtk.vtkVersion() print v.GetVTKVersion()
Если я пытаюсь импортировать vtk в Python-консоль PyCharm, я получаю следующую ошибку:
Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2881, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-2-b7e11aadda62>", line 1, in <module> import vtk File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import module = self._system_import(name, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/vtk/__init__.py", line 41, in <module> from .vtkCommonCore import * File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import module = self._system_import(name, *args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/vtk/vtkCommonCore.py", line 9, in <module> from vtkCommonCorePython import * File "/Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import module = self._system_import(name, *args, **kwargs) ImportError: No module named vtkCommonCorePython
Теперь я понимаю, что проблема вызвана защитой целостности системы (SIP), которая была введена в El Capitan. Одним из эффектов является то, что дочерние процессы имеют ограниченный доступ только к другим ресурсам, и, скорее всего, PyCharm выполняет Python как отдельный процесс.
Я также понимаю, что python не может импортировать vtk, потому что он не может найти dylibs, на которые ссылается модуль python. Я могу проверить это двумя способами:
DYLD_LIBRARY_PATH
пустой. Это потому, что python запускается как дочерний процесс в PyCharm:os.getenv('DYLD_LIBRARY_PATH')
возвращаетсяNone
,- Когда я копирую все библиотеки из
/opt/dev/versions/vtk/vtk-7.1.0-shared/lib/
в текущий рабочий каталог, я могу импортировать модуль
Теперь вопрос: видимо, DYLD_LIBRARY_PATH
не может использоваться в дочерних процессах и, следовательно, больше не должен использоваться со времен El Capitan. Итак, как правильно заменить этот "хак для связи", который прекрасно работал до MacOS 10.11.? Есть ли способ еще использовать DYLD_LIBRARY_PATH
?
Отключение SIP не вариант. По-видимому, это помогает копировать dylibs в текущий рабочий каталог, но это неосуществимо для меня. Однако размещение библиотек в расположении пакета сайта (из vtk) не помогает.
Я уверен, что многие люди полагались на DYLD_LIBRARY_PATH
взломать, а теперь бороться с последствиями SIP - вот почему я подумал, что сообщество может извлечь пользу из этого довольно длинного вопроса.
1 ответ
После долгой борьбы я смог решить последнюю часть своей проблемы.
Установив фиксированное значение для зависимых от RPATH Run-Path библиотек установленных двоичных файлов, мои проблемы с компоновкой исчезли.
Для этого есть разные возможности. Я думаю, что один из вариантов заключается в использовании install_name_tool
, Для меня проще всего было собрать vtk с соответствующими флагами CMake. Здесь мой обновленный звонок cmake
, где CMAKE_MACOSX_RPATH
а также CMAKE_INSTALL_RPATH
сделать разницу:
cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release \
-DVTK_WRAP_PYTHON=ON \
-DBUILD_EXAMPLES=OFF \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_TESTING=OFF \
-DCMAKE_INSTALL_PREFIX="/opt/dev/versions/vtk/vtk-7.1.0-shared" \
-DCMAKE_MACOSX_RPATH=ON \
-DCMAKE_INSTALL_RPATH="/opt/dev/versions/vtk/vtk-7.1.0-shared/lib" \
-DPYTHON_INCLUDE_DIR="/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/" \
-DPYTHON_LIBRARY="/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib"
Узнайте больше об обработке rpath в CMake. Обратите внимание, что otool -L vtkCommonCorePython.so
(для примера) все равно напишу @rpath
на выходе, но значение по-прежнему является фиксированным.
@rpath/libvtkCommonCorePython27D-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libvtkWrappingPython27Core-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.0)
@rpath/libvtksys-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libvtkCommonCore-7.1.1.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)