この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)
『PyInstaller』は、『Python』で書いたプログラムを1つにパッケージして、exe化するツールです。
PyInstaller
https://pyinstaller.org/
開発したゲームは、exeファイルにして配布したいです。『Python』のプロジェクトをexe化するツールはいくつかあるのですが、ここでは情報が多く、定番の『PyInstaller』を使います。
『PyInstaller』をグローバル環境に導入する際はpip install pyinstaller
コマンドを使います。今回は、仮想環境に導入して使いたいので、CLI環境でプロジェクトのディレクトリに移動して、次のコマンドを実行します。
.venv\Scripts\activatepip install pyinstallerdeactivate
インストールは3分程度かかります。「.venv」ディレクトリにファイルが導入されます。「.venv」ディレクトリのサイズは51.2MBになりました。前の操作では39.0MBだったので、12.2MBほど増えました。
仮想環境内に正しくインストールできたか確認しましょう。次のコマンドを実行します。
.venv\Scripts\activatepip listdeactivate
表示されるパッケージ一覧に「pyinstaller」が含まれていれば正しくインストールできています。
『PyInstaller』を使う上では、注意すべき点がいくつかあります。
1つ目の注意すべき点は、仮想環境についてです。仮想環境で開発したプログラムを正しくexe化するには、『PyInstaller』も仮想環境にインストールする必要があります。そして、exe化を仮想環境内でおこなう必要があります。
2つ目の注意すべき点は、出力される場所です。exe化をおこなうと「dist」ディレクトリ内に出力されます。ルート直下の「main.py」をexe化したときは、次のようなファイル構成になります。
「main.py」から、相対パスでファイルを読み込んでいる場合は、出力したexeの場所を次のように移動する必要があります。
3つ目の注意すべき点は__file__
のあつかいです。『Python』では、現在実行しているプログラムのファイルのパスが__file__
に入っています。3.9以降の環境では、この__file__
には絶対パスが入っています。
『PyInstaller』でexe化したプログラムでは、この__file__
のパスを使うことは避けた方がよいです。『PyInstaller』で作ったexeファイルを実行すると、exeファイルとは別の場所のパスになります。
print(__file__)
で出力するとC:\Users\<ユーザー名>\AppData\Local\Temp\_<一時的な文字列>\main.py
と出力されます。この場所に実行に必要なDLLなどが展開されています(「main.py」は展開されていません)。
この問題の回避方法は、次々節で解説します。
次のコマンドを実行します。
.venv\Scripts\activatepyinstaller main.py --onefile --noconsoledeactivate
コマンドを実行すると、「build」ディレクトリと「dist」ディレクトリができます。「build」ディレクトリはビルドに利用されたファイルが入っているので不要です。「dist」ディレクトリ内に「main.exe」が作成されます。実行ファイルの名前は、プログラムのエントリー ポイントのファイル名です。
デバッグ時は--noconsole
を消すとよいです。CLI環境のウィンドウが表示され、標準出力の内容を確かめられます。
アイコンを付けたいときは、コマンドに--icon=src/icon.ico
のように相対パスでアイコン ファイルの場所を書きます。
開発中の「main.py」の絶対パスは__file__
で得られます。exe化したときの「main.exe」の絶対パスはsys.executable
で得られます。exe化の判定はgetattr(sys, 'frozen', False)
がTrue
を返すかでおこなえます。
開発時と出力時のディレクトリの構成例を示します。
次にプログラムを示します。exe化の判定をおこない、パスを調整して、「root」をCWD(カレント ワーキング ディレクトリ)にして実行する例です。
import os, sys
app_path = __file__if getattr(sys, 'frozen', False): app_path = sys.executableapp_dir = os.path.dirname(os.path.dirname(app_path))os.chdir(app_dir)
print("@cwd@", os.getcwd())
CLI環境で「src/main.py」を実行して出力したCWDと、exe化して「dist/main.exe」を実行したCWDを確かめます。1行目と3行目で、同じパスが出力されます。
.venv\Scripts\activatepyinstaller src/main.py --onefiledist\main.exepython src/main.pydeactivate
この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。
同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。
(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)