概要
cx_Freeze 使って Python スクリプトを app にしていたら OpenCV の import に失敗していたので (暫定的な) 解決法をメモ.cx_Freeze の使い方とかはたくさんネットに上がっているのでこことか参照してください.
症状
環境:
- MacOS: 10.12.6
- Python: 3.5.2
- OpenCV: 3.1.0 (余談ですが MacOS で Python3.6 だと OpenCV3 入らない問題いつ解決されるんですかね)
簡単のために cv2.imshow()
するだけの main.py を作成.
import cv2
window_name = 'sample'
file_name = '/path/to/img'
img = cv2.imread(file_name)
cv2.imshow(window_name, img)
cv2.waitKey(5000)
cx_Freeze の build 用スクリプトはこんな感じで (ここから拝借).
import sys
from cx_Freeze import setup, Executable
build_exe_options = {"packages": ["os", 'sys', 'cv2']}
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup( name = "test",
version = "0.0",
description = "My GUI application!",
options = {"build_exe": build_exe_options},
executables = [Executable("main.py", base=base)])
build すると依存ライブラリのコピー中にこんなエラーが出ました.
$ python setup.py build
running build
running build_exe
...
copying mac64/libcilkrts.5.dylib -> build/exe.macosx-10.6-x86_64-3.5/libcilkrts.5.dylib
error: [Errno 2] No such file or directory: 'mac64/libcilkrts.5.dylib'
解法
他のライブラリはフルパスで指定しているのにこれだけ相対パスになってるからですね.brew で gcc 入れてるからかな〜とも思いましたけど普通に /usr/local/Cellar/gcc/
以下も読み行ってるしよく分からないですが,cx_Freeze のバグではって感じです (このへん).
圧倒的に脳筋な解法なんですけど,要するに libcilkrts.5.dylib
が見つからないだけなのでこれがあるところに mac64 って名前でシンボリックリンク貼ったら解決します.
$ find /usr/local/Cellar -name '*libcilkrts*'
/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libcilkrts.5.dylib
みたいに見つかると思うので,setup.py があるディレクトリで,
$ ln -s /usr/local/Cellar/gcc/7.1.0/lib/gcc/7/ mac64
するだけです.
これで build は通りますが,生成された main 実行すると実行時エラー吐きます.
ImportError: numpy.core.multiarray failed to import
OpenCV を使用するする際には numpy も packages に追加しましょう (Python で import cv2
するときはよしなにやってくれるんですがね).setup.py 中の
build_exe_options = {"packages": ["os", 'sys', 'cv2']}
を,
build_exe_options = {"packages": ["os", 'sys', 'numpy', 'cv2']}
とすれば無事描画できます.
以上です.cx_Freeze.setup() に /usr/local/Cellar/gcc/7.1.0/lib/gcc/7/
も読み行けよみたいなオプション与えられればそれで終わるんですけどよくわかりませんでした,どなたかご存知でしたら教えてください.