目标:在 Ubuntu 16.04.2 中编译 Android 7.1.2 的源代码, 并在模拟器上运行。
这不是一个 step by step 的教学,只记录过程。本文假设读者熟悉命令行,只是需要知道具体的步骤和命令。
官方文档:https://source.android.com/source/requirements,希望直接去看官方文档,我这里列出的步骤,只适用于我的特定环境。
- 2017-10-22 更新
LineageOS 编译起来简单多了,新手可以拿这个试手。
1. 要求
- 64 位操作系统
- 150 GB 可用硬盘空间
Ubuntu 16.04
(编译不同 Android 版本需要的 Ubuntu 版本不同,文档上说编译 Android 6.0 需要使用 Ubuntu 14.04),本文以 Ubuntu 为例,也支持 Mac OS X, 但不支持 Windows。OpenJDK 8
(编译不同 Android 版本需要的 JDK也不同)- 其他重要的依赖:
python2
,git
,GNU make
2. 建立编译环境
2.1. 设置代理
在中国,由于众所周知的原因,访问 Android 官方的源代码仓库需要使用代理。将以下代码保存为 proxy_on.sh
:1
2
3
4
5
6
7
8
9
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 | chmod +x proxy_on.sh |
要点是:这4个环境变量都要设置,才能满足所有应用的需要,如果按 Google 的文档设置,你会发现 git 没有使用代理。
2.2. 安装 JDK
1 | sudo apt-get update |
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 | mkdir ~/bin |
3.2. 初始化 repo 客户端
1 | mkdir android_source |
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
作为参数传给 lunch
。eng
代表 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 | # 查看一下 emulator 所在路径 |
5. 注意事项
5.1. 保存当前环境变量
编译完成后,不要关闭终端,执行以下命令将当前的环境变量保存起来,以备下次查看1
env > ~/android_env_after_build_for_aosp_x86-eng.txt
5.2. 下次如何使用
编译成功后,关掉终端,下次再打开。需要执行以下命令,恢复运行环境1
2
3
4cd ~/git/android_source # 进入源代码所在根目录
. ~/Dropbox/code/script/proxy_on.sh # 可选,设置好代理,proxy_on.sh 是自己写的脚本
. build/envsetup.sh
lunch # 选择上次编译时选择的选项,如不记得,请查看上一步保存的 .txt 文件
6. 遇到的问题
最后一步运行模拟器,经常黑屏假死(也许是等待的时候不够长)。尝试了几次不同的 target,最后运行成功的有
aosp_arm64-eng
和aosp_x86-eng
。运行模拟器时要有耐心,可能会假死几分钟。arm 模拟器性能很差,从 Android Studio 安装 App 失败,x86 的很流畅。代理问题。如果使用的是 http(s) 代理,要按前面的说明,4 个环境变量都设置。按照 Google 官方的文档设置的结果是 git 没有走代理,使用
git config --global
又不太方便。