Pyxel (v1.9.4) で作ったゲームをPyInstallerとspecファイルを用いてビルド(exeを作る)する手順
はじめに:
作業環境は Windows10です。Pyxelのやや古いバージョンでもできるとは思います(v1.8.8でも手順の成功を確認済み)。
この方法はv1.9.4現在、公式で明示的に非推奨になっているわけではありませんが、PyInstaller(とspecファイル)による手動ビルドのサポートも明言されていないため、自己責任で実施する必要があります。
また、将来的にv1.9.4より上のバージョンで、仕様変更等の理由からこの方法が使用できなくなる可能性も多分にあります。予めご了承下さい。
公式に用意されているコマンドではなくこの手順を用いてビルドを行った理由については、記事末尾の「最後に」の部分に記載しています。
掲載したspecファイルはいかなる用途(商用・非商用問わず)においてもそのままコピペして使っていただいて構いませんが、この記事の内容を複製して他の場所で掲載することは固く禁じます。
なお、この記事の手順に従って作業をした際になんらかの不利益や損害を被ったとしても当記事執筆者は一切責任を負わないものとします。あくまで自己責任でご利用ください(危険なことをやっているわけではありませんが、あなたが将来的にゲームの販売などを考慮されている場合、作業手順が不安定であることを含めて保守体制をよくご検討いただく必要があります、ということです)。
前提
Pyxel1.9.4でapp2exeコマンドが追加され、pyxapp形式のファイルをexe化することができるようになりました。例えば以下のようなコマンド形式で実行することができます。
※大前提として、まず先にpyxappファイルがビルド済であり、PyInstallerも予めインストールされている必要があります。アプリ名はこの記事では仮に"hoge"としました。
pyxel app2exe hoge.pyxapp
コマンドの実行結果としてなにもエラーが出ず、以下のようなメッセージが表示された後にプロンプトが返ってくればビルドは成功です。
xxxxx INFO: Building EXE from EXE-00.toc completed successfully.
その場合、hoge.exeのようなファイルがhoge.pyxappと同じディレクトリに生成されているのではないかと思います。これを実行すると、なにも問題がない場合は恐らく正常にゲームが立ち上がってプレイできるはずです。その場合は、当記事はあなたにとってまったく必要のないものだということになります(その場合、以下は読む必要なし)。
ただ、ビルドは成功したのに実際にはうまく起動しなかった、という場合もあるかと思います。例えばそもそもビルド元のpyxapp自体が上手く動作していない場合です。pyxappを実行するときは以下のようなコマンドで実行すると思いますが、
pyxel play hoge.pyxapp
このときにエラーが出てしまって動かないような状況の場合です。
こういった場合、表示されるエラーメッセージを見ると解決の糸口が見えてくることが多いのですが、それらの問題を解決するために、自分で細かい部分の設定を詰めてPyInstallerに指示をしたい場合も出てくるかと思います。例えばoggファイルやwavファイルを実行ファイル中に同梱したい場合などです(Pyxel 1.9.4現在ではこれらの形式はサポートされておらず、ゲーム中で再生するには他の手段を自前で用意する必要があるためです)。
そういった場合に、現状(Pyxel 1.9.4を想定)は回避方法としてapp2exeコマンドを使わずにPyInstallerを手動で実行してexeをビルドするといった代案がひとつ考えられます。このときにspecファイルというものを作成しておき、それを指定してPyInstallerを実行するとコマンドの実行形式が短くでき、設定の見通しも良くなるため便利です。specファイルはPyInstallerに細かい指定をするための指示書みたいなものです。
手順
前置きが長くなりましたが手順を記載していきます。この手順でもPyInstallerは使いますので、予めPyInstallerがインストールされている必要があります。
hogeプロジェクトのディレクトリ構成を簡単に記載します。
hoge
├─assets (アセットがあるディレクトリ)
(中略)
├─main.py (名前は任意)
├─hoge.spec (名前は任意、これから手順の中で作るので最初はなくても良い)
├─icon.ico (名前は任意、作成も任意)
まず適当な場所にspecファイルを作ります。空のテキストファイルを作成し、以下のような内容をテキストエディタなどで記述していきます。
ここではファイル名を”hoge.spec”としました。名前は適当でも大丈夫ですが、わかりやすいものがいいでしょう。あとでPyInstallerを実行する際に、このファイル名を指定します。
ファイルを置く場所は、ここではビルド対象となるプロジェクトのディレクトリの中の最上位階層にしました。
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
Tree('assets', prefix='assets',),
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='hoge',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='icon.ico',
)
掻い摘んで説明しますと、
['main.py'] の行は最上位の関数があるファイル名を指定します。ここではhogeプロジェクトの直下にあるmain.pyを指定しています。異なる名前を使っている場合は適宜差し替えてください。
Tree('assets', prefix='assets',) の行はPyxelで使用するassetsディレクトリを指定しています。自分はこの場所の下に更にサブディレクトリをいくつか作り、そこにbgm用のoggファイルやsfxのwavファイルを格納しました。その場合も上記記述のままで大丈夫です。
name='hoge' 行は最終的に生成されるexeにつけられる名前を入れます。この例ですとhoge.exeが作られることになります。ここは適宜修正してください。とりあえず適当な名前にしておいて、後で手作業でexeのファイル名を変更しても構いません。
icon='icon.ico' 行はexeファイルのアイコン画像を指定します。specファイルと同じ階層にでも予めico拡張子のファイルを作っておき、そのファイル名をここで指定しましょう。ここでは"icon.ico"というファイルを指定しています。アイコン画像の作り方はここでは取り扱いませんので、別途調べてみてください。取り急ぎアプリアイコンは必要ないよ、という場合はこの行自体を削ってしまっても大丈夫です。
上記内容に加えて必要な修正事項・追加事項がある場合は適宜修正をお願いします。
上記内容を反映したらspecファイルを保存してエディタを閉じます。
hogeプロジェクトディレクトリでPowerShellなどを開き、現在位置を確認し、以下のファイルがあることを最低限確認しましょう(名前はhogeプロジェクトのものを例に記載していますので、違う名前にする場合は適宜置き換えて考えてください)。
main.py
hoge.spec
icon.ico (任意)
それでは、以下のコマンドを実行します。具体的に何をするかというとPyInstallerをspecファイルを指定して実行します。
pyinstaller hoge.spec
実行すると処理内容がずらずらと表示され、最後に以下のようなメッセージが出てプロンプトが返ってくれば作業終了です。
xxxxx INFO: Building EXE from EXE-00.toc completed successfully.
hogeプロジェクトディレクトリ直下に"dist"というディレクトリができ(何度か実行したことがあれば既にあるかもしれません)、そこに"hoge.exe"というファイルができていると思います。これを実行して無事に起動でき、正常に動作していれば本手順は成功です。
なお、自動で作られたdistやbuildディレクトリは、不要であれば任意で削除してもかまわないと思います。
作業は以上です。お疲れ様でした。
最後に
本手順を行った理由についてですが、自分がPyxelで作ったゲームの中でサウンドを再生するのにpygame.mixerを使用したかったためです。つまり完全にPyxelとは関係ないライブラリを持ってきて勝手に使っているので、自分の責任範囲である程度なんとかする必要がありました。oggファイルやwavファイルをassetsディレクトリ(の配下のサブディレクトリ)に置いたときに、これらをうまく同梱してビルドし、アクセスできるようにするためにspecファイルを書いてやる必要があったということです(本来、Pyxelでユーザーが直接specファイルを書いて使うことはありません)。
技術的な間違い、誤記等のご指摘を受け付けております。
よろしくお願いします。
編集履歴
v1.0 2022/11/19 初版
v1.1 2022/11/19 プロジェクトのディレクトリ構成についての記述を追加。
v1.2 2022/11/20 細部の修正、補足の付け足し等。
v1.3 2022/11/20 表題など、細部の修正。
v1.4 2023/01/14 「はじめに」と「前提」に補足の文章を追加。