2024/05/27(月) [n年前の日記]
#2 [python] Pythonスクリプトのexeファイル化を試した
Python + tkinter で簡単なGUIアプリを作成したけれど、せっかくだから、Windowsの実行形式であるexeファイルにしてみたい。どんな手順で変換できるのか試してみた。
環境は以下。
Nuitka と py2exe について試してみた。どちらも .py/.pyw を .exe に変換できるけれど、Nuitka はPythonのソースファイルをC言語のソースに変換してCコンパイラでexeを生成する仕組みとのこと。
Nuitka については以前も試したことがあった。そちらへのリンクもメモしておく。
_mieki256's diary - pygameでWindows用スクリーンセーバを作る
環境は以下。
- Windows10 x64 22H2
- Python 3.10.10 64bit
- Nuitka 2.2.3
- Microsoft Visual Studio Community 2022
- py2exe 0.13.0.1
Nuitka と py2exe について試してみた。どちらも .py/.pyw を .exe に変換できるけれど、Nuitka はPythonのソースファイルをC言語のソースに変換してCコンパイラでexeを生成する仕組みとのこと。
Nuitka については以前も試したことがあった。そちらへのリンクもメモしておく。
_mieki256's diary - pygameでWindows用スクリーンセーバを作る
◎ PyInstallerはダメだった :
一般的に、Pythonスクリプトのexe化と言うと PyInstaller が紹介されるのだけど、今回手元で試してみたところ、exeに変換している最中に Windows Defenderがウイルスとして誤検出して処理がエラーだらけになった。
ググったところ、ウイルス作成に PyInstaller が使われてしまう事例が多くなったせいで、PyInstaller でexeにしただけでもウイルス扱いされてしまう状態になっているらしい…。
ググったところ、ウイルス作成に PyInstaller が使われてしまう事例が多くなったせいで、PyInstaller でexeにしただけでもウイルス扱いされてしまう状態になっているらしい…。
◎ 自分の環境特有の注意点 :
自分の環境に限った話だけど、ハマったのでメモしておく。
自分の環境は Strawberry Perl をインストールして使っているせいで、Nuitka が Strawberry Perlインストールフォルダ内の gcc を検出してしまう。そのせいで動作が怪しくなったりしたので、Perl をインストールしている D:\Perls\ を一時的に D:\Perls_\ にリネームして参照されないように対処した。
また、Nuitkaでexe化するPythonスクリプトは、ファイルの1行目のシバン行(Shebang)を見てPythonのバージョンを決めているらしい。今回はシバン行ごと削除して対応した。あるいは、以下のように書いてもいい。
自分の環境は Strawberry Perl をインストールして使っているせいで、Nuitka が Strawberry Perlインストールフォルダ内の gcc を検出してしまう。そのせいで動作が怪しくなったりしたので、Perl をインストールしている D:\Perls\ を一時的に D:\Perls_\ にリネームして参照されないように対処した。
また、Nuitkaでexe化するPythonスクリプトは、ファイルの1行目のシバン行(Shebang)を見てPythonのバージョンを決めているらしい。今回はシバン行ごと削除して対応した。あるいは、以下のように書いてもいい。
#!/usr/bin/python3.10
◎ 仮想環境の作成 :
Nuitka にしろ py2exe にしろ、そのPythonスクリプトの動作に最低限必要なモジュールだけを含めるようにしたい。使わないモジュールが入っていても、ファイル容量の無駄になる。
そのために、Pythonの仮想環境を作成して、最低限のモジュールだけをインストールした状態で作業していく。
仮想環境の作成には venv を使った。Python 3.3 から Python に標準で取り込まれた、らしい。
以下を打てば、venv というディレクトリができて、Pythonを実行するために必要な仮想環境一式が用意される。
余談。「python -m hoge」と打てば、hogeモジュールを呼び出して実行することができる。上記では python -m venv と打っているので、venvモジュールを呼び出して使うことを指示している。
仮想環境に切り替える。
Linux + bash環境の場合は、source venv/Scripts/activate と打つのだろうか。
ちなみに、仮想環境から抜ける時は以下を打つ。
Pythonのバージョンを確認したり、インストールされているモジュールを確認する。
pip や setuptools をアップグレードしておきたい。以下を打って更新。
自作のスクリプトを動かすために必要なモジュールをインストールする。今回、以下のモジュールをインストールしたが、何が必要になるかは各事例で違ってくる。
今回は PyAutoGUI 0.9.54, pynput 1.7.7 がインストールされた。また、それらが依存しているモジュールもインストールされている。
そのために、Pythonの仮想環境を作成して、最低限のモジュールだけをインストールした状態で作業していく。
仮想環境の作成には venv を使った。Python 3.3 から Python に標準で取り込まれた、らしい。
以下を打てば、venv というディレクトリができて、Pythonを実行するために必要な仮想環境一式が用意される。
python -m venv venv
余談。「python -m hoge」と打てば、hogeモジュールを呼び出して実行することができる。上記では python -m venv と打っているので、venvモジュールを呼び出して使うことを指示している。
仮想環境に切り替える。
venv\Scripts\activate.bat仮想環境に切り替えた状態になると、DOS窓のプロンプトの最初に「(venv)」と表示される状態になる。そこを見て、現在仮想環境で作業中か、そうでないかを判断できる。
Linux + bash環境の場合は、source venv/Scripts/activate と打つのだろうか。
ちなみに、仮想環境から抜ける時は以下を打つ。
deactivate
Pythonのバージョンを確認したり、インストールされているモジュールを確認する。
(venv) ...>python --version Python 3.10.10 (venv) ...>python -m pip list Package Version ----------- ------- pip 24.0 setuptools 70.0.0
pip や setuptools をアップグレードしておきたい。以下を打って更新。
python -m pip --upgrade pip python -m pip --upgrade setuptools
自作のスクリプトを動かすために必要なモジュールをインストールする。今回、以下のモジュールをインストールしたが、何が必要になるかは各事例で違ってくる。
python -m pip install pyautogui python -m pip install pynput
今回は PyAutoGUI 0.9.54, pynput 1.7.7 がインストールされた。また、それらが依存しているモジュールもインストールされている。
>python -m pip list | grep -e "PyAutoGUI" -e "pynput" PyAutoGUI 0.9.54 pynput 1.7.7
◎ Nuitkaのインストール :
Nuitkaをインストールする。
Nuitka のバージョンを確認しておく。
ここまでの作業で、以下のモジュールがインストールされた。
仮想環境から一度抜けてみる。
python -m pip install nuitka
Nuitka のバージョンを確認しておく。
>python -m nuitka --version 2.2.3 Commercial: None Python: 3.10.10 (tags/v3.10.10:aad5f6a, Feb 7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)] Flavor: CPython Official Executable: D:\home\prg\python\_public\pyrgbfloatviewer\venv\Scripts\python.exe OS: Windows Arch: x86_64 WindowsRelease: 10 Version C compiler: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\bin\Hostx64\x64\cl.exe (cl 14.3).
ここまでの作業で、以下のモジュールがインストールされた。
>python -m pip list Package Version ----------- ------- MouseInfo 0.1.3 Nuitka 2.2.3 ordered-set 4.1.0 pillow 10.3.0 pip 24.0 PyAutoGUI 0.9.54 PyGetWindow 0.0.9 PyMsgBox 1.0.9 pynput 1.7.7 pyperclip 1.8.2 PyRect 0.2.0 PyScreeze 0.1.30 pytweening 1.2.0 setuptools 70.0.0 six 1.16.0 zstandard 0.22.0
仮想環境から一度抜けてみる。
deactivate
◎ Nuitkaを使ってみる :
Nuitkaの利用には、C/C++コンパイラが必要になる。Microsoft Visual C++ か、MinGW64 が必要になるらしい。
自分の環境は Visual Studio Community 2022 をインストールしてあるので、ソレを使うことにする。スタートメニューの中から、「x64 Native Tools Command Prompt for VS 2022」を探して起動。DOS窓が開く。
自作スクリプトがある場所まで移動してから、仮想環境(venvディレクトリ内)の Python を有効にする。
いよいよ、Nuitkaでexe化してみる。
途中で、「Backend C compiler: cl (cl 14.3).」と表示されている。cl.exe は MSVC (Microsoft Visual C++) のプログラム名なので、たしかに MSVC が使われてそう。これが MinGW64 の場合は、gcc か g++ が表示されるのだろうか?
ちなみに、MinGW64 を使いたい時は、`--mingw64` をつけるらしい。MinGW64が見つからない場合は、Nuitka が自動でダウンロードして使ってくれる。
自分の環境は Visual Studio Community 2022 をインストールしてあるので、ソレを使うことにする。スタートメニューの中から、「x64 Native Tools Command Prompt for VS 2022」を探して起動。DOS窓が開く。
自作スクリプトがある場所まで移動してから、仮想環境(venvディレクトリ内)の Python を有効にする。
cd /d D:\home\prg\python\_public\pyrgbfloatviewer venv\Scripts\activate.bat
いよいよ、Nuitkaでexe化してみる。
python -m nuitka --standalone --enable-plugin=tk-inter --windows-disable-console pyrgbfloatviewer.pyw
- --standalone は、他の環境に持っていっても動くように Python一式を入れてくれる、らしい?
- --enable-plugin=tk-inter は、スクリプトが tkinter を使っているときにつけておく。
- --windows-disable-console は、作成された .exe を実行した際にDOS窓を開かないようにする。GUIアプリの作成時につける。
- --follow-imports は、利用するモジュールをチェックしてくれるらしいけれど、--standalone を付けた場合は全モジュールを同梱するから --follow-imports は働かない、という解説も見かけた。
(venv) D:\...> python -m nuitka --standalone --enable-plugin=tk-inter --windows-disable-console pyrgbfloatviewer.pyw Nuitka-Options: Used command line options: --standalone --enable-plugin=tk-inter --windows-disable-console Nuitka-Options: pyrgbfloatviewer.pyw Nuitka: Starting Python compilation with Nuitka '2.2.3' on Python '3.10' commercial grade 'not installed'. Nuitka-Plugins:anti-bloat: Not including 'PIL.ImageQt' automatically in order to avoid bloat, but this may cause: PIL Nuitka-Plugins:anti-bloat: will not be able to create Qt image objects. Nuitka: Completed Python level compilation and optimization. Nuitka: Generating source code for C backend compiler. Nuitka: Running data composer tool for optimal constant value handling. Nuitka: Running C compilation via Scons. Nuitka-Scons: Backend C compiler: cl (cl 14.3). Nuitka-Scons: Backend linking program with 106 files (no progress information available for this stage). Nuitka-Scons: Compiled 106 C files using clcache with 0 cache hits and 106 cache misses. Nuitka will make use of Dependency Walker (https://dependencywalker.com) tool to analyze the dependencies of Python extension modules. Is it OK to download and put it in 'C:\Users\USERNAME\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\depends\x86_64'. Fully automatic, cached. Proceed and download? [Yes]/No : Nuitka: Downloading 'https://dependencywalker.com/depends22_x64.zip'. Nuitka: Extracting to 'C:\Users\USERNAME\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\depends\x86_64\depends.exe' Nuitka-Plugins:tk-inter: Included 87 data files due to Tk needed for tkinter usage. Nuitka-Plugins:tk-inter: Included 835 data files due to Tcl needed for tkinter usage. Nuitka: Keeping build directory 'pyrgbfloatviewer.build'. Nuitka: Successfully created 'pyrgbfloatviewer.dist\pyrgbfloatviewer.exe'.
途中で、「Backend C compiler: cl (cl 14.3).」と表示されている。cl.exe は MSVC (Microsoft Visual C++) のプログラム名なので、たしかに MSVC が使われてそう。これが MinGW64 の場合は、gcc か g++ が表示されるのだろうか?
ちなみに、MinGW64 を使いたい時は、`--mingw64` をつけるらしい。MinGW64が見つからない場合は、Nuitka が自動でダウンロードして使ってくれる。
◎ 結果 :
今回は、以下の2つのディレクトリが作成された。
pyrgbfloatviewer.dist/ の中に大量のファイルがあって、その中に `pyrgbfloatviewer.exe` があった。
`pyrgbfloatviewer.exe` を実行してみたところ、動いているように見えた。pyrgbfloatviewer.build/ は削除してしまってもOKっぽい。
ちなみに、pyrgbfloatviewer.dist/ のサイズは35.48MBだった。
メインPC上で作成した pyrgbfloatviewer.dist/ をサブPC(Windows10 x64 22H2)にコピーして動作確認してみたところ、そちらでも動いてくれた。
pyrgbfloatviewer.build pyrgbfloatviewer.dist
pyrgbfloatviewer.dist/ の中に大量のファイルがあって、その中に `pyrgbfloatviewer.exe` があった。
`pyrgbfloatviewer.exe` を実行してみたところ、動いているように見えた。pyrgbfloatviewer.build/ は削除してしまってもOKっぽい。
ちなみに、pyrgbfloatviewer.dist/ のサイズは35.48MBだった。
メインPC上で作成した pyrgbfloatviewer.dist/ をサブPC(Windows10 x64 22H2)にコピーして動作確認してみたところ、そちらでも動いてくれた。
◎ MinGW64の場所 :
Nuitka利用時、MinGW64 を使おうとして、MinGW64が見つからない場合、今回は自動で以下の場所にダウンロードされた。1.2GB以上のファイルサイズだった。
実験終了後、Cacheフォルダを削除してみたが、これと言って妙な動作にはならなかった。
C:\Users\USERNAME\AppData\Local\Nuitka\Nuitka\Cache\DOWNLO~1\gcc\x86_64\13.2.0-16.0.6-11.0.1-msvcrt-r1
実験終了後、Cacheフォルダを削除してみたが、これと言って妙な動作にはならなかった。
◎ py2exeでexeファイル化 :
py2exe でexeファイル化できることも確認できた。
仮想環境の作成と切替、必要なモジュールのインストールは、Nuitka と同じ。
Nuitka の代わりに、py2exe をインストールする。
注意点。2024/05/27現在、pynput を使っているPythonスクリプトを py2exeを利用してexe化する場合は、pynput 1.6.8にダウングレードしないと import error が出る。
_python 3.x - Getting error when using pynput with pyinstaller - Stack Overflow
_ImportError when using PyInstaller - Issue #312 - moses-palmer/pynput
setup.py を作成。
py2exe でexe化する。
dist/ ディレクトリが出来上がるので、別の環境にコピー。中にある pyrgbfloatviewer.exe を実行したところ起動した。
これも、メインPC上から、サブPCに dist/ をコピーして動作確認したところ動いてくれた。
- Windows10 x64 22H2
- Python 3.10.10 64bit
- py2exe 0.13.0.1
仮想環境の作成と切替、必要なモジュールのインストールは、Nuitka と同じ。
Nuitka の代わりに、py2exe をインストールする。
python -m pip install py2exe
注意点。2024/05/27現在、pynput を使っているPythonスクリプトを py2exeを利用してexe化する場合は、pynput 1.6.8にダウングレードしないと import error が出る。
_python 3.x - Getting error when using pynput with pyinstaller - Stack Overflow
_ImportError when using PyInstaller - Issue #312 - moses-palmer/pynput
python -m pip install pynput==1.6.8
setup.py を作成。
from distutils.core import setup import py2exe setup(windows = [{"script": "pyrgbfloatviewer.pyw"}])
- コンソールアプリの場合は、setup(console = ["hoge.py"]) と記述する。
- GUIアプリの場合は、setup(windows = [{"script": "hoge.pyw"}]) と記述する。この記述にすることで、実行時にDOS窓が開かない状態になる。
py2exe でexe化する。
python setup.py py2exe
dist/ ディレクトリが出来上がるので、別の環境にコピー。中にある pyrgbfloatviewer.exe を実行したところ起動した。
これも、メインPC上から、サブPCに dist/ をコピーして動作確認したところ動いてくれた。
[ ツッコむ ]
以上です。