search
LoginSignup
129
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Organization

Pythonスクリプトを単一実行ファイルにする方法

はじめに

Pythonを配布しやすいように、実行可能形式で配布できたらいいのに…ということで、今回は、pythonスクリプトを単一の実行可能形式にする方法を解説します。
あくまで、覚書ですので、参考までにどうぞ。

インストール

Python で ファイルを 単一実行ファイル化するには pyinstaller を使用します。まずは pyinstaller をインストールしましょう。
基本的には以下のコマンドでインストールできます

pip install pyinstaller

環境によっては

pip3 install pyinstaller

や、組み込み用のpythonの場合は

python -m pip install pyinstaller

のように実行します、注意点としてはpipで以下のようなエラーが出た場合

Traceback (most recent call last):
  File "/usr/bin/pip", line 9, in <module>
    from pip import main
ImportError: cannot import name main

は、

python -m pip install pyinstaller

と、pipモジュールを指定して呼ぶか、/usr/bin/pipをvimなどで開いて

# -*- coding: utf-8 -*-
import re
import sys

from pip._internal import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

と書き換えてしまいましょう、場合によっては

from pip import main
if __name__ == '__main__':
    sys.exit(main())

の部分を

from pip import __main__
if __name__ == '__main__':
    sys.exit(__main__._main())

と書き換えることでも対応できます

実際に作成してみよう

基本的に、以下の形式で実行します

pyinstaller pythonファイル名 [--onefile] [--noconsole] [--windowed]
  • よく使うオプション
挙動 オプション 概要
コンパイルする --onefile 関連するファイルを1つにまとめてバイナリ化します
非コンソール表示 --noconsole コンソールアプリでもコンソール表示をしないようにします
Windowsバイナリ生成 --windowed 異なるプラットフォームでもWindowsのバイナリを作ります
データバインド --add-data バイナリ内部にファイルを取り込みます
管理者モード実行 --uac-admin --uac-uiaccess 管理者モードで実行するバイナリを作ります

よくあるサンプル

hello.py
#!/usr/bin/python

# -*- coding: utf-8 -*-

print("hello world")
#Mac Linuxの場合
pyinstaller hello.py --onefile

#Windowsの場合
pyinstaller hello.py --onefile --windowed 

実際に実行したログ

pyinstaller hello.py --onefile
302 INFO: PyInstaller: 3.4
302 INFO: Python: 3.4.8
302 INFO: Platform: Linux-3.10.0-693.11.1.el7.x86_64-x86_64-with-centos-7.4.1708-Core
303 INFO: wrote /home/pyuser/hello.spec
326 INFO: UPX is not available.
327 INFO: Extending PYTHONPATH with paths
['/home/pyuser', '/home/pyuser']
327 INFO: checking Analysis
327 INFO: Building Analysis because Analysis-00.toc is non existent
328 INFO: Initializing module dependency graph...
346 INFO: Initializing module graph hooks...
347 INFO: Analyzing base_library.zip ...
25932 INFO: Processing pre-find module path hook   distutils
49391 INFO: running Analysis Analysis-00.toc
49967 INFO: Caching module hooks...
50029 INFO: Analyzing /home/pyuser/hello.py
50189 INFO: Loading module hooks...
50190 INFO: Loading module hook "hook-pydoc.py"...
50190 INFO: Loading module hook "hook-encodings.py"...
51815 INFO: Loading module hook "hook-distutils.py"...
51817 INFO: Loading module hook "hook-xml.py"...
58878 INFO: Looking for ctypes DLLs
58960 INFO: Analyzing run-time hooks ...
59001 INFO: Looking for dynamic libraries
63887 INFO: Looking for eggs
63887 INFO: Using Python library /lib64/libpython3.4m.so.1.0
63929 INFO: Warnings written to /home/pyuser/build/hello/warn-hello.txt
64350 INFO: Graph cross-reference written to /home/pyuser/build/hello/xref-hello.html
64534 INFO: checking PYZ
64534 INFO: Building PYZ because PYZ-00.toc is non existent
64534 INFO: Building PYZ (ZlibArchive) /home/pyuser/build/hello/PYZ-00.pyz
68757 INFO: Building PYZ (ZlibArchive) /home/pyuser/build/hello/PYZ-00.pyz completed successfully.
68879 INFO: checking PKG
68879 INFO: Building PKG because PKG-00.toc is non existent
68880 INFO: Building PKG (CArchive) PKG-00.pkg
90765 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully.
90806 INFO: Bootloader /usr/lib/python3.4/site-packages/PyInstaller/bootloader/Linux-64bit/run
90806 INFO: checking EXE
90806 INFO: Building EXE because EXE-00.toc is non existent
90807 INFO: Building EXE from EXE-00.toc
90807 INFO: Appending archive to ELF section in EXE /home/pyuser/dist/hello
91052 INFO: Building EXE from EXE-00.toc completed successfully.

実行すると、buildとdistというフォルダが作成されます。
大体の場合、以下のような構造になると思います。

./hello.py
./hello.spec
./build/hello/base_library.zip
./build/hello/warn-hello.txt
./build/hello/xref-hello.html
./build/hello/Analysis-00.toc
./build/hello/PYZ-00.pyz
./build/hello/PYZ-00.toc
./build/hello/PKG-00.pkg
./build/hello/PKG-00.toc
./build/hello/EXE-00.toc
./dist/hello
./__pycache__
./__pycache__/hello.cpython-34.pyc

dist以下にできているものが、生成された単一ファイルで、そのほかのファイルは生成時の中間ファイルになります。
上記はCentOS7.4上で実行しています、とりあえず実行してみましょうか

./dist/hello
hello world

単一コマンドにしてしまえば、配布も楽ですね

さいごに

pythonの単一ファイル化は他にも方法がありますので、ここで説明しているのは一例にすぎません
あくまで参考にしてください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
129
Help us understand the problem. What are the problem?