homebrew上のpythonを利用している状況で
$ brew install --python --qt vtk
すると
import vtk
# => Fatal Python error: PyThreadState_Get: no current thread. Abort trap: 6
となる。
これは homebrew-scienceのissueに上がっている通り brew installで降ってくる.dylibや.soの中にOSXシステム側のPythonのPathが埋め込まれているためである。
試しにotool -Lしてみると (otoolとinstall_name_toolの利用にはXcodeのCommand Line Toolsが必要)
$ otool -L /usr/local/Cellar/vtk/7.0.0_3/lib/libvtkCommonCorePython27D-7.0.dylib
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtkCommonCorePython27D-7.0.dylib:
/usr/local/opt/vtk/lib/libvtkCommonCorePython27D-7.0.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtkWrappingPython27Core-7.0.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtkCommonCore-7.0.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.10)
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtksys-7.0.1.dylib (compatibility version 1.0.0, current version 1.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)
の通り、/System/Library/Frameworks/Python.framework/Versions/2.7/Python へのリンクが埋め込まれている。
これを修正するには、install_name_toolを用いて
$ sudo install_name_tool -change /System/Library/Frameworks/Python.framework/Versions/2.7/Python /usr/local/Cellar/python/2.7.11/Frameworks/Python /usr/local/Cellar/vtk/7.0.0_3/lib/libvtkCommonCorePython27D-7.0.dylib
と実行すればいい。(書き換えにはsudoが必要)
確認してみると、
$ otool -L /usr/local/Cellar/vtk/7.0.0_3/lib/libvtkCommonCorePython27D-7.0.dylib
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtkCommonCorePython27D-7.0.dylib:
/usr/local/opt/vtk/lib/libvtkCommonCorePython27D-7.0.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtkWrappingPython27Core-7.0.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtkCommonCore-7.0.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/local/Cellar/python/2.7.11/Frameworks/Python (compatibility version 2.7.0, current version 2.7.10)
/usr/local/Cellar/vtk/7.0.0_3/lib/libvtksys-7.0.1.dylib (compatibility version 1.0.0, current version 1.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)
となって、リンクをbrew pythonのpathに修正できていることが分かる。
変更する必要があるのはこれ1つではなく、/usr/local/Cellar/vtk/{version}/lib/*.dylib に加えて/usr/local/lib/python2.7/site-packages/vtk/vtk*.so も修正する必要があるため、以下のようなスクリプトを書いた。
#!/bin/sh
SystemPythonPath=/System/Library/Frameworks/Python.framework/Versions/2.7/Python # 利用しているpythonのversionに合わせて変更
BrewPythonPath=/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Python # 利用しているpythonのversionに合わせて変更
function replace_system_python() {
echo " -- before -- "
otool -L $1
install_name_tool -change ${SystemPythonPath} ${BrewPythonPath} $1
echo " -- after -- "
otool -L $1
}
for file in `find /usr/local/lib/python2.7/site-packages/vtk/vtk*.so`;do
replace_system_python ${file}
done
for file in `find /usr/local/Cellar/vtk/7.0.0_3/lib/*.dylib`;do
replace_system_python ${file}
done
全てのdylib, soファイルに対して(Pythonパスが含まれていないものに対しても) install_name_tool -changeを実行するので行儀が悪いが、matchしなければ特に置き換えられることもないので問題ないはず。
$ sudo ./vtk_fix_pythonpath.sh
した後、importできるか確認すると、
import vtk
# => No error!!!!!!
問題なくimportできた。
home-scienceのissueを読むと、リンク埋め込みなしのvtkをビルドできるパッチを書いている方もいるようだが、本体側の修正はまだみたい?