わくわく計算ライフ

ドムプラをキメつづけるブログになりつつある。

【2023/03/04更新】WSL2でのAndroid 12ビルド作業メモ

なんか色々あってAndroidのビルド(AOSP)をしたので作業記録
usbipdのバージョンが上がったり、やり方微妙に間違えている箇所があったので更新。

1. 環境

項目 内容
ビルド環境 Windows 11 22H2 + WSL2 Ubuntu 20.04
ターゲットOS Android 12
ターゲット端末 Google Pixel3
CPU Ryzen 7 2700
Memory 32GB(結論から言うと64GBは欲しい)

せっかくなので、最近のWSL2でどこまで出来るか試しにやってみることに。

2. ビルド

基本的に公式のビルドの項を参照して作業をします。

2.1. Repoのインストール

Repoは複数のリポジトリをまとめて管理するツール。
ダウンロードのRepoの項を参照。
aptによる自動インストールではうまく行かなかったので、手動インストールを実行する。

2.2. ソースのダウンロード

こちらを参照。

ターゲット端末および入れるAndroidのバージョンが決まっているので、ビルドのブランチをこちらから選択。
Pixel 3のAndroid12の最新のビルドを選択
バージョン : android-12.0.0_r34
ビルドID : SP1A.210812.016.C2

repo init -u https://android.googlesource.com/platform/manifest -b android-12.0.0_r34
repo sync

WSL2は案外適当にやってもCPUゲストと調停して使ってくれるようで40分ぐらいでソースの取得完了。

2.3. バイナリのダウンロード

AOSPのソースだけではビルドが出来ない。
ハードウェア固有の低レベルについてはベンダーイメージとドライバーのバイナリを取得する。

ドライバー置き場

先ほど取得したソースコードのビルドID SP1A.210812.016.C2 で検索。
同じビルドIDでも対応端末ごとに、バイナリが異なるのでその中で端末がPixel 3の物を選択した。
本体であるGoogleのVendor Imageとデバイス機能であるQualcommのドライバーをダウンロードする。

repoの作業ディレクトリにて

$ curl -o temp [binaryへのリンク]
$ tar -xzvf temp

を実行することで、展開用のシェルスクリプトが取得できる。(tempは適当な名前で良い)
こちらをVendor Image, ドライバーともに実行する。

2.4. ビルドの実行

まず、ビルド用の環境設定を行う。

export LC_ALL=C
source build/envsetup.sh #環境設定
lunch

lunchを実行するとデバイスビルドの一覧が出てくるので今回はこちらでPixel 3向きにすすめられているaosp_blueline-userdebugに対応する4番を選択した。
これでビルドの準備が完了する。毎回入力するのが面倒ならlunchにaosp_blueline-userdebug(使用するビルド環境の名称)を引数に入れた状態でスクリプトにしてしまってそれをsourceするのが手間なくて良いかもしれん。
あとは

m

でプロジェクトビルドを開始する。冒頭のスペックでは3時間30分ほどで途中でエラー停止したが、再度mを実行したら成功した(続きからの模様)。
合計で4時間といったところか。
WSL2でもそれなりにスペックがあれば4時間程度でビルドできるのは嬉しい(ちょっと前は8時間ぐらいかかると聞いていたので)。

WSL2に割り当てているメモリが少ない(16GB程度)場合は、ジョブ数をm -j4等で少なくすると時間はかかるが落ちなくなる。
-jの指定が無い場合は余ってるコア適当に割り当ててくれるっぽい(偉い)。
反面、Windows11 22H2の環境では大抵のケースでは全体メモリの半分がWSL2に割り当てられているが、今回の環境は32GBの半分。これでは足りない感じ。
メモリを増やすなどしたうえで、設定で明示的に割り当てメモリを増やしてやると良い気がする。そろそろ64GBとかにするか...。

⇒マシンを更新したところビルド時間が大幅に改善されました(末尾のおまけ参照)。

ビルドが上手くいかなかったら

m clobber

で生成物をクリアしてビルドし直す。
それでも通らなかったらそれまでに取得したソースやバイナリの組み合わせがまずかったりするので、一旦最初からやり直す。
ちなみに、一度別端末の同一ビルドIDのバイナリを落としてやっちまいました。うわーん4時間無駄。

3. 端末の接続

Webで調べると「シンボリックリンク張ってWindows側のadb.exeを叩くようにすると楽だよ!」という情報が結構見つかります。
が、ここはあえて最近WSL2が対応しているホスト(Windows側)のUSBを接続する手順を試します。
なお、今回の環境ではadbfastbootはAndroid Studioをから入れたものを使っています(aptではない)。
なので、後述のsudoでadb叩く際は

~/Android/Sdk/platform-tools

の中のadb等をパス指定してsudo実行しています。

learn.microsoft.com

3.1. USBIPD-WINを入れる

Winget一発です(以前よりシンプルに)。

winget install usbipd

3.2. WSL2にデバイスを接続

usbipdはusbip clientに対してUSBを接続することができるサービスとなっている。

3.2.1. usbip clientに対する共有化

まずは利用したい端末がusbip clientに対してsharedになっている必要がある。

usbidpd list

で所望の端末のSTATEがsharedになっていればOK。
Not Sharedの場合はbindでsharedにしてください。

以下、対象端末のbusid1-13だった場合で説明します。

usbipd bind -b1-13

で対象のUSB端末をusbip clientに対してsharedな状態にできます。
また、この状態は記録されるので端末切断後に再度接続した場合、前回の状態で再開します。

3.2.2. WSLへの接続

共有化された端末はusbipd wsl attachでWSLに接続できます。

usbidpd wsl list

