DYLD_LIBRARY_PATH-trick 自 Mac OS 10.11 El Capitan 的替代方案,具有系统完整性保护
Alternative for the DYLD_LIBRARY_PATH-trick since Mac OS 10.11 El Capitan with System Integrity Protection
这是我的:
- Mac OS 10.11 埃尔卡皮坦
- python 2.7.12,从
/Library/Frameworks/Python.framework/
下的 python.org 安装
- PyCharm 2016.2.3
- vtk 7.1.0
这是我的做法:
在本地构建一个 python 模块。就我而言,这是 vtk。有关摘要,请参阅我用来配置 vtk 的 CMake 调用。
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 软件包安装在 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()
如果我尝试在 PyCharm 的 python 控制台中导入 vtk,我会收到以下错误:
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
到目前为止,我了解到问题是由 System Integrity Protection (SIP) that has been introduced in El Capitan. One of the effects is that child processes only have restricted access 到其他资源引起的,并且很可能 PyCharm 作为单独的进程执行 python。
我也明白 python 无法导入 vtk,因为它找不到 python 模块链接到的动态库。我可以通过两种方式验证这一点:
DYLD_LIBRARY_PATH
为空。这是因为 python 在 PyCharm 中作为子进程运行: os.getenv('DYLD_LIBRARY_PATH')
returns None
.
- 当我将所有库从
/opt/dev/versions/vtk/vtk-7.1.0-shared/lib/
复制到当前工作目录时,我可以导入模块
现在的问题:显然,DYLD_LIBRARY_PATH
不能在子进程中使用,因此自 El Capitan 以来根本不应该再使用。那么,如何正确替换这个在 MacOS 10.11 之前运行良好的 "linkage hack"?有没有办法仍然使用DYLD_LIBRARY_PATH
?
禁用 SIP 不是一个选项。显然,将 dylib 复制到当前工作目录会有所帮助,但这对我来说不可行。然而,将库放在(vtk 的)站点包位置并没有帮助。
我很确定很多人一直依赖 DYLD_LIBRARY_PATH
-hack,现在正在与 SIP 的后果作斗争 - 这就是为什么我认为社区可能会从这个相当冗长的问题中受益。
经过长时间的斗争,我终于解决了最后一点问题。
通过为安装的二进制文件 的 RPATH Run-Path dependent Libraries 设置一个 固定值,我的链接问题就消失了。
实现这一点有不同的可能性。我想一种选择是使用 install_name_tool
。对我来说,最简单的方法是使用适当的 CMake 标志构建 vtk。在这里,我更新了对 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"
阅读 here 有关 CMake 的 rpath 处理的更多信息。请注意,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)
这是我的:
- Mac OS 10.11 埃尔卡皮坦
- python 2.7.12,从
/Library/Frameworks/Python.framework/
下的 python.org 安装
- PyCharm 2016.2.3
- vtk 7.1.0
这是我的做法:
在本地构建一个 python 模块。就我而言,这是 vtk。有关摘要,请参阅我用来配置 vtk 的 CMake 调用。
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 软件包安装在 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()
如果我尝试在 PyCharm 的 python 控制台中导入 vtk,我会收到以下错误:
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
到目前为止,我了解到问题是由 System Integrity Protection (SIP) that has been introduced in El Capitan. One of the effects is that child processes only have restricted access 到其他资源引起的,并且很可能 PyCharm 作为单独的进程执行 python。
我也明白 python 无法导入 vtk,因为它找不到 python 模块链接到的动态库。我可以通过两种方式验证这一点:
DYLD_LIBRARY_PATH
为空。这是因为 python 在 PyCharm 中作为子进程运行:os.getenv('DYLD_LIBRARY_PATH')
returnsNone
.- 当我将所有库从
/opt/dev/versions/vtk/vtk-7.1.0-shared/lib/
复制到当前工作目录时,我可以导入模块
现在的问题:显然,DYLD_LIBRARY_PATH
不能在子进程中使用,因此自 El Capitan 以来根本不应该再使用。那么,如何正确替换这个在 MacOS 10.11 之前运行良好的 "linkage hack"?有没有办法仍然使用DYLD_LIBRARY_PATH
?
禁用 SIP 不是一个选项。显然,将 dylib 复制到当前工作目录会有所帮助,但这对我来说不可行。然而,将库放在(vtk 的)站点包位置并没有帮助。
我很确定很多人一直依赖 DYLD_LIBRARY_PATH
-hack,现在正在与 SIP 的后果作斗争 - 这就是为什么我认为社区可能会从这个相当冗长的问题中受益。
经过长时间的斗争,我终于解决了最后一点问题。
通过为安装的二进制文件 的 RPATH Run-Path dependent Libraries 设置一个 固定值,我的链接问题就消失了。
实现这一点有不同的可能性。我想一种选择是使用 install_name_tool
。对我来说,最简单的方法是使用适当的 CMake 标志构建 vtk。在这里,我更新了对 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"
阅读 here 有关 CMake 的 rpath 处理的更多信息。请注意,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)