2021年10月03日

LuaAppMaker の AppImage を作る

 Raspberry Pi Desktop for PC で LuaAppMaker のビルドに成功したので、次に AppImage を作ってみたい。

AppImage provides a way for upstream developers to provide “native” binaries for Linux users just the same way they could do for other operating systems. It allow packaging applications for any common Linux based operating system, e.g., Ubuntu, Debian, openSUSE, RHEL, CentOS, Fedora etc.

Introduction - AppImage Document

 作り方がなかなか理解できなくて、いろいろなページを何度も行ったり来たりした。主に拠り所にしたのは "Creating an Appdir Manually" です。ポイントは、こういうことのようです。

  • 下のような構成のディレクトリを作成する。$(execname) はアプリ名。
    AppRun               #  usr/bin/$(execname) へのシンボリックリンク
    $(execname).desktop  #  デスクトップファイルへのシンボリックリンク
    usr                  #  下記参照
    $(execname).png      #  アイコンファイルへのシンボリックリンク
    
  • usr の中身は下の通り。
    bin                  #  実行ファイル $(execname) が入る
    lib                  #  $(execname) が必要とする共有ライブラリが入る
    share                #  アイコンファイル、デスクトップファイルなどの本体が入る
    
  • アイコンファイルの本体は usr/share/icons/hicolor/128x128/apps の中に置く。128x128 は 128x128 の PNG ファイルの場合で、他の解像度 (16x16, 32x32, 64x64, 256x256, scalable) の場合はそれぞれの名前のディレクトリ中に置く。
  • デスクトップファイルの本体は usr/share/applications/$(execname).desktop に置く。中身は下の通り(規格があるみたいだけど、まだ調べてない)。
    [Desktop Entry]
    Name=${execname}      #  アプリ名
    Exec=${execname}      #  実行ファイル名
    Icon=${iconbasename}  #  アイコンファイル名(拡張子なし!)
    Type=Application      #  アプリのタイプ
    Categories=Utility;   #  アプリのタイプ
    

 大事なのは usr/lib の中の共有ライブラリ。実行に必要なライブラリをここにコピーして、実行ファイルに同梱するのがポイントです。必要なライブラリ全部というわけではなく、「このファイルは(システムのライブラリを使うので)コピーすべからず」というのも決まっています(https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist 参照)。

 この作業を自動的にやってくれるのが、linuxdeploy というツールです。ドキュメントは linuxdeploy user guide にあります。linuxdeploy 自体も AppImage として提供されています。

$ linuxdeploy-i386.AppImage -e $(EXECPATH)/$(EXECNAME) -l $(LUAJIT_LIB) -d $(EXECNAME).desktop -i $(ICONNAME).png --appdir $(EXECNAME).AppDir

 ディレクトリを正しい形式で作成したら、appimagetool で AppImage 化する。https://github.com/AppImage/AppImageKit/releases にあります。なんで linuxdeploy の AppImage は i386 で、appimagetool の AppImage は i686 なのかは謎です。ビルドオプションが違うのかも?

$ appimagetool-i686.AppImage $(EXECNAME).AppDir

 一応できたんだけど、AppImage のサイズは 69 MB もありました。これは、単体配布するアプリとしては、ちょっと許容できないサイズです。このサイズが平気な人もいるだろうけど、Mac 版も Windows 版も 20 MB ぐらいなので(圧縮するともっと小さくなる)、これに近いサイズには収めたい。

 たぶんでかい共有ライブラリを組み込んでいるからだろう、と当たりをつけて、共有ライブラリのサイズを調べてみた。

$ cd LuaAppMaker.AppDir/usr/lib
$ ls -lS
-rw-r--r--  1 nagata  staff  58945244  9 21 23:26 libwebkit2gtk-4.0.so.37
-rw-r--r--  1 nagata  staff  27193712  9 21 23:26 libicudata.so.63
-rw-r--r--  1 nagata  staff  15395920  9 21 23:26 libjavascriptcoregtk-4.0.so.18
-rw-r--r--  1 nagata  staff   8561644  9 21 23:26 libgtk-3.so.0
-rw-r--r--  1 nagata  staff   3606796  9 21 23:26 libicui18n.so.63
-rw-r--r--  1 nagata  staff   2056764  9 21 23:26 libicuuc.so.63
...(以下略)

 はー、wxWebView 絡みですね。wxWebView にはいろいろ苦労させられるな。

 wxWebView は絶対にないといけない、というものでもない。wxwebview の存在を実行中にチェックして、なければ wxLaunchDefaultBrowser でブラウザに任せてしまう、というのもアリだとは思う。

if wxwebview then
  local webview = wxwebview.wxWebView.New(...)
  webview:LoadURL(url)
else
  wx.wxLaunchDefaultBrowser(url)
end

 一方、システムが libwebkit2gtk-4.0 を持っている場合は、それを使って wxWebView をサポートできるのなら、それに越したことはない。LuaAppMaker 本体は wxWebView サポートを外しておき、立ち上がった後に dlopen() でサポートコードを読み込んで、ロードできたら wxWebView をサポートし、できなかったらサポートしない、というやり方がベスト。次はこれをやります。

Posted at 2021年10月03日 11:11:12
email.png