cx_Freeze で Tkinter を使った Python スクリプトを実行ファイル化する際に必要な設定
必須手順
ここの手順は全て行わないとビルドが通らない。
LIBRARY 系の環境変数を設定する
cx_Freeze の setup を走らせる前に以下の環境変数に値を入れておく。
rem Set Tkinter pathes of your environment. set TCL_LIBRARY=D:\bin1\Python361\tcl\tcl8.6 set TK_LIBRARY=D:\bin1\Python361\tcl\tk8.6
DLL のパスを build_exe の include_files オプションに指定する
cx_Freeze の setup を走らせる前に、build_exe の include_files オプションに Tkinter の DLL パスを入れておく。
やり方は色々あるが、下記は環境変数経由で入れる方法。
手順は2つ。1つ目は、環境変数に DLL パスを入れておく。
rem Set Tkinter DLLs path od your environment. set TCL_DLL_PATH=D:\bin1\Python361\DLLs\tcl86t.dll set TK_DLL_PATH=D:\bin1\Python361\DLLs\tk86t.dll
2つ目は、ビルドスクリプト側で以下のようにして読み込ませる。
include_files = [ os.environ['TCL_DLL_PATH'], os.environ['TK_DLL_PATH'], ] options = { 'build_exe': { 'include_files' : include_files, }, }
推奨手順
できればやっておきたいもの。
不要なファイルを削除する
Tkinter を使った Python スクリをビルドすると、生成物のファイルサイズやらファイル数やらが結構えらいことになる。
- ファイルサイズは 20MB くらい
- ファイル数は 1000 以上
もう少し軽くしたいのが本音だが、cx_Freeze のビルドオプション等で省く手段は無さそう。できそうなことと言えば 生成されたファイルのうち、不要なものを削除する くらい。
もちろん必要なモノを削除したら実行ファイルが動かなくなる(おそらく以下のような ImportError が出るはず)ので、
Traceback (most recent call last): ... import _tkinter # If this fails your Python may not be configured for Tk ImportError: DLL load failed: 指定されたモジュールが見つかりません。
手順としては以下のようにすると良いだろう。
- 削除したいフォルダやファイルをリネームする
- 例:
tzdata
→_tzdata
- 例:
- 実行ファイルを起動して、動作確認してみる
- エラーが出た → 必須なので消しちゃダメ。リネームを元に戻す
- エラーが出ない → 消してもok。消す
ちなみに私は以下のようなバッチファイルを書いた。tk\demos とか tcl\tzdata やらが削除対象。
@echo off setlocal set DIST_ROOT_NAME=dist_incl set DIST_ROOT_PATH=%~dp0dist_incl set REMOVE_FOLDER_CMD=rmdir /s /q %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tk\demos %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tk\images %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tk\msgs %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tcl\encoding %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tcl\http1.0 %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tcl\msgs %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tcl\opt0.4 %REMOVE_FOLDER_CMD% %DIST_ROOT_PATH%\tcl\tzdata
これで大体以下のように推移した。
- ファイルサイズは
20MBくらい→ 16.5KB - ファイル数は
1000以上→ 275
……まだまだ。
結論: 面倒くさい。