ビルドマシンでビルドしたAndroidイメージをシームレスにローカルでエミュレートしたかった
最近Androidのビルドをしているのですが、手元のPCではビルドに時間がかかりすぎてしまい、なんとか高速化できないか試行錯誤してみたので、記事にしてみます。
発端
Androidのビルドは並列化することによって高速化できるのですが、そもそも手元のPC(2コア4スレッド)では4並列が限界で、1回のフルビルドに2時間近くかかっていました。
そこで、処理性能の高い(CPUコア数の多い)ビルドマシンを用意して、Androidのビルドはビルドマシンの方でおこない、ビルド成果物を用いて手元のPCでビルドしたイメージをエミュレートしたいと考えました。
試したこと
-
ramdisk.img、system.img、userdata.img
をダウンロード -
/out
をダウンロード -
sshfs
でビルドマシンの/out
をローカルにマウント -
sshfs
でローカルの/out
をビルドマシンにマウント - lsyncdで
/out
を同期する
1. system.img
をダウンロード
ビルドマシンでビルドして生成した ramdisk.img、system.img、userdata.img
をダウンロードして、手元のビルド環境の ramdisk.img、system.img、userdata.img
と置き換えてエミュレータ起動
結果: これだと上手くいかなかった。(エミュレートはできるが、古いイメージをエミュレートしている?)
2. /out
をダウンロード
ビルドマシンでビルドして生成した /out
をダウンロードして、手元のビルド環境の /out
と置き換えてエミュレータ起動
結果: 上手くいったが、 /out
をダウンロードするのに1時間以上かかってしまい、ビルドマシンで高速化した意味があまりなかった
3. sshfs
でビルドマシンの /out
をローカルにマウント
sshfsを用いて、ビルドマシンの /out
をローカルにマウントして、ビルドマシンでビルド後、ローカルで emulator
を起動
結果: エミュレータが立ち上がらなかった
4. sshfs
でローカルの /out
をビルドマシンにマウント
sshfsを用いて、ローカルの /out
をビルドマシンにマウントして、ビルドマシンでビルド後、ローカルで emulator
を起動
結果: ビルドマシンのビルド途中で、コネクションが切れてしまった
ここまで試して、「起動しない」か「起動しても遅すぎてビルドマシンを使う意味が無い」という結果になってしまいました。
6. lsyncdで /out
を同期する
Ubuntu: lsyncd によるディレクトリのリアルタイム同期(追記あり)
ビルドマシンにlsyncdをインストールして、下のような設定ファイルを用意して、ビルドマシンの /out
を手元PCの /out
に同期するようにしました。
settings {
logfile = "/var/log/lsyncd.log",
statusFile = "/tmp/lsyncd.stat",
delay = 1
}
sync {
default.rsync,
source="/home/build-machine/AOSP-9.0.0/out/",
target="local-user@xxx.xxx.xxx.xxx:/home/local-user/AOSP-9.0.0/out/",
delete=running,
rsync = {
rsh = "/usr/bin/ssh -i /home/build-machine/.ssh/id_rsa.rsync -o UserKnownHostsFile=/home/build-machine/.ssh/known_hosts"
}
}
ビルドマシン側で make clean
をした際に、手元のビルド成果物も消すために、 delete=running
にしています。
結果: 今の所いい感じ。 system.img
のrsyncに少し時間がかかるものの、ビルドマシンでのビルド後にほぼシームレスにローカルでエミュレートできている。
まとめ
lsyncdを使うことで、処理能力の高いビルドマシンでAndroidを高速ビルドしつつ、手元でエミュレートできるようになりました。
いろいろ試行錯誤の結果なのですが、もっと良い方法があれば試してみたいです。