QuickIRを py2exeでWindowsのEXEファイルにする(1)
ただしpy2exeはPython3.4までにしか対応しておらず、Python3.5とそれ以降の場合は使用できません
0. 背景
QuickIR を cx_freeze で EXE化してみましたが、生成されたEXEファイル以外に多くのファイルが必要で、それらもEXEファイルと一緒の場所にコピーされるという事が分りました。cx_freeze は Pythonスクリプトを EXEファイル化すると言うよりも、一つのフォルダ配下に纏まった実行環境を作成するツールと言った方が的確かもしれませんね。もう少しスッキリとした実行環境にならないものかと色々調べてみましたが、どうも cx_freeze 単独では無理っぽいです。
そこで、py2exeという他の EXE化ツールも試してみることにしました。
1. Python3.4のインストール
py2exe は Python3.5 には対応していません。そこで、Python3.4 をインストールすることにしました。
QuickIRは Python3.5 の上で作成、動作確認していますが、Python3.5 の新規機能を使っているわけではないので、Python3.4 でも動作できるはずです。まぁ完全に動作検証をしたというわけではないので、Python3.5 の使用を推奨していますが・・・
Python3.4 の Windows版インストーラは、Python本家からダウンロードできます。Python3.4 の現時点での最終版は Ver.3.4.5 ですが、この版では何故か Windows用のインストーラが作成されていません。(ソースコードの配布のみ。)そこで、一つ前の Ver.3.4.4 のインストーラ(MSI)を使用することにしました。
使用しているOSに合わせて以下をダウンロードします。
- Windows x86-64 MSI installer (
"python-3.4.4.amd64.msi" : 64bit版)
- Windows x86 MSI installer (
"python-3.4.4.msi" : 32bit版)
インストール後、PATH環境変数を調整します。と言うのは、先に Python3.5 をインストールしてあった環境に後から Python3.4 をインストールすると、PATH環境変数には Python3.4 が先頭の方に指定されているかもしれないからです。すると Python3.4 の方が優先的に使用されてしまいますよね。
今回は EXE化の際にだけ Python3.4 を使い、普段は主に Python3.5 の方を使用したいので、PATH環境変数の順番を入れるような調整をしておいた方が良いだろうと思います。
ただ、複数バージョンのPythonをインストールして使い分けるのであれば、pyenv や仮想環境(virtualenv, venv)を使用することを考えた方が良いでしょう。これについては、また次の機会にでも勉強したいと思います。
2. py2exeのダウンロード&インストール
py2exe は Python2系用と Python3系用とでは配布場所が異なっています。py2exe本家からは Python2系用の py2exe へのリンクしか張られていません。Python3系用の py2exe は以下のPyPIリポジトリからダウンロードします。
PyPI/py2exe:<https://pypi.python.org/pypi/py2exe>
現時点での最新版は Ver.0.9.2.2です。
- py2exe-0.9.2.2-py33.py34-none-any.whl (Python Wheel)
- py2exe-0.9.2.2.win-amd64.exe (64bit版)
- py2exe-0.9.2.2.win32.exe (32bit版)
インストールはダウンロードした.exeファイルを実行し、後はインストーラの指示に従ってインストールしていきます。その際、インストール先ディレクトリ(Pythonのバージョン)に注意が必要です。py2exeは Python3.4 までしか動作しないため、間違って Python3.5 にインストールしないように気をつけましょう。
または、Python Wheelをダウンロードし、Python3.4のpipコマンドを使用して以下のようにインストールしても良いでしょう。(こちらの方が間違えにくいかもしれません。)
C:¥> pip3.4 install py2exe-0.9.2.2-py33.py34-none-any.whl
|
3. サンプルプログラムを用意する
cx_freeze のときと同じように、先ずは簡単なサンプルプログラムから試してみます。サンプルプログラムは cx_freeze のときと同じもの"main.py" を用意しました。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
def main():
print('Hello World!')
if __name__ == '__main__':
main()
4. setupスクリプトを作成する
py2app や cx_freeze と同様、py2exe も setupスクリプトを作成してEXE化します。最もシンプルな setupスクリプトは以下のようになります。
from distutils.core import setup
import py2exe
setup(console=['main.py'])
5. サンプルプログラムをEXE化する
サンプルプログラムを py2exe で EXE化するには、コマンドプロンプトを開いて以下のように実行します。
C:¥> C:¥Python34¥python setup.py py2exe
running py2exe
1 missing Modules
------------------
? readline imported from cmd, code, pdb
Building 'dist¥main.exe'.
Building shared code archive 'dist¥library.zip'
〜略〜
|
見つからないモジュールがあると言われましたが、これは気にしなくても良いようです。EXE化が終了すると"dist" フォルダが作られ、その配下にEXEファイル"main.exe" が出来ていました。これを実行してみます。
C:¥> dist¥main.exe
Hello World!
|
おぉ、ちゃんと実行できました!cx_freezeのように__name__ が'__main__' ではない別の名前に変わってしまうようなことはないようですね。
"dist" フォルダ内を見てみると、こんなに短いプログラムなのに cx_freeze と同じように"main.exe" だけでなく"*.dll" や"*.pyd" 等、様々なファイルが沢山あります。でも、py2exeには、これらのファイルを纏めてくれるオプションがあるらしいです。この機能を使用するため、setupスクリプトを以下のように修正します。
from distutils.core import setup
import py2exe
option = {
'bundle_files': 2
}
setup(
options={
'py2exe': option
},
console=['main.py']
)
すると、"dist" フォルダ配下に作られるファイルは、"main.exe" 以外に"python34.dll", "library.zip" の計3つのファイルだけになりました。
更にbundle_files オプションを 1にすると、"python34.dll" も無くなり、"main.exe" と"library.zip" の 2つだけになりました。どの場合でも"main.exe" は正常に実行できます。
bundl_files オプションの意味は、
- 3 :
- シンプルな方法。実行に必要なファイルが
"dist" サブディレクトリ配下に作成される。
- 2 :
- 全ての Python拡張がzipアーカイブファイル内に含められる。それらは特別なプログラムコードによって、実行時にファイルシステム上に解凍されることなく読み込まれる。
- 1 :
- Pythonの.dllファイルもzipアーカーブファイル内にパックされる。
- 0 :
- 単一の実行可能ファイル(.exe)が作成される。
ということですが、自分の環境では 0を指定しても 1の場合と変わらず"main.exe" と"library.zip" の
2つファイルが作成されました。(単一の EXEファイルを作成したい場合は、bundle_files に 0 を指定するのに加えて、後述のzipfile=None も指定する必要があるようです。)bundle_files オプションは 1か 2を使うのが良さげですね。
|