mikutter 3.9.0のalpha3がリリースされました。
このバージョンから、ゆんたん氏がリクエストしていたAppImage形式での配布がとりこまれました。よくわかっていなかったんですが、mikutterとかそれに必要なソフトとかライブラリとかをまとめて1バイナリパッケージ化して、同じアーキテクチャならそのまま動かせるぜというやつしいです。goといいそういう感じの時代なんですね。いいやん。
AppImage | Linux apps that run anywhere
で、ひとまずx86_64版が公開されたわけですが、頑張ればラズピッピ向けも行けるのかなと思って、この週末ちょっとチャレンジしてました。結果から言うと、できました。
環境
Raspbian Buster 2019-06-10
Docker環境を作る
Busterのdocker.ioパッケージはカーネルオプションがなんちゃらの罠を踏むので、Docker-ceのDebian Busterのナイトリービルドを使いました。
sudo vi /etc/apt/source.list.d/docker.list deb https://download.docker.com/linux/debian/ buster nightly
んでインストール。後で必要に無るパッケージもここでまとめて入れてします。あとaufs-dkmsは一緒に入るけど動かないので消してしまいました。
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - sudo apt update sudo apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common cmake libjpeg-dev cimg-dev docker-ce docker-ce-cli containerd.io patchelf sudo gpasswd -a pi docker sudo apt remove -y aufs-dkms
mikutterのスクリプトを読む
mikutterのdeployment/appimage以下に作成のためのDockerfile、スクリプト、説明があるので、それを読みます。gen_appimage.shを読むと、linuxdeploy.AppImage、exec.soの部分でGitHubからx86_64版をダウンロードするように書かれていたので、これをarmhf版に書き換えればOK…かと思いきや、どちらもarmhf版は提供されていませんでした。
building exec.so for armhf
こちらはかんたん。
cd ~ git clone https://github.com/darealshinji/AppImageKit-checkrt cd AppImageKit-checkrt make -j4 cp exec.so ~/mikutter/deployment/appimage/
building linuxdeploy.AppImage for armhf (失敗) (1)
そのままコンパイルしたらlinuxdeployのバイナリができたので組み込んだら、オプションがないとか言われました。それもそのはず、コンパイルしてできたlinuxdeployは素の状態で、それにプラグインを足してAppImage化したものが必要だったのでした。
travis/build.shにある内容がAppImageまで作る手順でした。これを読むとlinuxdeploy-plugin-appimage-armhf.AppImageが別途必要そうです。これを先にビルドします。
(7/5追記)linuxdeploy-plugin-appimage-armhf.AppImageを作るには上記でできた素のlinuxdeployが必要でした。ここでのコンパイルは必要です。
building linuxdeploy-plugin-appimage-armhf.AppImage for armhf
こちらもtravis/build-appimage.shにAppImageを作るまでの手順が書かれていましたが、travisのことは知らないのでリポジトリのルートにコピーして、パス周りを書き換えて無理やりビルドしました。
cd ~ git clone https://github.com/linuxdeploy/linuxdeploy-plugin-appimage cd linuxdeploy-plugin-appimage cp travis/build-appimage.sh . vi build-appimage.sh <いじるとこ> ・cleanupを無力化。失敗するとソースコードが全部消えるので。 ・以下2行を冒頭に追記 BUILD_DIR=$(pwd) ARCH=armhf ・ARCHのif分岐にarmhfを追加する。中身はなくてもOKでした。 elif [ "$ARCH" == "armhf" ]; then EXTRA_CMAKE_ARGS=() (下記2点7/5追記) ・linuxdeployのダウンロードをコメントアウト ・deploy linuxdeploy-plugin-appimageのコマンドを前項でできたlinuxdeployに差し替える
いじり終わったらビルド実行。
./build-appimage.sh
linuxdeploy-plugin-appimage-armhf.AppImageができたことを確認します。
building linuxdeploy.AppImage for armhf again (2)
同じくtravis/build.shをリポジトリのルートにコピーして編集します。
cd ~ git clone https://github.com/linuxdeploy cd linuxdeploy cp travis/build.sh . vi build.sh ・cleanupを無力化。同じ理由。 ・冒頭に2行を追記 BUILD_DIR=$(pwd) ARCH=armhf ・ARCHのif分岐にarmhfを追加する。こちらも中身はなくてもOK。 elif [ "$ARCH" == "armhf" ]; then EXTRA_CMAKE_ARGS=() ・linuxdeploy-plugin-appimage-"$ARCH".AppImageをコピーしてきて使うように書き換える #wget https://github.com/TheAssassin/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-"$ARCH".AppImage cp ~/linuxdeploy-plugin-appimage/linuxdeploy-plugin-appimage-"$ARCH".AppImage .
そしてビルド実行。armhf版linuxdeploy.AppImageが入手できました。
./build.sh
building mikutter.AppImage for armhf
とりあえずmikutterのコードを用意。
cd ~ git clone git://toshia.dip.jp/mikutter.git cd ~/mikutter/deployment/appimage/ git checkout develop
編集内容はgistに貼りました。
mikutterのappimageを実行した環境のアーキテクチャでやっていきする改変と、gir1.2-glib-2.0はいるんじゃないですかねえしらんけど · GitHub
がざっくり解説。
作成したexec.soとlinuxdeploy.AppImageは、bin/armhfディレクトリを掘ってその中に入れました。もしi386とか作りたくなったらここにi386ディレクトリを掘れば多分いいです。
Dockerfileをいじります。
- FROM debian:busterに変える。linuxdeployをビルドした環境より新しいglibc6とlibstdc++が必要になるため
- libgdbm3をlibgdbm6に書き換え
- gir1.2-glib-2.0が足りないっぽかったので追加
- binディレクトリをコピーする行の追加
ubuntuのままがよい場合は、18.10以上にするか、Ubuntu 16.04のglibc6とlibstdc++よりふるいバージョンを採用したRaspbianでlinuxdeployを作る必要がありそうです(すくなくともStretchではだめっぽいです)。
gen_appimage.shの編集は変に気を利かせていろいろいじってしまったのでdiffを見てほしいです。
- ARCH変数を活用したが、あんな方法でいいのか私にはわからない……
- wgetでexec.soとかlinuxdeploy.AppImageを拾うところを、ファイルがbin/$ARCH/にあれば適宜mvして、なければwgetするようにした
いじったら、README.mdと同じ手順でビルドを開始します。REVISIONはどこで使われているのかわからんかったのですが、とりあえず指定はしました。SSDをUSB接続したRPi 3B+で1時間くらい気長に待つと終わります。必要に応じてscreenとか張ってSSHが切れてもいいようにしておくと良いです。
export REVISION=develop docker build -t mikutter-build-appimage . && docker run --rm -v $PWD/volume:/volume -v $(git rev-parse --show-toplevel):/mikutter-src:ro -it mikutter-build-appimage
ビルドが問題なく終わると、volumesの下にmikutter-3.9.0-alpha2-armhf.AppImageができます。alpha3じゃなかったのか?さておき、これをVNC接続したRaspberry Piデスクトップ上で実行すると、(gtkがどうとか出るけど)mikutterが動きました。
まとめ
mikutterをインストールするAnsible Playbook(わたしのRPi-toolsリポジトリに入ってる)を書いたりなんかもしましたけど、これはいい時代になったわねェという感想です。Raspberry Piという(arm)環境では作れるようになるまでとビルド時間がだるい感じですが、ジョブ的に実行できれば別に良さそうですし、Raspberry Pi 4が日本でも使えるようになればもっと高速にビルドできることでしょう。
私がビルドしたブツはGoogle Driveにぶん投げたので、他人のビルドが怖くない人は試してみたらいいと思います。
先週のガッツリ発熱風邪に続いて鼻風邪で鼻水を垂らしながらでしたが、久々に面白いものがいじれたので楽しかったです。
ただし、まだ終わらない
mikutter-3.9.0-alpha2-armhf.AppImageはできるんですが、RPi2以降でしか動きません。言い換えるとRPi1とZeroでは動きません。なのでmikutter-3.9.0-alpha2-armv7l.AppImageとなるべきところですが、私のgen_appimage.sh改変が雑なのがよろしくない感じでした。
そもそもarmhfとかarmv7l/armv6lとかarm-linux-gnueabihfを取得する適切な方法というか、それぞれの呼称とかってどうなんでしたっけね……?