音楽プログラミングの超入門(仮)

Python / 音楽情報処理 初心者が、初心者にも分かるような記事を書きたい。

Python スクリプトのスタンドアロン化【bbfreeze】

Pitch shift

photo by Ryan Johnson

関連記事

Pythonスクリプトスタンドアロン

上記の記事で、Pythonスクリプトcx_Freeze というライブラリを用いてスタンドアロン化する方法を紹介しました。(「スタンドアロン化」については上記記事参照)

最近、cx_Freeze よりも bbfreeze というライブラリを用いた方が楽にスタンドアロン化できることに気づいたので、その方法を紹介します。

bbfreeze の利点

bbfreeze · PyPI

cx_Freeze と比較した bbfreeze の利点は主に以下の2点です。

  1. setup.py ファイルを書くのが簡単
  2. フリーズされたバイナリファイルが軽い(比較的)

cx_Freeze では setup.py ファイルに使用するライブラリや依存するバイナリファイルを手書きで指定してやる必要がありましたが、bbfreeze ではそれらは必要なく自動でかき集めてくれるようです。

bbfreeze の使い方

bbfreeze の使い方は cx_Freeze とほぼ同じで、

  1. 好きなPythonコードを書く
  2. setup.py を書く
  3. " python setup.py" を実行する

みたいな感じです。
例えば、以下のコードをフリーズすることを考えます。

sample.py

from scipy import dot, rand
print dot(rand(10, 1), rand(1, 10))

setup.py は次のように書けます。

setup.py

from bbfreeze import Freezer

f = Freezer("./build/",includes=())
f.addScript("sample.py" , True)

f()

これだけです。フリーズされたバイナリファイルの置き場所とフリーズするメインスクリプトを指定しています。

python setup.py

を実行することで、"./build/sample" としてスタンドアロン化することができます。

bbfreeze の注意点

glibc のバージョン

bbfreeze の公式サイトにさりげなく次のように書かれています。

Linux Notes
The glibc version on the system used for freezing will generally be the minimum glibc version required to run the binaries.

https://pypi.python.org/pypi/bbfreeze

フリーズしたバイナリファイルを実行する環境の glibc のバージョンが、フリーズする環境の glibc 以上である必要があります。よって linux ディストリビューションスタンドアロン化を行う場合は、できるだけ glibc のバージョンが低い OS で行うべきです。
例えば、"Ubuntu 12.04" でフリーズしたバイナリファイルは "Ubuntu 14.04" で実行することができますが、その逆は不可となります。

bbfreeze で対処すべき点

上で扱ったコードのようにあまりライブラリを使わないシンプルなものは上手くフリーズできる場合が多いですが、使用するライブラリによってフリーズが失敗する場合があります。それらを回避するための方法を紹介しておきます。

bbfreeze/recipe.py の変更

bbfreeze ライブラリ内の、recipe.py というファイル内に "mf.import_hook("matplotlib.numerix.random_array", m)" という行が存在します。しかし、最新の matplotlib では numerix というモジュールは存在しないため、場合によってはこの行でエラーがでてしまいます。これに対処するには、この行をコメントアウトすれば十分です。

もしコメントアウトに伴って何かエラーが発生した場合は...頑張ってください。

bbfreeze/freezer.py の変更

bbfreeze ライブラリ内の、freeze.py というファイル内に "replace_paths_in_code()" という関数があります。この関数は返り値の一つとして "newname" という文字列を持ちますが、これが文字コードエラーを引き起こす場合がありました。以下のように変更してしまいましょう。

newname -> str(newname)

足りない関数の補填

bbfreeze は使用するライブラリ関数などを自動でかき集めてフリーズしてくれますが、たまに取りこぼしがあるようです。例えば、自分の場合はフリーズしたバイナリファイルを実行した際、以下の関数がインポートできないとエラーがでたため、元のメインスクリプトに明示的にインポート文を書き足すことで対処できました。

import scipy.special._ufunc_cxx
import scipy.sparse.csgraph._validation