🐍

pyenvのPythonでpy2appを使うときに注意すること[M1対応]

commits3 min read

はじめに

この記事は、Macのpyenv環境のPythonで、tkinterを使ったプログラムをpy2appで.app化するときのエラーハンドリングを紹介するものです。

環境

  • macOS Catalina 10.15.7
  • pyenv 1.2.21-1-g943015eb
  • Python 3.9.0
  • tk 8.6
  • tcl 8.6
  • py2app 0.23

解決策は後述しますが、py2appのバージョンが0.22以前だと、app化の際、バグでDATA_FILESに指定したフォルダーがコピーされません。注意してください。

つくったGUIアプリが起動しない!py2appがエラー吐いちゃう!

macOSでのpyenv環境では、オプションを指定せずにインストールしたPythonとtkinterを使ってアプリをつくっても、いざ起動するとエラーを吐いてしまったり、それをなんとかしても今度はpy2app使用時にエラーを吐いてしまったりします。

解決策

結論から言ってしまうと、py2appではpythonをフレームワークとして使って.appにしていますが、pyenvのPythonはデフォルトではフレームワークとして使えないので、Pythonをインストールする際にオプションをつける必要があります。また、tkinterやそのラッパーライブラリを使う場合、また別のオプションを追加する必要があります。したがって、次のようにpyenvからインストールする必要があります。

2021年3月29日追記
M1チップ搭載macOS Big Sur 11.2.2,Python 3.9.2(その他同じ環境)で試したところ、app化するための--enable-frameworkを指定したところでエラーを吐いてしまうので、--enable-frameworkが使われている以下の方法ではできません(tkinterを使うだけなら以下の方法でできます)。また、PythonはM1には3.9.1から対応していることに注意してください。

tkinterを使ったアプリをpy2appでapp化したい人

pythonのバージョンは自分のものに読み替えてください。

$ env \
  PATH="$(brew --prefix tcl-tk)/bin:$PATH" \
  LDFLAGS="-L$(brew --prefix tcl-tk)/lib" \
  CPPFLAGS="-I$(brew --prefix tcl-tk)/include" \
  PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
  CFLAGS="-I$(brew --prefix tcl-tk)/include" \
  PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I$(brew --prefix tcl-tk)/include' --with-tcltk-libs='-L$(brew --prefix tcl-tk)/lib -ltcl8.6 -ltk8.6' '--enable-framework'" \
  pyenv install 3.9.0

\で区切っているだけで1つのコマンドです

tkinterは使わないけどpy2appでapp化したい人

こちらは一行で済みます。

$ env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.9.0

app化はしないけどtkinterを使いたい人

最後の'--enable-framework'を消しただけです。

$ env \
  PATH="$(brew --prefix tcl-tk)/bin:$PATH" \
  LDFLAGS="-L$(brew --prefix tcl-tk)/lib" \
  CPPFLAGS="-I$(brew --prefix tcl-tk)/include" \
  PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
  CFLAGS="-I$(brew --prefix tcl-tk)/include" \
  PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I$(brew --prefix tcl-tk)/include' --with-tcltk-libs='-L$(brew --prefix tcl-tk)/lib -ltcl8.6 -ltk8.6'" \
  pyenv install 3.9.0

インストールしたpythonをグローバルにする

pyenv global 3.9.0

画像などを使ったアプリをapp化したら起動しなくなった!!

pngjsonなど(pythonファイル以外)へのpathを書いたファイルをapp化するとき、setup.pyに追記しなければでき上がったappは起動しません。

解決策

まずはDATA_FILESに使用するファイルの入ったディレクトリが記入されているか確認しましょう。

setup.py
"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ["src/main.py"] # app化するmainモジュール
DATA_FILES = ["asset"] # 使うファイルが入ったディレクトリのpathのリストを書く

setup(
    app=APP,
    data_files=DATA_FILES,
    setup_requires="py2app",
    )

それでも解決しない場合

使っているpy2appのバージョンが0.22以前だと、本来ならdist/**.app/Contents/Resouces内にDATA_FILESで指定したディレクトリをコピーするはずが、バグでコピーされないようです。
py2appのアップデートを行うか、手動でResoucesにコピーしましょう。

おわりに

ここまでお読み頂きありがとうございました!
py2app関連で困っている人がちらほらいたので、記事にしてみました。

GitHubで編集を提案

Discussion

ログインするとコメントできます