Альтернатива для трюка 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)
Другие вопросы по тегам