pygame2exeを使ってみた

py2exeに挑戦

Pythonで書いたスクリプトはPythonの実行環境があれば、そのまま実行できるがたいていのパソコンにPythonの実行環境は入っていないため、Pythonで書いたプログラムを配布するためには少し細工してやる必要があります。*1


py2exeというツールを使うとPythonで書いたスクリプトをWindows上で動く実行ファイルにすることができます。py2exeを使うためにはまずpy2exeパッケージをインストールする必要がありますので、以下のサイトから落としてきましょう。
FrontPage - py2exe.org


次にsetup.pyという設定ファイルを書く必要があります。setupスクリプトの書き方はPythonドキュメントのdistutilsの中に書いてあります。他の人のをコピペして使ったほうが手っ取り早いのでPygame入門のサイトにあるものを使ってみました。
2 setup スクリプトを書く

C:\Programming\Python\Typing>python pygame2exe.py
Input script directry:./
Setup directry:C:\Programming\Python\Typing
Input starting script:typing.py

とりあえず実行ファイルにしたいスクリプト群の起動スクリプトがあるフォルダにpygame2exe.pyを置いて実行すると良いでしょう。そして、起動スクリプトがあるディレクトリと起動スクリプト名を入力してやるだけです。自分の作ったパッケージもきちんと実行ファイルに含んでくれました。ちなみに以下のようなエラーが出るときがありましたが、何回か同じようにpygame2exe.pyを実行するとうまくいきました。しかし、Errorと出ているのに「この操作を正しく終了しました」とはわかりにくい表現ですね。

RuntimeError: BeginUpdateResource: この操作を正しく終了しました。

完了するとbuildフォルダとdistフォルダが作成されます。distフォルダに必要なものが全て入っているのでこのフォルダごと配布すると良いでしょう。それでは早速distフォルダにある実行ファイルを実行してみましょう。


そして発生するエラー。
実行時に例外が発生するとその旨を知らせてくれるメッセージボックスが出てきて、エラーの詳細がlogファイルに記録されます。ちなみにこんなのが出てきました。もちろん普通にpython typing.pyとして実行したときには発生しなかったエラーです。

Traceback (most recent call last):
  File "typing.py", line 162, in ?
  File "typing.py", line 148, in main
  File "typing.py", line 101, in __init__
  File "typing.py", line 127, in SetScreen
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 0: ordinal not in range(128)

該当箇所にはこのような記述をしていました。system['caption']にはUnicode文字列が格納してあるので、とりあえずUnicode関連の問題であることは推測できますがそれ以上はわかりません。

pygame.display.set_caption(system['caption'])

検索してみると以下のようにutf-8エンコードしなさいと書いてありました。

since you're getting a UnicodeEncodeError, the "note" object is probably a Unicode string, not a "binary code". to write Unicode strings to a file, you need to decide what encoding to use, and encode the string on the way out. e.g.
nodeFileObj.write(note.encode("utf-8"))

この文章で言いたいことはわかりますが、なぜ実行ファイルにしたときにしかこのエラーは発生しないのかはまだわかりません。とりあえず今は素直にencodeすることにします。

pygame.display.set_caption(system['caption'].encode('sjis'))

これでもう一度やってみるとようやく上手くいきました。やれやれです。

py2exeに含まれるexeとdllをUPX圧縮

別にUPXを試してみるために実行ファイルを作成したわけではありませんがせっかくなので試してみたいと思います。py2exeを使ったときにコピーされるdllや実行ファイルのサイズなどはsetup.pyの書き方で大きく変わりますが、上記のpygame2exe.pyを使ったときには以下のようなdllがコピーされました。それぞれのサイズと圧縮率は以下の通り。

ファイル名 圧縮前サイズ 圧縮後サイズ 圧縮率
msvcr71.dll 340KB 162KB 47.65%
python24.dll 1828KB 778KB 42.56&
SDL.dll 284KB 117KB 41.20%
SDL_image.dll 229KB 116KB 50.44%
SDL_mixer.dll 408KB 190KB 46.57%
SDL_ttf.dll 396KB 184KB 46.52%
w9xpopen.exe 5KB 4KB 77.78%
typing.exe 1657KB 1613KB 97.32%
合計 5147KB 3164KB 61.47%


結構小さくなるもんですね。とは言っても今どき5MBと3MBにどれほどの違いがあるのかというと非常に微妙なところです。実行時のメモリ消費はUPX圧縮する前とした後では後の方が1MBほど増えています。また、普通にPythonコマンドで起動したときと比べると4MBほど増えています。CPU使用率ではどちらもほとんど変化ありませんでした。


実行ファイルにしたときにメモリの使用量が増えるのは、やはりプログラムをまるごとメモリ上に展開しないといけないからなのでしょうか。とりあえず数MB程度の増加であれば問題ないので、これで行くことにしましょう。

*1:なぜかIBMのパソコンには最初からPythonが入っていますが・・・