MochiuWiki : SUSE, EC, PCB
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Pythonその他 - 実行ファイルのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Pythonその他 - 実行ファイル
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == Pythonスクリプトを実行ファイル化することにより、Pythonがインストールされていない環境でもプログラムを実行できるようになる。<br> 実行ファイル化のツールとして広く使用されており信頼性の高いPyInstallerやNuitkaが存在する。<br> <br> PyInstallerの主な特徴を以下に示す。<br> * 単一ファイルまたはフォルダ形式での出力 * Windows、Linux、MacOSに対応 * 依存モジュールの自動検出 * データファイルやリソースの組み込み * GUIアプリケーションのサポート <br><br> == 複数ファイルで構成されるプロジェクトの構造 == 実際の開発では、単一ファイルではなく複数のモジュールに分割されたプロジェクト構造が一般的である。<br> <br> ==== 想定するプロジェクト構造 ==== この構造において、<u>main.py</u> ファイルがエントリーポイントとなり、他のモジュールをimportして使用する。<br> <br> my_project/ ├── main.py # エントリーポイント (メインスクリプト) ├── requirements.txt # 依存パッケージ一覧 ├── config.ini # 設定ファイル (データファイル) ├── resources/ # リソースフォルダ │ ├── images/ │ │ └── logo.png │ └── data/ │ └── default_settings.json ├── src/ # ソースコードのメインパッケージ │ ├── __init__.py │ ├── core/ # コア機能モジュール │ │ ├── __init__.py │ │ ├── engine.py │ │ └── processor.py │ ├── ui/ # UI関連モジュール │ │ ├── __init__.py │ │ ├── main_window.py │ │ └── dialogs.py │ └── utils/ # ユーティリティモジュール │ ├── __init__.py │ ├── file_handler.py │ └── logger.py └── tests/ # テストコード (実行ファイルには含めない) ├── __init__.py └── test_engine.py <br> ==== エントリーポイント (main.py) の例 ==== <syntaxhighlight lang="python"> #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ アプリケーションのエントリーポイント PyInstallerでexe化する際は、このファイルを指定する """ import sys import os def get_base_path(): """ 実行ファイルのベースパスを取得する。 PyInstallerでパッケージ化された場合と、通常のPython実行の場合で パスの取得方法が異なるため、この関数で吸収する。 """ if getattr(sys, 'frozen', False): # PyInstallerで実行されている場合 # sys._MEIPASS は一時展開フォルダのパス (--onefileの場合) # sys.executable は実行ファイル自体のパス return os.path.dirname(sys.executable) else: # 通常のPython実行の場合 return os.path.dirname(os.path.abspath(__file__)) def get_resource_path(relative_path): """ リソースファイルへのパスを取得する。 --add-data で含めたファイルにアクセスする際に使用する。 """ if getattr(sys, 'frozen', False): # PyInstallerの一時展開フォルダ内のパス base_path = sys._MEIPASS else: base_path = os.path.dirname(os.path.abspath(__file__)) return os.path.join(base_path, relative_path) def main(): """メイン関数""" # リソースファイルへのアクセス例 config_path = get_resource_path('config.ini') logo_path = get_resource_path(os.path.join('resources', 'images', 'logo.png')) # 各モジュールのimport from src.core.engine import Engine from src.ui.main_window import MainWindow from src.utils.logger import setup_logging # ロギングの設定 setup_logging() # アプリケーションの起動 engine = Engine() window = MainWindow(engine) window.run() if __name__ == '__main__': main() </syntaxhighlight> <br><br> == Windows == ==== 環境構築 ==== コマンドプロンプトまたはPowerShellを開き、Pythonのバージョンを確認する。<br> python --version pip --version <br> <code>python</code> コマンドが認識されない場合は、Pythonのインストール時に[Add Python to PATH]にチェックを入力し忘れている可能性がある。<br> その場合は環境変数を手動で設定、または、Pythonを再インストールする。<br> <br> ==== 仮想環境の作成 ==== プロジェクトフォルダに移動して仮想環境を作成する。<br> 仮想環境を使用することで、実行ファイルに不要なパッケージが含まれることを防ぎ、ファイルサイズを最小限に抑えられる。<br> cd C:\path\to\my_project python -m venv venv venv\Scripts\activate <br> プロンプトの先頭に <u>(venv)</u> と表示されれば、仮想環境がアクティブになっている。<br> <br> ==== 依存パッケージとPyInstallerのインストール ==== pip install pyinstaller pip install -r requirements.txt <br> ==== 基本的なビルドコマンド ==== 複数ファイルのプロジェクトでも、指定するのはエントリーポイントのファイルだけである。<br> PyInstallerは、そのファイルからimportされている全てのモジュールを自動的に追跡して、実行ファイルに含める。<br> pyinstaller main.py <br> このコマンドにより、<u>main.py</u> がimportしている <u>src.core.engine</u>、<u>src.ui.main_window</u> 等のモジュールは自動的に検出されて、実行ファイルに組み込まれる。<br> <br> ==== 生成されるディレクトリとファイル ==== <center> {| class="wikitable" |+ ビルド時に生成されるディレクトリとファイル |- ! ディレクトリ / ファイル !! 説明 |- | build/ || PyInstallerが作業中に使用する一時ファイルの格納場所。<br>配布時には不要。 |- | dist/ || 生成された実行ファイルと依存ファイルの格納場所。 |- | your_script.spec || PyInstallerの設定ファイル。<br>カスタマイズに使用する。 |} </center> <br> ==== データファイルとリソースの追加 ==== Pythonソースコード以外のファイル (設定ファイル、画像、JSONデータ等) は自動的には含まれない。<br> <code>--add-data</code> オプションで明示的に指定する必要がある。<br> pyinstaller --onefile ^ --add-data "config.ini;." ^ --add-data "resources;resources" ^ main.py <br> <code>--add-data</code> オプションの書式は、<code>"元のパス;実行ファイル内での配置先パス"</code>となる。<br> Windowsではセミコロン (<code>;</code>) を区切り文字として使用する。<br> <br> 上記の例では、config.iniファイルは実行ファイルと同じ階層に配置され、resourcesフォルダはその中身ごとresourcesという名前で配置される。<br> <br> ==== GUIアプリケーション向けオプション ==== GUIアプリケーションの場合は、コンソールウィンドウを非表示にし、アイコンを設定する。<br> pyinstaller --onefile --noconsole ^ --icon=resources\images\app_icon.ico ^ --name=MyApplication ^ --add-data "config.ini;." ^ --add-data "resources;resources" ^ main.py <br> <center> {| class="wikitable" |+ 主なオプション |- ! オプション !! 説明 |- | --onefile || 単一の実行ファイルにまとめる |- | --noconsole || コンソールウィンドウを非表示 (GUIアプリ向け) |- | --windowed || --noconsoleと同じ |- | --icon || アイコンファイルを指定 (.ico形式) |- | --name || 出力ファイル名を指定 |- | --add-data || データファイルを追加 |- | --hidden-import || 自動検出されないモジュールを追加 |} </center> <br> ==== specファイルを使用した詳細設定 ==== 複雑なプロジェクトでは、specファイルを使用して設定を管理することを推奨する。<br> まず、初回のビルドでspecファイルを生成する。<br> pyinstaller --onefile --noconsole --name=MyApplication main.py <br> 生成されたMyApplication.specファイルを開いて、必要に応じて編集する。<br> <syntaxhighlight lang="python"> # -*- mode: python ; coding: utf-8 -*- block_cipher = None # データファイルの定義 # 形式: (元のパス, 実行ファイル内での配置先) added_files = [ ('config.ini', '.'), ('resources/images', 'resources/images'), ('resources/data', 'resources/data'), ] # 自動検出されないモジュールがある場合に追加 hidden_imports = [ # 例: 動的インポートを使用している場合 # 'src.plugins.optional_module', ] # 除外するモジュール (ファイルサイズ削減のため) excludes = [ 'tkinter', # GUIフレームワークを使わない場合 'unittest', # テストフレームワーク 'pytest', ] a = Analysis( ['main.py'], pathex=[], binaries=[], datas=added_files, hiddenimports=hidden_imports, hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=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( pyz, a.scripts, a.binaries, a.datas, [], name='MyApplication', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, # UPX圧縮を使用 (インストール済みの場合) upx_exclude=[], runtime_tmpdir=None, console=False, # コンソールウィンドウを非表示 disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, icon='resources\\images\\app_icon.ico', ) </syntaxhighlight> <br> specファイルを編集した後は、以下に示すコマンドを実行してビルドする。<br> pyinstaller MyApplication.spec <br> ==== Hidden Importsの対処 ==== PyInstallerは静的解析によってimportを検出するが、以下のようなケースでは自動検出できないことがある。<br> <br> * 動的インポートを使用している場合 *: <code>importlib.import_module()</code> 等 * 文字列からモジュールを参照している場合 * 一部の複雑なライブラリ *: pandas、scipy、scikit-learn、PIL等のサブモジュール <br> エラーメッセージに <u>ModuleNotFoundError</u> が含まれている場合は、そのモジュールを <code>--hidden-import</code> オプションで追加する。<br> pyinstaller --onefile --hidden-import=PIL._tkinter_finder main.py <br> または、specファイルの <u>hiddenimports</u> リストに追加する。<br> <br> ==== Windows用ビルドスクリプト ==== ビルド作業を効率化するため、バッチファイルを作成することを推奨する。<br> <syntaxhighlight lang="batch"> @echo off setlocal REM 仮想環境のアクティベート call venv\Scripts\activate REM 出力ディレクトリの作成 if not exist dist\windows mkdir dist\windows REM PyInstallerの実行 pyinstaller --onefile --noconsole ^ --distpath dist\windows ^ --workpath build\windows ^ --add-data "config.ini;." ^ --add-data "resources;resources" ^ --icon=resources\images\app_icon.ico ^ --name=MyApplication ^ main.py echo. echo ビルドが完了しました。出力先: dist\windows\MyApplication.exe pause </syntaxhighlight> <br><br> == RHEL / SUSE == ==== 前提条件 ==== PyInstallerはクロスコンパイルをサポートしていない。<br> Linux向けの実行ファイルを作成するには、Linux環境でPyInstallerを実行する必要がある。<br> <br> もし、Windows環境からLinux向けの実行ファイルを作成する場合は、WSL2、Docker、仮想マシンを使用する。<br> <br> ==== 環境構築 ==== ===== RHEL ===== まず、Pythonと開発ツールをインストールする。<br> # RHEL sudo dnf install python3 python3-pip python3-devel sudo dnf groupinstall "Development Tools" <br> RHELでは、デフォルトのPythonバージョンがシステムによって異なる。<br> 例えば、Python 3.9以上を使用する場合は、以下に示すようにインストールする。<br> # Python 3.11を使用する場合 sudo dnf install python3.11 python3.11-pip python3.11-devel <br> ===== SUSE ===== まず、Pythonと開発ツールをインストールする。<br> devel_basisパターンには、gcc、make等の基本的な開発ツールが含まれている。<br> <br> # SUSE sudo zypper install -t pattern devel_basis sudo zypper install python3 python3-pip python3-devel <br> ==== 仮想環境の作成 ==== プロジェクトディレクトリに移動して、仮想環境を作成する。<br> cd /path/to/my_project python3 -m venv venv source venv/bin/activate <br> 特定バージョンのPythonを使用する場合は、そのバージョンを明示的に指定する。<br> python3.11 -m venv venv source venv/bin/activate <br> ==== 依存パッケージとPyInstallerのインストール ==== pip install --upgrade pip pip install pyinstaller pip install -r requirements.txt <br> ==== 実行ファイルの作成 ==== 基本的なコマンド構文はWindowsと同様である、<code>--add-data</code> オプションの区切り文字がコロン (<code>:</code>) になることに注意する。<br> # CLIアプリケーションの場合 pyinstaller --onefile \ --add-data "config.ini:." \ --add-data "resources:resources" \ main.py # GUIアプリケーションの場合 pyinstaller --onefile --noconsole \ --add-data "config.ini:." \ --add-data "resources:resources" \ --name=MyApplication \ main.py <br> <center> {| class="wikitable" |+ PyInstallerによるビルドと実行時の環境要件 |- ! 項目 !! 説明 |- | ビルド時 || PyInstallerのビルドプロセス自体はコマンドラインで実行するため、ディスプレイサーバー (X11 / Wayland) は不要 |- | 実行時 || 使用するGUIツールキットに依存する |} </center> <br> 下表に、GUIツールキットのWayland対応状況を示す。<br> <br> <center> {| class="wikitable" |+ Python GUIツールキットのWayland対応状況 (2025年1月時点) |- ! ツールキット !! Wayland対応 !! 備考 |- | Qt5 / Qt6 || ネイティブサポート || qt5-wayland / qt6-wayland パッケージのインストールが必要となる。<br>環境変数 <code>QT_QPA_PLATFORM=wayland</code> で明示的に指定可能 |- | PyQt5 / PyQt6 / PySide6 || ネイティブサポート || QtのPythonバインディングのため、Qt同様にWaylandをネイティブサポート |- | GTK3 / GTK4 || ネイティブサポート || GTK3はバージョン3.20以降で完全サポート<br>GTK4はWayland優先設計 |- | Kivy || SDL2経由でサポート || OpenGL ES 2.0とSDL2上に構築<br>SDL2がWayland対応のため、間接的にサポート |- | wxWidgets (wxPython) || GTK経由でサポート || LinuxではGTKバックエンドを使用するため、GTK経由でWaylandをサポート<br>ただし、クリップボードやドラッグ&ドロップ等で一部制限あり |- | Tkinter || 非対応 (XWayland経由で動作) || Tcl/TkがX11ベースで設計されているため、ネイティブ非対応<br>XWayland互換レイヤー経由で動作可能<br><br>将来的なWayland対応は検討中だが、現時点では未実装 |} </center> <br> ==== specファイルを使用した設定 ==== Linuxでのspecファイルは、パス区切り文字がスラッシュになる点を除き、Windowsとほぼ同じ構造である。<br> <syntaxhighlight lang="python"> # -*- mode: python ; coding: utf-8 -*- block_cipher = None # データファイルの定義 (Linux版) # パス区切り文字は / を使用 added_files = [ ('config.ini', '.'), ('resources/images', 'resources/images'), ('resources/data', 'resources/data'), ] hidden_imports = [] excludes = [ 'tkinter', 'unittest', 'pytest', ] a = Analysis( ['main.py'], pathex=[], binaries=[], datas=added_files, hiddenimports=hidden_imports, hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=excludes, noarchive=False, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, a.binaries, a.datas, [], name='MyApplication', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=True, # CLIアプリの場合はTrue、GUIの場合はFalse ) </syntaxhighlight> <br> ==== 実行権限の付加と動作確認 ==== # 実行権限の付加 ls -la dist/MyApplication chmod u+x dist/MyApplication # 必要な場合 # 動作確認 ./dist/MyApplication <br> ==== GLIBCバージョンの互換性について ==== PyInstallerで生成されたバイナリは、ビルド環境のGLIBCバージョンに依存する。<br> 新しいGLIBCでビルドしたバイナリは、古いGLIBCを持つシステムでは動作しない可能性がある。<br> <br> 配布先の環境で確実に動作させるためには、以下に示す事柄を考慮する。<br> * ターゲット環境と同じ、あるいは、それより古いバージョンのディストリビューションんでビルドする。 *: 例 : RHEL 9向けの実行ファイルを作成する場合は、RHEL 9環境でビルドする。 <br> 現在のGLIBCバージョンは以下に示すコマンドで確認できる。<br> ldd --version # または rpm -q glibc <br> ==== 共有ライブラリの依存関係の確認 ==== 生成されたバイナリが依存している共有ライブラリを確認するには、<code>ldd</code> コマンドを使用する。<br> ldd dist/MyApplication <br> <u>"not found:</u> と表示されるライブラリがある場合、そのバイナリはターゲット環境で動作しない可能性がある。<br> <br> ==== Linux向けビルドスクリプト ==== <syntaxhighlight lang="bash"> #!/usr/bin/env sh # 仮想環境のアクティベート source venv/bin/activate # 出力ディレクトリの作成 mkdir -p dist/linux # PyInstallerの実行 pyinstaller --onefile \ --distpath dist/linux \ --workpath build/linux \ --add-data "config.ini:." \ --add-data "resources:resources" \ --name=MyApplication \ main.py echo "" echo "ビルドが完了しました。出力先: dist/linux/MyApplication" </syntaxhighlight> <br> スクリプトに実行権限を付与する。<br> chmod u+x build_scripts/build_linux.sh <br><br> == Nuitkaを使用した高度なコンパイル == Nuitkaは、PythonコードをC言語にコンパイルしてから実行ファイルを生成するツールである。<br> PyInstallerと比較して、実行速度が向上し、リバースエンジニアリングへの耐性も高くなる。<br> <br> ==== Nuitkaのインストール ==== pip install nuitka <br> Windows環境では、Visual Studio Build Tools または MinGW-w64 が必要である。<br> Linux環境では、GCCと関連ツールが必要である。<br> # RHEL sudo dnf install gcc gcc-c++ # SUSE sudo zypper install gcc gcc-c++ <br> ==== 基本的な使用方法 ==== # CLIアプリケーションの場合 python -m nuitka --standalone --onefile your_script.py # GUIアプリケーションの場合 python -m nuitka --standalone --onefile --windows-disable-console --windows-icon-from-ico=icon.ico your_script.py <br> Nuitkaは初回ビルド時に時間が掛かるが、生成される実行ファイルは一般的にPyInstallerよりも高速に動作する。<br> <br><br> == トラブルシューティング == ==== ModuleNotFoundErrorが発生する ==== * 原因 *: PyInstallerが動的インポートや特定のライブラリのサブモジュールを検出できていない。 * 対処法 *: エラーメッセージに表示されているモジュールを <code>--hidden-import</code> オプションで追加する。 <br> pyinstaller --onefile --hidden-import=missing_module main.py <br> よく問題になるライブラリと対処例を以下に示す。<br> <center> {| class="wikitable" |+ Hidden Importが必要になることが多いライブラリ |- ! ライブラリ !! 追加が必要なモジュールの例 |- | pandas || pandas._libs.tslibs.timedeltas |- | PIL / Pillow || PIL._tkinter_finder |- | scikit-learn || --collect-submodules=sklearn |} </center> <br> ==== ファイルが見つからないエラー ==== * 原因 *: データファイル (設定ファイル、画像等) が実行ファイルに含まれていない、または、パスの解決が正しくない。 * 対処法 *: <code>--add-data</code> オプションでファイルを正しく含めているか確認する。 *: ソースコード内で <code>get_resource_path()</code> メソッドを使用してパスを解決しているかどうかを確認する。 <br> ==== 実行ファイルのサイズが大きすぎる ==== 対処法を以下に示す。<br> <br> * 仮想環境を使用して、必要なパッケージのみをインストールした環境でビルドする。 * specファイルの <u>excludes</u> リストに、使用していないモジュールを追加する。 * UPX圧縮を使用する。 *: もしUPXがインストールされていれば、PyInstallerは自動的に使用する。 *: <br> *: UPXのインストール手順を以下に示す。 *: <syntaxhighlight lang="text"> # RHEL sudo dnf install upx # SUSE sudo zypper install upx </syntaxhighlight> <br> ==== "GLIBC_X.XX not found" エラー ==== * 原因 *: ビルド環境のGLIBCのバージョンが、実行環境より新しい。 * 対処法 *: ターゲット環境と同じか、それより古いバージョンのLinuxでビルドする。 *: Dockerを使用して古い環境でビルドする方法も効果的である。 *: <br> *: Dockerを使用したビルド方法を以下に示す。 *: <syntaxhighlight lang="text"> # 例: openSUSE Leap 15.1のDockerコンテナでビルド docker run -it -v $(pwd):/app opensuse/leap:15.1 bash # コンテナ内でPythonとPyInstallerをセットアップしてビルド # ...略 </syntaxhighlight> <br><br> == 手法の選択指針 == <center> {| class="wikitable" |+ ツール選択の指針 |- ! 用途 !! 推奨ツール !! 備考 |- | 通常の用途で手軽に実行ファイルを作成したい || PyInstaller || 豊富な情報があり、トラブルシューティングも容易 |- | 実行速度を重視する || Nuitka || ビルド環境の準備とビルド時間が増加する |- | コードの難読化を強化したい || Nuitka || C言語へのコンパイルにより難読化される |- | クロスプラットフォーム対応が必要 || PyInstaller || 各OSの環境でそれぞれビルドを行う必要がある |} </center> <br> クロスプラットフォーム対応が必要な場合は、各OSの環境 (実機、VM、Docker、WSL2等) でそれぞれビルドを行う必要がある。<br> CI/CDパイプライン (GitHub Actions等) を活用すると、複数プラットフォーム向けのビルドを自動化できる。<br> <br><br> == 外部リンク == * [https://pyinstaller.org/en/stable/ PyInstaller公式ドキュメント] * [https://nuitka.net/ Nuitka公式サイト] * [https://github.com/pyinstaller/pyinstaller PyInstaller GitHub] <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Python,PyInstaller,Nuitka,exe,実行ファイル,Windows,Linux,RHEL,SUSE,openSUSE,パッケージング,配布,デプロイ |description={{PAGENAME}} - PythonスクリプトをWindows exeやLinux実行ファイルに変換する方法 | This page is {{PAGENAME}} in our wiki about Python packaging and deployment |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Python]]
Pythonその他 - 実行ファイル
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse