AOSP環境構築 [備忘録]

# AOSP環境構築 [備忘録]
AndroidOS (Android 8.1) をビルドしたので、環境構築やビルド方法について備忘録を残しておきます。

AOSPの公式ページを見ると、流れは書いてあるが結構つまづく...
https://source.android.com/setup/build/requirements

## ビルドのためのシステム要件
https://source.android.com/setup/build/requirements
に書いてあります

- Android2.3.x以上のバージョンでビルドする際は、64ビット環境が必要
- 合計250GBの空き容量が必要
  - ソースコードのチェックアウト(ダウンロード)に最低100GBの空き容量
  - ビルドに最低150GBの空き容量
- 仮想マシン上のLinuxでビルドを行う場合、最低16GBのRAM/swapが必要

## 自分の環境
自分は以下の環境でビルドを行いました

- OS: Ubuntu 18.04
- RAM: 16GB
- CPU: Core i5 (4コア/4スレッド)
- ROM: HDD 1TB

## ビルド環境の準備

### 必要なパッケージをインストールする

```zsh
$ sudo apt update
$ sudo apt -y install curl make zip unzip \
git python default-jre openjdk-8-jdk \
bison g++-multilib gcc-multilib libxml2-utils 
```

### KVMの設定(エミュレータで実行する場合)
```zsh 
$ sudo apt install -y qemu-kvm libvirt0 libvirt-bin virt-manager bridge-utils
$ sudo adduser $USER kvm
```
- 再起動すると反映されます

### ソースコードのダウンロードに必要なツール`repo`をインストールする

> repoはAndroidのプロジェクト管理用に作られたgitの管理ツールです。
> 複数のgitリポジトリを一括で管理することが出来ます。
> https://qiita.com/fuuuuumin65/items/12310745a0d3c2319fe1

```zsh 
$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
```

### プロジェクト用のフォルダを作成する

```zsh
$ mkdir AOSP
$ cd AOSP
```

### manifestを作成し、リポジトリをクローンする

```zsh 
$ repo init -u https://android.googlesource.com/platform/manifest -b android-8.1.0_r1
$ repo sync -j4
```

- `-b android-8.1.0_r1` でチェックアウトするブランチを選択しています
  - 一覧は https://source.android.com/setup/start/build-numbers.html#source-code-tags-and-builds

- `repo sync` でリポジトリをクローンすることができます (3、4時間かかる)
  - `repo sync -j4` のようにすることで、並列実行できます (並列させる分、CPUパワーとネットワーク帯域を多く使うので注意)

## ビルド
### 前準備

```zsh 
$ export LC_ALL=C #LC_ALL=Cでないとビルドがこける
$ source build/envsetup.sh #環境設定
$ lunch aosp_x86-eng #ターゲットの選択
```

### ビルドする

```zsh
$ make -j4
```

- `repo sync` 同様、 `make -j4` のようにすることで並列実行できます。自分の環境では4コア/4スレッドなので、4並列させています。

### クリーン

```zsh
$ make clobber
```

- 前回のビルドで利用されたoutputを削除する

### キャッシュ
- ccacheを有効にすることで、2回目以降のビルドを早くすることができます

```zsh
$ export USE_CCACHE=1 #ccacheを有効にする
$ export CCACHE_DIR=/home/$USER/.ccache #キャッシュディレクトリの指定
$ prebuilts/misc/linux-x86/ccache/ccache -M 100G #ccacheでキャッシュするサイズ上限
```

## ビルド成功したときのログ
```
[ 99% 69233/69234] Install system fs image: out/target/product/generic_x86/system.img
out/target/product/generic_x86/system.img+ maxsize=2740556544 blocksize=2112 total=2684354560 reserve=27684096
[100% 69234/69234] Create system-qemu.img
1+0 records in
2048+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.00265058 s, 396 MB/s
2560+0 records in
2560+0 records out
2684354560 bytes (2.7 GB, 2.5 GiB) copied, 37.3617 s, 71.8 MB/s
1048576+0 records in
1048576+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 1.33945 s, 783 kB/s
Creating new GPT entries.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.
Setting name!
partNum is 0
REALLY setting name!
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.

#### build completed successfully (01:41:10 (hh:mm:ss)) ####
```
- `build completed successfully` と出てれば成功です。おめでとうございます :tada:

## ビルド失敗したときのログ
```
[  8% 5820/69234] Notice file: external/tcpdump/NOTICE -- out/target/product/generic_x86/obj/NOTICE_FILES/src/system/xbin/tcpdump.txt
[  8% 5821/69234] Copy xml: out/target/product/generic_x86/system/etc/apns-conf.xml
FAILED: out/target/product/generic_x86/system/etc/apns-conf.xml 
/bin/bash -c "(xmllint device/generic/goldfish/data/etc/apns-conf.xml >/dev/null ) && (mkdir -p out/target/product/generic_x86/system/etc/ ) && (rm -f out/target/product/generic_x86/system/etc/apns-conf.xml ) && (cp device/generic/goldfish/data/etc/apns-conf.xml out/target/product/generic_x86/system/etc/apns-conf.xml )"
/bin/bash: xmllint: command not found
[  8% 5822/69234] target  C: tcpdump <= external/tcpdump/util-print.c
[  8% 5823/69234] target  C: tcpdump <= external/tcpdump/print-smb.c
[  8% 5824/69234] target  C: tcpdump <= external/tcpdump/smbutil.c
ninja: build stopped: subcommand failed.
17:49:19 ninja failed with: exit status 1

#### failed to build some targets (04:14 (mm:ss)) ####
```
- 失敗すると、`failed to build some targets` となります。頑張ってエラーを直す必要があります。
- `FAILED: out/target/product/generic_x86/system/etc/apns-conf.xml` のように表示されるので、エラーメッセージでググると解決策が出てきたり出てこなかったりします。

## エミュレータの実行
### 環境設定
- `emulator`コマンド利用するために、下記を実行してパスを通す

```zsh 
$ source build/envsetup.sh
$ lunch aosp_x86-eng
```

### エミュレータの実行
```zsh 
$ emulator
```
- `out/` にビルド成果物が入っています
- `emulator` コマンドは `out/target/product/generic_x86/`以下のイメージファイルを探して実行してくれるみたいです

### imgを指定してエミュレータを実行する
```zsh 
emulator \
-system $USER/AOSP/out/target/product/generic_x86/system.img \
-ramdisk $USER/AOSP/out/target/product/generic_x86/ramdisk.img \
-data $USER/AOSP/out/target/product/generic_x86/userdata.img
```
- 上記のようにイメージファイルを自分で指定して`emulator`を起動することも可能です