kivyで作ったアプリをNuitkaでexe化する時のエラー対処例

  • このエントリーをはてなブックマークに追加

Pythonプログラムの実行ファイル化(exe化)はPyInstallerが有名ですが、Nuitkaというライブラリも最近注目されてきました。ただやはり実行ファイル化はビルド時のエラーとの戦いが避けられません。この記事では筆者が直面して最終的に解決した方法を備忘録として記録します。

こんにちは。wat(@watlablog)です。今回はkivyで作ったGUIアプリを実行ファイル化する時に直面したエラー例と解決方法を紹介します

ここでは「動作環境」の項目に記載の環境のための解決策を示します。環境の確認は目次からジャンプしてみてください。

Nuitkaの概要と参考ページ

公式ページ

NuitkaはPythonで書かれたPythonに最適化されたコンパイラです。環境によりコマンドは変わりますがpip install nuitkaでインストールできます(筆者はMac&Python3環境のためpip3 install nuitkaでインストールしました)。

またNuitkaはWindows, macOS, Linux等のクロスプラットフォームで使用できます。

さらにNuitkaはApache License2.0であり、再配布時にライセンス条文をそのまま配布者に提供する必要はありますが、Nuitkaを使って作成されたアプリケーションの商用利用や複製が可能です。
参考:https://www.apache.org/licenses/LICENSE-2.0

Nuitkaの詳細やライセンス(ユーザーガイドに記載)は以下の公式ページを参照してください。

・トップページ:https://nuitka.net/
・要件やコマンド等の使い方:https://nuitka.net/doc/user-manual.html

日本語の使い方ページ

上記公式ページにも使い方が記載されていますが、英語が苦手な人は以下の日本語の記事が見やすいかも知れません。基本的なコマンドはここに記載されているもので十分だと思います。

NuitkaでPythonプログラムを配布してみよう

実行ファイル化するソースコードと環境

kivyで作成したGUIアプリ

今回実行ファイル化するソースコードは、「kivyでピーク検出機能付き簡易FFTアナライザを作ってみた」の記事で作成した3ファイルです。

このアプリはkivyでGUI関係を作り、PyAudioで録音、SciPyNumPyで計算、matplotlibでプロット…と様々なライブラリを駆使して成り立っています。この構成でビルド成功してしまえば、今後も幅広い科学技術系プログラムの実行ファイルが作れるようになるはずです。

上記記事はどこかでリライトしてしまう可能性があるので、念のため3つのファイル「main.py」「my.kv」「dspToolkit.py」+アイコン画像をまとめたZIPファイルをダウンロード可能としておきます。

動作環境

実行ファイルのビルドで発生するエラーやワーニングはPC環境(OSのバージョン等)やPython環境(Python本体やライブラリのバージョン等)が密接に関係します。

今回筆者が直面したエラーやワーニングは以下の環境で発生したものです。今後同じような所で躓く人が検索してきた時のために、ここから備忘録を記載します。

Mac OS macOS Catalina 10.15.7
CPU 1.4[GHz]
メモリ 8[GB]
        
Python Python 3.9.6
PyCharm (IDE) PyCharm CE 2020.1
Numpy 1.21.1
Scipy 1.4.1
Pandas 1.0.5
matplotlib 3.4.3
PySoundFile 0.9.0.post1
PyAudio 0.2.11
kivy 2.1.0
Kivy-Garden 0.1.5

結論:Error/Warning内容と解決方法

色々なエラーとワーニングに直面しましたが、最初に結論を示しておきます。macOSアプリをコンパイルするために、筆者は最終的に以下のコマンドを使いました。

まずはmacでターミナルを開き、先ほどの3つのソースコード+icon.pngが入ったフォルダまでcdコマンドで移動します。

次に以下のコマンドを実行します。詳細は後述。

ちなみにコンパイルには20分ほどかかりました。どうやらNuitkaは一度C言語に変換してからコンパイルしてくれるそうです(そのため計算速度もはやくなるとか)。

筆者の環境には既にCythonが入っていましたが、もしかしたら事前にpip installが必要かも知れません。