でWLSとの接続状態とBUSIDを確認ができる。
attachedが接続されている状態、Not attachedが接続されていない状態。

usbipd wsl attach -b1-13

こちらはbindと異なり、端末の挿抜やWSLの再起動で解除されてしまいますので、その都度必要に応じて再attachが必要です。
attach後、WSL2側でlsusbでデバイスがつながっていることを確認したら。

sudo adb kill-server # 起動してない場合は不要
sudo adb start-server

で管理者権限でadbを起動する(rootに対してパスが通ってないと思うので、絶対パス指定で実行)。
上手くいけばadb devicesでデバイスとして認識される。
管理者権限でadb start-serverした後は一般ユーザーでadbコマンドを使用しても大丈夫。

3.3. adbに上手く認識されない時

以下の処理を行う

(1) WSL2から端末を切り離す

usbipd wsl detach --busid 1-13

で一旦端末をWSL2から切り離す(busidは各自のbusidに置き換えて読んでください)。

(2) adbkeyを消す
WSL2側でユーザーのhome直下の.androidを丸ごと消す。
多分その中のadbkey, adbkey.pubだけ消してもいい。

(3) 端末側の設定の確認
開発者オプションが有効になっていることを確認する。
そのうえで、"USBデバッグ許可の取り消し"を押して、接続PCに対するデバッグ権限をクリアする。

USBデバッグは有効化し、USBの設定からはMTP接続(ファイル転送/Android Auto)の設定にしておく。

(4) 再接続
usbipd wsl attachで再接続し、端末側でPC(WSL2)に対してデバッグ許可を与えた上で3.2の手順を再度行う。
これで上手くいくはず。

4. デバイスへのAndroidの書き込み

Androidがビルドできて、端末にもつながった。ということで、fastbootを使ってビルドしたAndroidを書き込んでいく。

4.1. OEMロック解除

開発者向けオプションから「OEMロック解除」をしておく。
しておかないと

4.2. bootloader起動

adb reboot bootloader

でbootloaderで再起動する。通常の開発環境と変わらない。

4.3. fastboot注意点

私の確認したWSL2の環境(20.04)では、fastbootはsudoでやらなければならず、
その場合sudoの環境変数にfastbootのpathが通っておらず明示的に指定する必要がありました。
別環境(NativeのUbuntu 18.04)ではenvsetup.shを実行して環境変数をセットアップしてやれば、公式の通りにfastboot flashallとかだけで一発で焼けていました。
うーん、WSLが悪いのか20.04が悪いのか、はたまたこのバージョン(blueline)が悪いのか…謎です。
usbipd以外の操作はAOSP公式の説明に沿って行い、うまく行かなかったら以下を参照すると参考になるかと思います。

利用できるfastbootは余り古くなければLocalに入れているモノでも、AOSPをビルドした時に出来るものでも構いません(where fastbootで探して適度に選んでください)。
以下の説明では記載を短くするためfastbootのディレクトリ内で作業するものとして説明ます。

4.3. bootloader unlock

端末のfashingがunlockされてない場合のみ実施する。
再起動に伴い、一旦端末が切断されるのでWindows側からusbipd wsl attachで端末をWSL2に再接続する。

sudo ./fastboot flashing unlock

管理者権限で書き込みをunlockする。
端末側の電源ボタン横の表記が「Do not unlock the bootloader」に変化するので、音量ボタンを押して「Unlock the bootloader」に切り替え、電源ボタンを押して決定する。

4.4. flashboot での書き込み

一旦端末が切断されるのでWindows側からusbipd wslで端末をWSL2に再接続する。
envsetup.shで設定されているローカルのANDROID_PRODUCT_OUTをsudo時に引き渡してfastbootで書き込む。

sudo env ANDROID_PRODUCT_OUT=$ANDROID_PRODUCT_OUT ./fastboot flashall -w

なお、最後の-wオプションが必要なのは初回のみ。

書き込み中に一旦接続が切れるので、しばらくしてfastbootdの画面が出たところでWindows側からusbipd wsl attachで端末をWSL2に再接続する。 しばらくすると書き込みが完了しOSが再起動する。

5. おわりに

ほぼ既存のサイトをなぞった形にはなりますが以下が確認できました(2023/03/04 現在)。

  • WSL2 + Ubuntu20.04の環境でAOSPがビルドできた
  • usbipd を用いて、ホストOS(Windows11 22H2)の端末をWSL2に接続できた
  • WSL2側のAndroid開発環境(Android Studio, platform-tools)で作業できるようになった
  • WSL2 + usbipd + fastbootでビルドしたOSを書き込むことができた

少し手間があるものの、Android StudioやAndroid開発ツールをWLS2側のUbuntu一本で一通りの作業が出来るようになりました。
SnapdragonのライブラリであるSNPEとかはLinux側じゃないとビルド出来いので、今までは「Linux側でビルドしてから、Windows側のadbで書き込んで…」と二重管理になっていたのでOSのビルドなども含め、開発環境をWSL2側に一本化できたのはちょっと嬉しい。

6. 参考

本エントリー執筆にあたり以下のサイトを参考にさせていただきました。

【AOSP】ビルドしたAndroidOSを実機に入れる
USB デバイスを接続する(Microsoft lgnite)
Android スタートガイド(公式)

7. おまけ

PCを強化しました(2023/2月)

項目 内容
ビルド環境 Windows 11 22H2 + WSL2 Ubuntu 20.04
ターゲットOS Android 12
ターゲット端末 Google Pixel3
CPU Ryzen 9 7900
Memory 64GB(DDR5)

ビルドが52分ぐらいで終わります。イエーイ。