LoginSignup
1
2

More than 5 years have passed since last update.

brew pythonでvtkをimportする

Posted at

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 も修正する必要があるため、以下のようなスクリプトを書いた。

vtk_fix_pythonpath.sh
#!/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をビルドできるパッチを書いている方もいるようだが、本体側の修正はまだみたい?

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2