Error/Warning等メッセージと対応方法

nuitkaコマンド実行時

nuitkaの実行ファイル名を確認する

他のWebを参考にnuitka --standalone --onefile main.pyを実行すると、筆者の環境ではそもそもnuitkaコマンドが見つからないというメッセージを確認。

これはターミナルでパスが通っているbinフォルダの中にあるnuitkaがnuitka3となっていることを確認することで解決。

nuitkaの実行ファイル

これを根拠に基本コマンドを以下に決定。--follow-importsはimportしているPythonファイルを自動で探してくれるコマンドなので追加しておく。

コンパイルの高速化にorderedsetがあった方が良い

実行中のターミナルに以下のメッセージが表示され、orderedsetのpip installを実施。このライブラリのおかげでコンパイルが速くなるとのこと。

Nuitka:WARNING: Using very slow fallback for ordered sets, please install 'orderedset' PyPI package for best Python compile time performance.

PyPI orderedsethttps://pypi.org/project/orderedset/

--Onefileではzstandardが必要

--onefileコマンドを使用するとzstandardがないと圧縮できないと言われるのでこれもpip install。

Nuitka-Onefile:WARNING: Onefile mode cannot compress without 'zstandard' module installed.

PyPI zstandardhttps://pypi.org/project/zstandard/

PyQt5が使われているので--enable-plugin=pyqt5が必要

kivyがPyQt5を使っているからか、以下のメッセージが出てくるのでnuitkaコマンドに--enable-plugin=pyqt5を追加。

Nuitka-Plugins:WARNING: Use '--enable-plugin=pyqt5' for: Inclusion of Qt plugins.

macOSでPyQt5を使う場合は--macos-create-app-bundleが必要

PyQt5を指定すると以下のメッセージが出てくる。macOS特有と思われるが、このメッセージを根拠にnuitkaコマンドに--macos-create-app-bundleを追加。

FATAL: options-nanny: Error, package 'PyQt5' requires '--macos-create-app-bundle' to be used or else it cannot work.

tkinterを含めないようにする

以下のワーニングが表示されるので一応tkinterを--nofollowしておく。ただし、なくても実行ファイルは作成される。

Nuitka-Plugins:WARNING: pyqt5: Unwanted import of 'tkinter' that is redundant with 'PyQt5' encountered. Use '--nofollow-import-to=tkinter' or uninstall it for best compatibility with pure Python execution.

いらなかったコマンド

numpyやmatplotlib、scipy等の外部ライブラリは--plugin-enable=<Module name>が必要と書いてある記事がありましたが、筆者の環境だと必要ありませんでした。

逆に指定していると以下メッセージのように「それは必要ないよ」と教えてくれます。

<Module name>:Plugin is defined as always enabled, no need to enable it.

実行ファイル化されたアプリ起動時

kvファイルやアイコンファイルの指定が必要

kivyは別途kvファイル(ここではmy.kv)を使っているが、--follow-importsでは拾ってくれない。そのため--include-data-files=<source>=<target>を指定する。

実行ファイル化したアプリを起動した時に、これを指定しないと以下のエラーメッセージがターミナルに表示される(これはIDEで実行した時にkvファイルを指定しない時に出てくるメッセージ)。

AttributeError: 'super' object has no attribute 'getattr'

使い方は公式ページに記載。

公式ページhttps://nuitka.net/doc/user-manual.html#tutorial-setup-and-build-on-windows

アイコン画像等別途プログラムで参照しているファイルも同じコマンドで指定する。

指定が必要なModule

アプリ起動時にModuleNotFoundErrorが出る場合は--include-moduleコマンドで個別に入れるしかない。このエラーは実行ファイル化すると一個一個出てくるので、何度も実行ファイルをつくることになる…。でもこれは仕方ない(メッセージが出てくるだけありがたいと思います)。

ModuleNotFoundError: No module named 'kivy.uix.pagelayout'
ModuleNotFoundError: No module named 'kivy.graphics.cgl_backend.cgl_sdl2'

