搭建环境
Ubuntu 18.04环境:
sudo apt install git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig
注:Ubuntu 20.04应该也可以,不确定是否还需要安装其它库。
安装repo
选择一个文件夹作为源码目录,在该源码根目录下:
mkdir ~/bin # 准备环境变量目录
PATH=~/bin:$PATH # 添加到环境变量(仅当前终端有效)
# 将repo下载到环境变量目录下
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo # 修改执行权限
下载源码
初始化
最新Android版本:
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest
如果需要某个特定的 Android 版本(列表),修改-b参数即可,如:
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-12.1.0_r20
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-13.0.0_r15
之后会在当前目录出现一个.repo文件夹:
下载源码
# 同步源码树(以后只需执行这条命令来同步):
repo sync
或者:
# 使用8线程下载代码
repo sync -j8
注:下载全部代码确保硬盘有至少200GB容量。
编译源码
导入环境
在源码根目录下,执行以下命令:
source build/envsetup.sh # 导入命令环境
lunch # 选择要编译的项目,如aosp_arm64-eng
lunch选项解释:
| 参数 | 说明 |
|---|---|
| aosp | 一个全功能的Android,有时也称为通用系统映像 |
| x86,x64,arm,arm64等 | Android系统运行时所在设备的CPU架构 |
| user | 正常的发行版Android系统 |
| eng | 带有附加调试工具的Android系统 |
| userdebug | 具有 root 访问权限和调试功能 |
| redfin,raven等 | 设备代号,如redfin表示Pixel 5 |
| car | 未知,应该指车载系统 |
| cf | 未知 |
make编译
编译命令:
make -j8 # 全编译
make services -j8 # 编译services
make framework -j8 # 编译framework,Android 10(Q)机之前版本用此命令
ninja framework-minus-apex -j8 # Android 11(R)及之后版本用此命令
注:make -j8全编译13.0.0_r15耗时大约2h40min,根据具体硬件设备有所不同。输出文件夹out约110GB。
ninja编译
在第一次使用make编译之后,之后如果修改过源码,则可以使用ninja编译,相较于make速度较快。
(1) 源码项目第一次使用ninja时
在源码根目录执行以下命令:
source build/envsetup.sh
lunch aosp_arm64-eng # 选择要编译的项目
croot # 回到源码根目录
cp prebuilts/build-tools/linux-x86/bin/ninja out/host/linux-x86/bin/
cp prebuilts/build-tools/linux-x86/lib64/* out/host/linux-x86/lib64/
# 建立软链接(注意替换具体机型名)
# 如combined-aosp_arm64.ninja
ln -sf out/combined-<product_name>.ninja build.ninja
(2) 之后每次执行以下快速编译命令
ninja framework -j8 # 编译framework模块
ninja framework-minus-apex -j8 # Android 11(R)及之后版本用此命令
ninja services -j8 # 编译services
常见问题
(1) ninja编译后再用mmm或make编译错误
解决:删除out/host/linux-x86/lib64/文件夹。
运行模拟器
说明
(1) lunch命令
需要注意的是,如果是要在x86或x64平台上运行编译好的镜像,那么lunch的参数则应该选择带有x86_64后缀的,如lunch sdk_pc_x86_64-userdebug和sdk_phone_x86_64等。如果编译的是其它平台的镜像,则执行emulator无法在电脑上运行,会报出错误。
Google官网给出的示例是lunch aosp_arm-eng,但在实际编译完成后执行emulator是无法正常运行的。
(2) 可以在x86及x64运行的项目
以下项目在lunch选择菜单中没有,但实际上可以执行。
sdk_x86_64-userdebug
sdk_phone_x86_64-userdebug
sdk_pc_x86_64-userdebug
注:sdk_x86_64-eng和sdk_phone_x86_64的编译结果目录都是out/target/product/emulator_x86_64
(3) 加载环境
若关闭了终端,则运行模拟器需要重新执行以下命令。
source build/envsetup.sh
lunch xxx
emulator
模拟器运行
注:使用模拟器需要在电脑BIOS中开启虚拟化支持。
使用make全编译后,执行emulator命令即可打开模拟器,会自动加载编译好的镜像文件。但如果lunch命令选择了用于其它设备的安卓系统,则会出现错误,常用lunch命令及模拟器运行如下。
(1) lunch aosp_arm64-eng
全编译后执行”emulator”打开模拟器失败且提示:
qemu-system-aarch64: Could not open '/xxx/android-13.0.0_r30/out/target/product/generic_arm64/userdata-qemu.img': No such file or directory
原因:生成的是专用于arm平台的安卓系统,而电脑通常都是x86或x64平台的,所以无法运行。
(2) lunch aosp_x86_64-eng
全编译源码后打开模拟器,也出现了类似提示:
qemu-system-x86_64: Could not open '/xxx/android-13.0.0_r30/out/target/product/generic_x86_64/userdata-qemu.img': No such file or directory
原因:暂时未知。
(3) lunch sdk_phone_x86_64-userdebug
成功打开模拟器
(4) lunch sdk_pc_x86_64-userdebug
成功打开模拟器
其它
ROM与源码匹配
ROM列表:https://developers.google.com/android/images
源码列表:https://source.android.com/docs/setup/about/build-numbers#source-code-tags-and-builds
源码列表示例:

ROM列表示例:

根据Build ID匹配到刷机包和源码。
为什么要使用ninja?
测通常使用make编译会有两个阶段:
(1) 先分析Android.bp,将所有需要参与编译的文件的路径都记录下,writing build rules并打包到out/soong/combined-xxx.ninja中,这一步普遍耗时15-20min。
(2) 然后ninja工具通过第一步生成的文件,编译需要编译的模块。(不同模块速度不同,比如services模块只需要大约20s)
优点:直接使用ninja就可以省去第一部分耗时,尤其在反复编译时调试效率提高。
注意:进行ninja之前必须要先make一次(当然要想make必须先根目录source 和 lunch一次),以生成路径文件;如果你的修改增删了模块中文件的名字路径,就必须重新make生成路径文件。