記事の内容
Macでpyinstallerを使ってPythonコードから実行ファイルを生成した時の記録です。
Pythonコード
import sys
print(sys.path)
print(f"__name__ = {__name__}")
print(f"__file__ = {__file__}")
pyinstaller実行とエラーメッセージ
pipでインストールしたpyinstallerを使用し、端末で以下を実行しました。
pyinstaller print_sys_path.py --onefile
以下のようにPython library not foundエラーが出ました。
71 INFO: PyInstaller: 3.6
71 INFO: Python: 3.7.4
83 INFO: Platform: Darwin-19.2.0-x86_64-i386-64bit
(中略)
OSError: Python library not found: libpython3.7m.dylib, .Python, libpython3.7.dylib, Python
This would mean your Python installation doesn't come with proper library files.
This usually happens by missing development package, or unsuitable build parameters of Python installation.
* On Debian/Ubuntu, you would need to install Python development packages
* apt-get install python3-dev
* apt-get install python-dev
* If you're building Python by yourself, please rebuild your Python with `--enable-shared` (or, `--enable-framework` on Darwin)
対処その1 (1回目の--enable-sharedで失敗)
pyenvでPythonをインストールするときのオプションに「--enable-shared」を使用。
端末で以下を実行しました。
PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.4
以下のように表示されて、3.7.4が上書きインストールされました。
pyenv: /Users/username/.pyenv/versions/3.7.4 already exists
continue with installation? (y/N) y
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.7.4.tar.xz...
-> https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tar.xz
Installing Python-3.7.4...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.7.4 to /Users/username/.pyenv/versions/3.7.4
使用されるPythonを確認します。
$ pyenv global
3.7.4
pyinstallerを起動したら、以下のようにまだPython library not foundエラーが出ました。
$ pyinstaller print_sys_path.py --onefile
(中略)
OSError: Python library not found: Python, libpython3.7.dylib, .Python, libpython3.7m.dylib
This would mean your Python installation doesn't come with proper library files.
This usually happens by missing development package, or unsuitable build parameters of Python installation.
* On Debian/Ubuntu, you would need to install Python development packages
* apt-get install python3-dev
* apt-get install python-dev
* If you're building Python by yourself, please rebuild your Python with `--enable-shared` (or, `--enable-framework` on Darwin)
.dylibファイルが見つからないと叱られているので、以下のようにfindコマンドで場所を探して、
find $HOME -name 'libpython3*.dylib' 2> /dev/null
LD_LIBRARY_PATH環境変数にlibpython3.7m.dylibの場所を指定して実行してみましたが、以下のようにPython library not foundエラーのままでした。
$ LD_LIBRARY_PATH=/Users/username/.pyenv/versions/3.7.4/lib pyinstaller print_sys_path.py --onefile
(中略)
OSError: Python library not found: .Python, Python, libpython3.7m.dylib, libpython3.7.dylib
This would mean your Python installation doesn't come with proper library files.
This usually happens by missing development package, or unsuitable build parameters of Python installation.
* On Debian/Ubuntu, you would need to install Python development packages
* apt-get install python3-dev
* apt-get install python-dev
* If you're building Python by yourself, please rebuild your Python with `--enable-shared` (or, `--enable-framework` on Darwin)
対処その2 (--enable-frameworkで成功)
pyenvでPythonをインストールするときのオプションに「--enable-framework」を使用。
端末で以下を実行しました。
PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.7.4
以下のように表示されて、3.7.4が上書きインストールされました。
pyenv: /Users/username/.pyenv/versions/3.7.4 already exists
continue with installation? (y/N) Y
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.7.4.tar.xz...
-> https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tar.xz
Installing Python-3.7.4...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.7.4 to /Users/username/.pyenv/versions/3.7.4
pyinstallerを起動したら、以下のように「pyinstallerがない」というエラーが出ました。
$ LD_LIBRARY_PATH=/Users/username/.pyenv/versions/3.7.4/lib pyinstaller print_sys_path.py --onefile
-bash: /Users/username/.pyenv/shims/pyinstaller: No such file or directory
pyinstallerの再インストールを試みたら、以下のように「既にある」と言われました。
$ pip install pyinstaller
Requirement already satisfied: pyinstaller in /Users/username/.pyenv/versions/3.7.4/lib/python3.7/site-packages (3.6)
Requirement already satisfied: altgraph in /Users/username/.pyenv/versions/3.7.4/lib/python3.7/site-packages (from pyinstaller) (0.17)
Requirement already satisfied: setuptools in /Users/username/.pyenv/versions/3.7.4/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyinstaller) (40.8.0)
Requirement already satisfied: macholib>=1.8 in /Users/username/.pyenv/versions/3.7.4/lib/python3.7/site-packages (from pyinstaller) (1.14)
訳がわからなくなりました!
試行錯誤の結果、以下のようにアンインストール→インストールの手順で、pyinstallerを再インストールできました。
$ pip uninstall pyinstaller
Uninstalling PyInstaller-3.6:
Would remove:
/Users/username/.pyenv/versions/3.7.4/lib/python3.7/site-packages/PyInstaller-3.6.dist-info/*
/Users/username/.pyenv/versions/3.7.4/lib/python3.7/site-packages/PyInstaller/*
Proceed (y/n)? Y
Successfully uninstalled PyInstaller-3.6
$ pip install pyinstaller
Processing /Users/username/Library/Caches/pip/wheels/62/fe/62/4c0f196d1e0dd689e097449bc81d7d585a7de7dd86b081b80b/PyInstaller-3.6-cp37-none-any.whl
Requirement already satisfied: setuptools in /Users/username/.pyenv/versions/3.7.4/Python.framework/Versions/3.7/lib/python3.7/site-packages (from pyinstaller) (40.8.0)
Requirement already satisfied: macholib>=1.8 in /Users/username/.pyenv/versions/3.7.4/lib/python3.7/site-packages (from pyinstaller) (1.14)
Requirement already satisfied: altgraph in /Users/username/.pyenv/versions/3.7.4/lib/python3.7/site-packages (from pyinstaller) (0.17)
Installing collected packages: pyinstaller
Successfully installed pyinstaller-3.6
以下のように再びpyinstallerを起動したら、distディレクトリの下に実行ファイルが生成されました。
LD_LIBRARY_PATHを指定しましたが、指定しなくても動くようです。
LD_LIBRARY_PATH=/Users/username/.pyenv/versions/3.7.4/lib pyinstaller print_sys_path.py --onefile
生成された実行ファイルを起動しました(成功)。
dist/print_sys_path
['/var/folders/kc/blch89657dv8zrzlxjljz6f40000gr/T/_MEInZMCQo/base_library.zip', '/var/folders/kc/blch89657dv8zrzlxjljz6f40000gr/T/_MEInZMCQo']
__name__ = __main__
__file__ = print_sys_path.py
対処その3 (2回目の--enable-sharedで成功)
1回目の--enable-sharedは失敗しましたが、再び--enable-sharedでインストールしたら成功するようになっていたので、記録しておきます。
pyenvでPythonのインストール:
$ PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.4
pyenv: /Users/username/.pyenv/versions/3.7.4 already exists
continue with installation? (y/N) y
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.7.4.tar.xz...
-> https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tar.xz
Installing Python-3.7.4...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.7.4 to /Users/username/.pyenv/versions/3.7.4
pyinstaller起動:
pyinstaller print_sys_path.py --onefile
生成された実行ファイルを起動:
$ dist/print_sys_path
['/var/folders/kc/blch89657dv8zrzlxjljz6f40000gr/T/_MEIf6CW7m/base_library.zip', '/var/folders/kc/blch89657dv8zrzlxjljz6f40000gr/T/_MEIf6CW7m']
__name__ = __main__
__file__ = print_sys_path.py
pipenvでも試します。
pyinstaller起動:
pipenv run pyinstaller print_sys_path.py --onefile
生成された実行ファイルを起動:
$ dist/print_sys_path
['/var/folders/kc/blch89657dv8zrzlxjljz6f40000gr/T/_MEIPYS34b/base_library.zip', '/var/folders/kc/blch89657dv8zrzlxjljz6f40000gr/T/_MEIPYS34b']
__name__ = __main__
__file__ = print_sys_path.py
対処その1でうまく動かなかった理由
たぶん、pyenvでPythonを上書きインストールしたら、pipでインストールされていたものも再インストール(uninstall → install)が必要なんだろうと思います。
対処その1でPythonを上書きインストールしたけど、pyinstallerは以前から入っていたものをそのまま使ったので、同じエラーが発生してしまったのでしょう。