ちなみに、kivy.graphics.cgl_backend.cgl_sdl2を入れなくてもアプリは起動するが、kivyで使っているWindow.size文が実行できずに以下のエラー文が表示される(その文をコメントアウトすれば使えるようになるが、--includeしておいた方が良い)。

AttributeError: 'NoneType' object has no attribute 'size'

macOSでアイコン設定するために--macos-app-iconが必要

GUIアプリケーションでアイコンを設定する時は--macos-app-iconコマンドも必要。これがないと以下のメッセージが出る。

Nuitka:WARNING: For GUI applications, you ought to specify an icon with '--macos-app-icon'.", otherwise a dock icon may not be present.

公式ページにはWindows版のコマンドも併記されている。

公式ページhttps://nuitka.net/doc/user-manual.html#tutorial-setup-and-build-on-windows

テキストファイルを読む時はpathを明示しておく必要がある

--include-data-filesのみだと.txtファイルを読もうとした時に、実行ファイルにした時にFileNotFoundエラーがでました。

そんな時は以下のコードのように、osを使って明示的にファイルを読み込むと解決します。

実行ファイルの場所

上記コマンドを使って、疲労コンパイルで実行ファイル化できました。1ファイル化された実行ファイルは筆者の環境でmain.app/Contents/MacOS/に入っていました。作成された実行ファイルさえあればプログラムが実行可能であり、フォルダ名やファイル名は変更可能です。

ちなみにmacOSの場合はmain.appを右クリックして「パッケージの内容を表示」で中に入ることができます。

以下が実行時の例です。

アプリケーションの起動例

未解決な点

--disable-consoleをつけているのにターミナルが表示されたり、icon画像を指定したのに反映されないといった不明点が残りました。これは今後の課題。

--disable-consoleについては公式の文章でWindows用と読み取れます。macOS用に何かないものか、まだ探せず。

Console Window
On Windows, the console is opened by programs unless you say so. Nuitka defaults to this, effectively being only good for terminal programs, or programs where the output is requested to be seen. There is a difference in pythonw.exe and python.exe along those lines. This is replicated in Nuitka with the option --disable-console

https://nuitka.net/doc/user-manual.html#tutorial-setup-and-build-on-windows

main.distというフォルダには1ファイルになっていない実行ファイルがありますが、こちらを起動するとiconは正常に読めているようです。

まとめ

まだ不明点が残っていますが、まずは作ってみたアプリの実行ファイルができたのでヨシとします。今回はエラーを一つずつ潰していくことでなんとか動くところまで到達できました。

Nuitkaでつくった実行ファイルはPyInstallerでつくった場合と比べて容量も軽くなるそうです(こちらは未検証)。

本記事の内容が少しでもこれからNuitkaを使う人のヒントになればと思います。

作成したアプリをこのページに置こうか迷いましたが、パッケージ毎にライセンス条文が違うようなので、配布についてはもう少し勉強してから考えます。

↓こちらにちょっと調べたことについて記載しておきます。

配布時の注意について

実行ファイル化したプログラムを配布する際に気を付けることとして各パッケージのライセンスがあります。

NuitkaやPythonに関する数多くのライセンスはOSSOpen Source Software)であることが多いです(例外もあります)。

例えばMITライセンスやApacheライセンスはコード改変の有無に関わらずソースコードの開示は不要で商用利用も可能ですが、著作権は放棄していません。
そのためOSSのコードを使用したアプリは著作権表示ライセンス本文免責事項原文(多くは英文)のまま配布するユーザーに提示する必要があります。

OSSの著作権に関する書籍はこちらの本がわかりやすいです。

OSSを利用してソフトウェアを開発することが当たり前になっていますが、そのライセンスについては、まだまだ誤解もあります。その誤解のため、訴訟やその他のトラブルなども起きています。そこで本書では、OSSを正しく理解するために著作権を主眼点において解説しています。

また、以下の記事はVSCodeやTerminalといった実際の製品例を紹介しつつ、OSSのライセンス表示を調査していました。日本語の記事として一番参考になったと思うのでリンクを紹介します。

参考:OSSのライセンス表示はどうするべきなのか調べてみた

nuitkaによる実行ファイル化になんとか成功しました!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*