QuickIR を py2app で Macのアプリケーションにしてみた
参照:py2app - Create standalone Mac OS X applications with Python
アプリにした方が起動しやすいですものね
長いこと放ったらかしでしたが、久しぶりに QuickIR の話です。py2app を使って QuickIRを Macのアプリケーションにしてみました。とは言え、py2app をインストールしたのは随分前のことで、以前アプリケーション化にトライした時にはうまくいかず挫けたので、py2appのインストール方法については書き残したものがありません。記憶も曖昧なので、正しくないかも知れませんので、もし間違っていても御容赦ください。
参考URL:py2app - Create standalone Mac OS X applications with Python
1. pip3 を使って py2app をインストールする
py2app は Pythonのスクリプトを Mac OS X (macOS) のアプリケーションに変換してくれるツールです。先ず、これをインストールします。インストールには pip3 というPythonのパッケージ管理ツールを使用します。
$ pip3 --version ※pip3のバージョンを確認しています
pip 8.1.2 from /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages (python 3.5)
$ sudo pip3 install -U pip ※pip3を最新版にします(既に最新版の場合は不要)
$ sudo pip3 install -U py2app ※py2appをインストールします
$ pip3 list | grep py2app
py2app (0.10) ※py2app 0.10 がインストールされました
|
py2appのインストール方法には、他にも easy_install を使用する等がありますので、py2app - Create standalone Mac OS X applications with Pythonの「Installation」を参照してください。
2. setup.py を作成する
以下のようにして setup.py の雛形を作成します。以下で使用している py2applet は py2app パッケージに含まれているツールです。ここではアプリケーション化したいPythonスクリプト"QuickIR.py" を指定して setup.py の雛形を作成させています。
$ py2applet --make-setup QuickIR.py
Wrote setup.py
|
作成される setup.py の内容はこんな感じになります。
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
APP = ['QuickIR.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
3. setup.py を編集する
作成された setup.py を編集します。編集した箇所は赤字の部分です。
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
APP = ['QuickIR.py']
APP_NAME = 'QuickIR'
DATA_FILES = ['images/file_add.gif',
'images/file_delete.gif',
'images/file_post.gif',
'images/file_rename.gif',
'images/folder_add.gif',
'images/folder_delete.gif',
'images/folder_rename.gif',
'images/IRKit.gif']
OPTIONS = {
'argv_emulation': False,
'iconfile': 'app.icns',
'includes': ['irkit', 'resolve_irkit', 'pybonjour'],
'strip': True,
'plist': {
'CFBundleName': APP_NAME,
'CFBundleDisplayName': APP_NAME,
'CFBundleGetInfoString': "QuickIR IRKit controller 1.0.7",
'CFBundleIdentifier': "jp.ddo.y-naito.QuickIR",
'CFBundleVersion': "1.0.7",
'CFBundleShortVersionString': "1.0.7",
'NSHumanReadableCopyright': "Copyright (C) 2015-2016, N@i, All Rights Reserved"
}
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
|
以下、修正した内容について説明します。
DATA_FILES リスト
DATA_FILES リストには、アプリケーション内に取り込みたいファイルを記述します。QuickIRでは、いくつか画像ファイルを使用していますので、これを取り込むようにしています。
OPTIONS 辞書
OPTIONS には辞書形式で py2app へのオプションを記述します。
'argv-emulation' オプション
'argv-emulation' オプションは argvエミュレーションを使用するかどうかを指定するオプションだそうです。原因は良く分かってないのですが、これがTrueだとGUIアプリの場合は画面が表示されないことがあるので、Falseにしています。
'iconfile' オプション
'iconfile' オプションにはアプリケーションのアイコンファイル(.icns)を指定します。アイコンファイルは著作権フリーの素材を利用しても良いでしょうし、作成するためのツールもいくつかあるようです。色々探してみると結構楽しめます。
'includes' オプション
'includes' オプションには、アプリケーションのPythonスクリプトが importしているスクリプト、パッケージを記述します。たぶん記述しなくても py2app が追跡してくれると思うのですが、念のため QuickIR.py が importしている自分のPythonモジュールと pybonjour を記述しています。
'strip' オプション
'strip' オプションは、アプリケーションに組み込むライブラリ等からシンボル情報を削除します。Python環境がインストールされていない環境でも動作するアプリケーションを作成しようとすると、かなり多くのフレームワーク/ライブラリ群が組み込まれるので、サイズが結構大きくなります。シンボル情報を削除することで、僅かながらサイズを小さくすることができるのではないかと思います。
'plist' オプション
'plist' オプションには、アプリケーションの「情報を見る」で表示される「一般情報」を辞書形式で記述します。このオプションは指定しなくてもアプリケーションを作ることはできますので、面倒だったら無くても構いません。詳しい内容は、py2app - Create standalone Mac OS X applications with Pythonの「Tweaking your Info.plist」に書かれていますので、参照してください。
4. アプリケーションを作成する
いよいよ QuickIR アプリケーションを作成します。
$ rm -rf build dist ※アプリケーション作成時に作成されるディレクトリです。念のため掃除しておきます。
$ python3 setup.py py2app -A
running py2app
creating /Users/hoge/work/QuickIR/build
creating /Users/hoge/work/QuickIR/build/bdist.macosx-10.6-intel
creating /Users/hoge/work/QuickIR/build/bdist.macosx-10.6-intel/python3.5-standalone
creating /Users/hoge/work/QuickIR/build/bdist.macosx-10.6-intel/python3.5-standalone/app
creating /Users/hoge/work/QuickIR/build/bdist.macosx-10.6-intel/python3.5-standalone/app/collect
creating /Users/hoge/work/QuickIR/build/bdist.macosx-10.6-intel/python3.5-standalone/app/temp
creating /Users/hoge/work/QuickIR/dist
creating build/bdist.macosx-10.6-intel/python3.5-standalone/app/lib-dynload
creating build/bdist.macosx-10.6-intel/python3.5-standalone/app/Frameworks
*** creating application bundle: QuickIR ***
Done!
|
このように出力されればアプリケーション作成成功です。./dist配下にアプリケーション(QuickIR.app)が作成されているはずです。
しかし、このままではアプリケーションをダブルクリックしても正常に動作しないはずです。QuickIRの場合、以下のようなダイアログが出てしまいました。
「Terminate」ボタンをクリックすると終了してしまいます。これでは動作しない原因が分からないので「Open Console」の方をクリックし、コンソールを表示させます。コンソールが表示されたら、検索フィールドにアプリケーション名(QuickIR)を入力すると、そのアプリケーションに関するメッセージのみが表示されますので、これでエラー原因を探ります。
すると、今回の場合は画像ファイルが見つからないことが原因と分かります。この画像ファイルは setup.py のDATA_FILES に指定してアプリケーション内に取り込んだはず。と言うことで、問題の画像ファイルがアプリケーション内の何処にあるのか見てみます。
$ cd ./dist/QuickIR.app/Contents/Resources/
$ ls -l
total 96
lrwxr-xr-x 1 hoge admin 40 10 23 11:28 IRKit.gif -> /Users/hoge/work/QuickIR/images/IRKit.gif
-rw-r--r-- 1 hoge admin 2689 10 23 11:28 __boot__.py
-rwxrwxr-x 1 hoge admin 559 9 23 20:17 __error__.sh
drwxr-xr-x 4 hoge admin 136 10 23 11:28 __pycache__
lrwxr-xr-x 1 hoge admin 32 10 23 11:28 app.icns -> /Users/hoge/work/QuickIR/app.icns
lrwxr-xr-x 1 hoge admin 43 10 23 11:28 file_add.gif -> /Users/hoge/work/QuickIR/images/file_add.gif
lrwxr-xr-x 1 hoge admin 46 10 23 11:28 file_delete.gif -> /Users/hoge/work/QuickIR/images/file_delete.gif
lrwxr-xr-x 1 hoge admin 44 10 23 11:28 file_post.gif -> /Users/hoge/work/QuickIR/images/file_post.gif
lrwxr-xr-x 1 hoge admin 46 10 23 11:28 file_rename.gif -> /Users/hoge/work/QuickIR/images/file_rename.gif
lrwxr-xr-x 1 hoge admin 45 10 23 11:28 folder_add.gif -> /Users/hoge/work/QuickIR/images/folder_add.gif
lrwxr-xr-x 1 hoge admin 48 10 23 11:28 folder_delete.gif -> /Users/hoge/work/QuickIR/images/folder_delete.gif
lrwxr-xr-x 1 hoge admin 48 10 23 11:28 folder_rename.gif -> /Users/hoge/work/QuickIR/images/folder_rename.gif
drwxr-xr-x 3 hoge admin 102 10 23 11:28 lib
-rw-rw-r-- 1 hoge admin 3788 9 23 20:17 site.py
|
ありました。py2app に -Aオプションを指定したので、画像ファイルそのものではなくシンボリックリンクになっています。ところで、QuickIR で読み込む画像ファイルは images フォルダ配下に置かれているものと想定しています。しかし、取り込まれた画像ファイルは images フォルダ配下に置かれていません。画像ファイルが見つからない原因はこれでした。そこで、images フォルダを作成して、画像ファイルをその配下に移動させます。
$ mkdir ./images
$ mv *.gif ./images
|
これで QuickIRアプリケーションがダブルクリックで正常に起動するようになりました。アプリケーションになれば、Dock内に置くこともできます。
でも、アプリケーションを作り直す度に毎回手作業でimages フォルダを作って画像ファイルを移動させていたのでは面倒ですので、アプリケーションを作成するスクリプトを書きましょう。
作成したスクリプトはこんな感じです。
#!/bin/sh
rm -rf ./build ./dist
python3 setup.py py2app -A
cd ./dist/QuickIR.app/Contents/Resources
mkdir ./images
mv *.gif ./images/
さて、これで一応アプリケーションにはなりましたが、画像ファイルはシンボリックリンクでしたね。実は画像ファイルだけでなく、アプリケーション内のPythonやパッケージ・ライブラリ群も全てシンボリックリンクになっています。このままでは、アプリケーションを配布してもPython、パッケージ・ライブラリ群や画像ファイルが無い環境では全く動作できません。py2app の -Aオプションは aliasの意味で、(for development only!) と書かれています。つまり開発時のみに使用するオプションなのですね。
配布するためのアプリケーションを作成する際には py2app の -Aオプションを外します。すると、Pythonおよび使用しているフレームワーク、パッケージ、画像ファイル等々を全て取り込んだアプリケーションが出来上がります。QuickIR の場合、アプリケーションのサイズは44.2MBにもなりました。デカ過ぎ(^^;)。因に -Aオプション指定時のサイズは 137KBでした。
とは言え、これでPythonスクリプトを簡単にアプリケーション化できますので、Pythonスクリプトのままよりは随分と使いやすくなります。これらの Macのアプリケーション化するための setup.py, make_app.sh 等も QuickIRのソース資産に取り込みました。また、macOS Sierra 上で簡単に動作確認も行い、ドキュメントでの「Mac OS X」という表記を「Mac OS」に修正しました。(プログラムに変更はありません。)
|