Альтернатива трюку DYLD_LIBRARY_PATH, начиная с Mac OS 10.11 El Capitan с защитой целостности системы

Вот что у меня есть:

  • Mac OS 10.11 Эль-Капитан
  • 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), которая была введен в Эль-Капитан. Одним из эффектов является то, что дочерние процессы имеют только ограничения. доступ к другим ресурсам, и, скорее всего, PyCharm выполняет python как отдельный процесс.

Я также понимаю, что python не может импортировать vtk, потому что он не может найти dylib, на которые ссылается модуль 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 не вариант. Судя по всему, это помогает скопировать дилибы в текущий рабочий каталог, но для меня это неосуществимо. Однако размещение библиотек в местоположении пакета сайта (vtk) не помогает.

Я почти уверен, что многие люди полагались на DYLD_LIBRARY_PATH-hack и теперь борются с последствиями SIP - вот почему я подумал, что сообщество может извлечь выгоду из этого довольно длинного вопроса.


person normanius    schedule 07.10.2016    source источник
comment
DYLD_LIBRARY_PATH - это не взлом. Это переменная среды, предоставленная для определенной цели. Он работает так же, как и раньше в El Capitan - кроме для защищенных системных процессов . Поведение, описанное выше в PyCharm, вызвано тем, что MacOS использует разные среды для приложений оболочки и графического интерфейса. Вы пишете среду графического интерфейса, используя / usr / bin / defaults. Например: defaults write ~/.MacOSX/environment DYLD_LIBRARY_PATH $DYLD_LIBRARY_PATH   -  person Dave    schedule 02.02.2019


Ответы (1)


После долгой борьбы я смог решить последнюю часть своей проблемы.

Установив фиксированное значение для RPATH Библиотеки, зависящие от пути выполнения установленных двоичных файлов, мои проблемы с компоновкой исчезли.

Для этого есть разные возможности. Думаю, один из вариантов - использовать 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)
person normanius    schedule 10.10.2016
comment
Связанные сообщения в списке рассылки пользователей vtk, которые также могут быть интересны: (сообщение 1) и (Сообщение 2) - person normanius; 11.10.2016
comment
Прочтите, возможно, также этот разъясняющий ответ по этой теме. - person normanius; 08.12.2017