はじめに
今回は社内ツールの開発で利用したPythonのexe化ライブラリ2種について書いていきます。
半ば自分用のメモでもあるので、わかりにくかったらすいません。
exe化とは
Pythonで開発したツールは、Pythonのない環境では動かせません。使っているライブラリもインストールする必要があります。なので、同じようにPython環境を用意していない人に共有するのは一筋縄ではいきません。
そこで役に立つのがexe化です。Pythonスクリプトをexeファイル(Windowsの実行ファイル)に変換することで、Python環境なしでも同じような動作をさせることができます。
Pyinstallerについて
Pythonのexe化について調べると、最初に見つかるライブラリがPyinstallerです。自分も最初はこれを使いました。
PyInstaller は、Python アプリケーションとそのすべての依存関係を 1 つのパッケージにバンドルします。ユーザーは、Python インタープリターやモジュールをインストールしなくても、パッケージ化されたアプリを実行できます。 PyInstaller は Python 3.8 以降をサポートし、numpy、matplotlib、PyQt、wxPython などの多くの主要な Python パッケージを正しくバンドルします。
公式サイトより引用
試しに使ってみましょう。
print("Hello World")
みんな大好きHelloWorld君です。
用意した同フォルダで以下のコマンドを実行しましょう。
PS C:\vscode\python_test> pyinstaller test.py
元々あったtest.py以外にいくつかファイルが作成されました。
以下はChatGPTに聞いてみた各ファイルの内容です。
dist
ディレクトリ
役割
- このディレクトリには、PyInstallerによって生成された実行可能ファイルと、アプリケーションの実行に必要な全ての依存ファイルが含まれます。
- アプリケーションを配布する際には、この
dist
ディレクトリ内の内容をユーザーに提供します。
内容
- 実行可能ファイル
- 依存するDLLファイル
- Pythonライブラリ
- データファイルなど
build
ディレクトリ
役割
-
build
ディレクトリは変換プロセス中にPyInstallerが使用する一時ファイルを格納します。 - ビルドプロセスのデバッグやトラブルシューティングに役立つ情報が含まれます。
内容
- 中間ファイル
- ログファイル
- 解析されたバイナリファイルなど
.spec
ファイル
役割
- PyInstallerがアプリケーションをコンパイルする際に参照する設定ファイルです。
- ビルドプロセスの細かいカスタマイズを可能にします。
内容
- 追加のファイルやディレクトリの指定
- 隠されたインポートの追加
- アイコン設定
- 単一ファイルモードやウィンドウモードの指定など
あっさり言うと、完成品がdistフォルダに格納されることが分かっていればOKだと思います。
PS C:\vscode\python_test\dist\test> .\test.exe
Hello World
--onefileオプションについて
distフォルダはexeファイル以外にもファイルが形成されています。それらも実行に必要なファイルなので、人に渡す際はフォルダごと渡す必要があります。
それは面倒ですよね、ということでよく使われるのが--onefile
オプション
PS C:\vscode\python_test> pyinstaller test.py --onefile
これで中身がexeファイルのみになりました。
他にもオプションは色々あるようなので、気になる方は調べてください。
Pyinstallerの問題点
これで楽に共有ができる!と思って、ちゃんとしたツールを作成し、exe化したところで、Pyinstallerの大きな問題点に直面しました。
ライブラリ重い問題
ライブラリを色々入れてみた状態でpyinstaller --onefile
をやりましょう。
import numpy
import pyautogui
import pandas
import pyppeteer
print("Hello World")
容量はこんな感じになりました。
問題なのは起動時間です。
ライブラリ無し:一瞬
ライブラリ有り:2秒くらい
これ、簡単な処理の場合はこれくらいで済むのですが、処理を色々と連ねていくと、起動時間が数十秒にも伸びていきます。
実際、ツール作成時では起動に20秒以上かかってしまい、exe化について見直すに至りました。
Nuitkaについて
続いては同じくexe化ライブラリ Nuitkaについて
Pyinstallerに比べて人気は少なめですね。。
--standalone
オプションを付けることでPython無し環境でも動くよう作れるみたいです。
PS C:\vscode\nuitka_test> nuitka --standalone test.py
2024/03/26現在はPython3.12が最新ですが、Nuitkaは3.11まで対応となっています。
PS C:\vscode\python_test> nuitka --standalone test.py
Nuitka-Options: Used command line options: --standalone test.py
Nuitka:WARNING: The Python version '3.12' is only experimentally supported by Nuitka '2.1.3', but an upcoming release will change that. In the mean time use Python version '3.11' instead or newer Nuitka.
FATAL: The Python version '3.12' is not supported by Nuitka '2.1.3', but an upcoming release will add it. In the mean time use '3.11' instead.
暫くしたら対応されそうですね。
とりあえずpython3.11に変更しました。
Pyinstallerとは異なり、test.buildとtest.distが作成されました。
distフォルダの中身が完成品です。
同じように--onefile
オプションはあるので、一ファイルにまとめたい場合は使ってみましょう。
ちなみに容量はそこまで変わりませんでした。(35,754 KB)
Pyinstallerと比べると
メリット
- 起動が早い
- 実行速度も速い
Nuitkaは一度C言語に変換して、それからコンパイルが行われるので、比較的速度が速いようです。
社内ツール作成時に利用した時も、起動が確実に速くなりました。
デメリット
- コンパイルに時間がかかる(特に
--onefile
付けた場合) -
--onefile
オプションで社内ソフトにウイルス判定された…
コンパイルは極端に長くなります。Pyinstallerでは1分程度で出来たものも、Nuitkaでは0分以上かかることがありました。
結局どっち使ったのか
最終的に、社内ツールの共有にはNuitka --standalone
を使いました。
--onefile
オプションも使いたかったのですが、ウイルス誤検知や起動時間の関係で、使わないことになりました。
コンパイルに時間はかかりますが、頻繁な更新はしないので別にいいかなと思いました。
今後も社内共有で利用していきたいと思います。