Compile AOSP Android 7.1.2 Source Code

目标:在 Ubuntu 16.04.2 中编译 Android 7.1.2 的源代码, 并在模拟器上运行。

这不是一个 step by step 的教学,只记录过程。本文假设读者熟悉命令行,只是需要知道具体的步骤和命令。

官方文档:https://source.android.com/source/requirements,希望直接去看官方文档,我这里列出的步骤,只适用于我的特定环境。

  • 2017-10-22 更新

LineageOS 编译起来简单多了,新手可以拿这个试手。


1. 要求

  1. 64 位操作系统
  2. 150 GB 可用硬盘空间
  3. Ubuntu 16.04 (编译不同 Android 版本需要的 Ubuntu 版本不同,文档上说编译 Android 6.0 需要使用 Ubuntu 14.04),本文以 Ubuntu 为例,也支持 Mac OS X, 但不支持 Windows。
  4. OpenJDK 8 (编译不同 Android 版本需要的 JDK也不同)
  5. 其他重要的依赖:python2, git, GNU make

本节来源

2. 建立编译环境

2.1. 设置代理

在中国,由于众所周知的原因,访问 Android 官方的源代码仓库需要使用代理。将以下代码保存为 proxy_on.sh:

1
2
3
4
5
6
7
8
9
#!/usr/bin/env bash

url=127.0.0.1:1080 # 修改为你自己的代码服务器地址

# different software read different variable name
export http_proxy=http://${url}
export https_proxy=https://${url}
export HTTP_PROXY=http://${url}
export HTTPS_PROXY=https://${url}

每次打开终端时运行一次(代理服务器地址需要相应修改):

1
2
chmod +x proxy_on.sh
./proxy_on.sh

要点是:这4个环境变量都要设置,才能满足所有应用的需要,如果按 Google 的文档设置,你会发现 git 没有使用代理。

2.2. 安装 JDK

1
2
3
4
sudo apt-get update
sudo apt-get install openjdk-8-jdk
# 验证
java -version

2.3. 设置 USB 访问规则

Linux 中,普通用户没有权限访问 USB 设备,需要进行配置。

1
wget -S -O - http://source.android.com/source/51-android.txt | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules

2.4. 设置编译缓存 ccache

如果需要多次编译,建议设置编译缓存,这里略过,请参考官方文档

本节来源

3. 下载源代码

3.1. 安装 repo 工具

repo 是管理 Android 源代码仓库的工具。Android 的源代码分散在多个 git 仓库里,使用 repo 工具方便统一管理。

安装 repo:

1
2
3
4
mkdir ~/bin
PATH=~/bin:$PATH # 最好将这一句加到 ~/.profile 里,方便后续使用
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

3.2. 初始化 repo 客户端

1
2
3
4
5
mkdir android_source
cd android_source
repo init -u https://android.googlesource.com/platform/manifest -b android-7.1.2_r11

repo sync # 会下载 80 GB 的数据,耐心等待

android-7.1.2_r11 是我要编译的 Android 代码的版本号(一个tag),可以从这里选择其他版本 Source Code Tags and Builds.

接下来就是耐心的等待。Android 7.1.2 的代码有大约 80 GB,够下载一阵子的了。如果你的代理服务器不够快,https://android.googlesource.com/platform/manifest 这个地址国内有镜像地址,我没用过,就不写了。

本节来源

4. 开始编译

我们要编译一个在模拟器上运行的ROM,因此就不需要下载 proprietary binaries 了。如果是想刷到 Nexus 或 Pixel 设备上,还要下载对应的 proprietary binaries,详见文档

4.1. 清除前一次的编译结果

如果进行多次编译,并修改了编译配置,最好运行这个命令将之前的结果删除。

1
make clobber

4.2. 设置编译环境

1
. build/envsetup.sh

4.3. 选择 target

1
lunch

选择 aosp_x86-eng,即输入 5。 也可以将 aosp_x86-eng 作为参数传给 luncheng 代表 development configuration with additional debugging tools,即工程模式。

4.4. 编译

下面的命令会编译所有东西(所以很慢),-j10 表示并行任务数,这个数字一般指定为电脑的核数的1 - 2 倍之间。我的电脑是 4 核 8 线程,SSD 硬盘,瓶颈在 CPU 上,高了反而不好,所以选了 10。

视电脑性能,这个命令需要一到多个小时。

1
make -j10

最后出现类似下面的绿色文字,说明编译成功。

1
#### make completed successfully (01:05:36 (hh:mm:ss)) ####

4.5. 运行模拟器

编译过程已经将模拟器加到运行路径里了,直接运行

1
2
3
4
5
6
7
8
9
# 查看一下 emulator 所在路径
which emulator
# 输出 /home/ty/git/android_source/prebuilts/android-emulator/linux-x86_64/emulator

which android
# 输出 /home/ty/git/android_source/prebuilts/devtools/tools/android

# 运行 emulator,非常慢,耐心等待
emulator -memory 2048 -verbose -skin WVGA854

本节来源

5. 注意事项

5.1. 保存当前环境变量

编译完成后,不要关闭终端,执行以下命令将当前的环境变量保存起来,以备下次查看

1
env > ~/android_env_after_build_for_aosp_x86-eng.txt

5.2. 下次如何使用

编译成功后,关掉终端,下次再打开。需要执行以下命令,恢复运行环境

1
2
3
4
cd ~/git/android_source     # 进入源代码所在根目录
. ~/Dropbox/code/script/proxy_on.sh # 可选,设置好代理,proxy_on.sh 是自己写的脚本
. build/envsetup.sh
lunch # 选择上次编译时选择的选项,如不记得,请查看上一步保存的 .txt 文件

6. 遇到的问题

  1. 最后一步运行模拟器,经常黑屏假死(也许是等待的时候不够长)。尝试了几次不同的 target,最后运行成功的有 aosp_arm64-engaosp_x86-eng。运行模拟器时要有耐心,可能会假死几分钟。arm 模拟器性能很差,从 Android Studio 安装 App 失败,x86 的很流畅。

  2. 代理问题。如果使用的是 http(s) 代理,要按前面的说明,4 个环境变量都设置。按照 Google 官方的文档设置的结果是 git 没有走代理,使用 git config --global 又不太方便。