Skip to content

编译 AOSP 总流程 ​

记录为 Pixel 3(blueline)搭建 AOSP 编译环境的全过程,运行环境为 Debian 13,已写步骤均经实机验证。

配置 SSH 免密登录 ​

后续步骤均在该主机上执行,先配置免密登录。

项目值
系统Debian 13
IP192.168.2.13
用户kpa
  1. Windows 机器上生成密钥对(默认路径、空口令):

    powershell
    ssh-keygen -t rsa
  2. Windows 机器上查看公钥:

    ps1
    PS C:\Users\Kpa\.ssh> cat .\id_rsa.pub
  3. 登录主机,将公钥写入 authorized_keys 并设置权限:

    sh
    ssh kpa@192.168.2.13
    cd ~
    mkdir -p .ssh && echo "上面公钥内容" > .ssh/authorized_keys
    chmod 700 .ssh && chmod 600 .ssh/authorized_keys
  4. Windows 侧配置连接信息,在 C:\Users\Kpa\.ssh\config 中加入:

    Host 192.168.2.13
      HostName 192.168.2.13
      User kpa
      IdentityFile C:\Users\Kpa\.ssh\id_rsa

查看手机信息 ​

编译前确认设备信息,源码分支与内核版本均以此为准。

信息类型命令示例输出
设备型号adb shell getprop ro.product.modelPixel 3
设备品牌adb shell getprop ro.product.brandgoogle
设备制造商adb shell getprop ro.product.manufacturerGoogle
操作系统版本adb shell getprop ro.build.version.release11
硬件信息adb shell getprop ro.hardwareblueline
产品名称adb shell getprop ro.product.nameblueline
Build IDadb shell getprop ro.build.idRQ3A.211001.001
构建版本号adb shell getprop ro.build.version.incremental7641976
构建描述adb shell getprop ro.build.descriptionblueline-user 11 RQ3A.211001.001 7641976 release-keys
构建日期adb shell getprop ro.build.dateSat Aug 14 01:17:42 UTC 2021
内核版本uname -aLinux localhost 4.9.248-gc4689af91bc5-ab7425221 #0 SMP PREEMPT Fri Jun 4 06:01:28 UTC 2021 aarch64

获取源码 ​

源码分支由 AOSP tag 唯一确定,tag 可由设备的 ro.build.id 在官网反查。

  1. 根据 ro.build.id(RQ3A.211001.001)查询对应的 AOSP tag:https://source.android.com/docs/setup/about/build-numbers?hl=zh-cn

    查询结果:

    Build Id标记版本支持的设备安全补丁级别
    RQ3A.211001.001android-11.0.0_r46Android11Pixel 3、Pixel 3 XL、Pixel 3a、Pixel 3a XL、Pixel 4、Pixel 4 XL、Pixel 4a、Pixel 4a (5G)、Pixel 52021-10-01

    即 tag 为 android-11.0.0_r46,后续按该 tag 拉取源码。

  2. 根据 build id 查询对应的驱动文件:https://developers.google.cn/android/drivers?hl=zh-cn

    适用于 Android 11.0.0(RQ3A.211001.001)的 Pixel 3 二进制文件:

    硬件组件公司下载SHA-256 校验和
    供应商图片Google下载845382bc012a70ae69b03be70a16532d1f92e759bc5c65e85ad1a3417c80f485
    GPS、音频、相机、手势、图形、DRM、视频、传感器Qualcomm下载b12a986161e912e3afd71e57d31d2b4e5c682a8f70c31b37c064fe4bc08de5ad
  3. 根据 build id 查询对应的原厂刷机包:https://developers.google.cn/android/images?hl=zh-cn

  4. 确认 Pixel 3 对应的内核版本代号:https://source.android.com/docs/setup/build/building-pixel-kernels?hl=zh-cn#legacy-kernel-branches

    设备AOSP 树中的二进制文件路径仓库分支
    Pixel 3 (blueline)、Pixel 3 XL (crosshatch)device/google/crosshatch-kernelandroid-msm-crosshatch-4.9-android12

环境准备 ​

Debian 13 下安装 LXD 作为容器管理工具。

sh
# 安装 LXD(Debian 13 软件源中包名为 incus)
sudo apt update
sudo apt install -y incus

# 将当前用户加入 incus-admin 组,之后操作容器无需每次都加 sudo
sudo adduser $USER incus-admin

# 当前终端激活分组(不用重新登录),之后所有 incus 命令都不需要 sudo
newgrp incus-admin

# 初始化向导会依次询问网络与存储配置;日常本地开发一路回车(全部默认值)即可
incus admin init

# 验证服务可用
incus list

配置 Git ​

在宿主机上配置 git 提交身份与镜像重定向:

sh
git config --global user.email "473926009@qq.com"
git config --global user.name "kpa"

# 将 android.googlesource.com 重定向到科大镜像,后续 repo 拉取自动走镜像
git config --global url."https://mirrors.ustc.edu.cn/aosp/".insteadOf "https://android.googlesource.com/"

下载 Repo 工具 ​

在宿主机上执行:

sh
sudo apt install repo -y
# 安装好后执行 repo -h 检查

再通过科大代理获取官方脚本,并将 repo 自我更新源持久指向国内镜像:

sh
mkdir -p ~/bin
PATH=~/bin:$PATH

# 下载 repo 脚本(清华镜像,连接更稳)
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
chmod a+x ~/bin/repo

# 关键:指定 repo 自我更新的国内镜像源
export REPO_URL='https://gerrit-googlesource.proxy.ustclug.org/git-repo'

# 建议把上面两项永久写入 ~/.bashrc
echo 'export PATH=~/bin:$PATH' >> ~/.bashrc
echo "export REPO_URL='https://gerrit-googlesource.proxy.ustclug.org/git-repo'" >> ~/.bashrc

拉取 AOSP 源码 ​

在宿主机上按 tag android-11.0.0_r46 初始化仓库,--depth=1 浅克隆:

sh
mkdir aosp && cd aosp
repo init -u https://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-11.0.0_r46 --depth=1
# 同步代码
repo sync -c -j4

创建 aosp11 容器 ​

容器系统镜像按手机目标系统选择:目标为 Android 11,编译容器使用 Ubuntu 18.04。官方远程镜像 images:ubuntu/18.04 已因过期下架,无法再用 incus launch 直接拉取,改为手动下载官方归档并导入为本地镜像。

sh
# 1. 下载官方归档(amd64 为例)
wget https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64-lxd.tar.xz
wget https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.squashfs

# 2. 导入为本地镜像
incus image import ubuntu-18.04-server-cloudimg-amd64-lxd.tar.xz ubuntu-18.04-server-cloudimg-amd64.squashfs --alias ubuntu-18.04

# 3. 启动并进入容器
incus launch ubuntu-18.04 aosp11
incus exec aosp11 -- bash

常用容器操作(容器名 aosp11):

操作命令说明
查看状态incus list查看所有容器的运行状态、IP、资源占用
进入容器incus exec aosp11 -- bash相当于 SSH 登录进容器终端
退出终端exit退出终端回到宿主机(容器仍会继续运行)
停止容器incus stop aosp11类似于关机,下班不用时可以关掉
启动容器incus start aosp11启动已经存在的容器(不用再 launch 了)
重启容器incus restart aosp11重启容器
彻底删除incus delete -f aosp11强制删除容器(-f 表示即使在运行也强行删除)
主机/容器拷文件incus file push 本地文件 aosp11/root/将宿主机文件拷贝进容器
容器/主机拷文件incus file pull aosp11/root/文件 本地路径将容器里的文件拷回宿主机

挂载源码到容器 ​

容器只用于编译,源码放在宿主机,以 disk 设备挂载进容器:

sh
# shift=true 利用内核 idmap 机制,让容器内的 root 读写该目录时自动映射为宿主机的 kpa 权限
incus config device add aosp11 aosp_share disk source=/home/kpa/aosp path=/root/aosp shift=true

容器内源码目录即 /root/aosp,后续编译在该目录进行。

安装 AOSP 编译环境 ​

在 aosp11 容器内执行:

sh
sudo apt update
sudo apt install flex bison build-essential 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 fontconfig -y
sudo apt install make git-core gnupg zip unzip curl python3 openjdk-11-jdk -y

sudo apt clean && sudo apt autoremove -y

配置内存交换空间 ​

本机器 64G 内存,无需配置交换空间;内存低于 32G 时再开启(32G 内存编译到一半进程会被 kill):

sh
sudo swapoff /swapfile
sudo rm /swapfile
sudo fallocate -l 32G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 配置永久交换
# /etc/fstab
# 最后一行插入,进入后按 i 进入编辑模式,修改好按 ESC :wq
sudo apt-get install vim
sudo vim /etc/fstab
/swapfile swap swap defaults 0 0

# 配置交换规则
# /etc/sysctl.conf
sudo vim /etc/sysctl.conf
vm.min_free_kbytes=1500000 # 大致 1.5G,启用交换

# 重启生效

下载驱动文件 ​

用 build id RQ3A.211001.001 搜索,得到对应 Pixel 3 二进制文件:

硬件组件公司下载SHA-256 校验和
供应商图片Google下载845382bc012a70ae69b03be70a16532d1f92e759bc5c65e85ad1a3417c80f485
GPS、音频、相机、手势、图形、DRM、视频、传感器Qualcomm下载b12a986161e912e3afd71e57d31d2b4e5c682a8f70c31b37c064fe4bc08de5ad

在宿主机上执行:

sh
export ALL_PROXY="http://192.168.2.12:7890"

cd ~/aosp_driver
wget https://googledownloads.cn/dl/android/aosp/google_devices-blueline-rq3a.211001.001-4c450e6d.tgz
wget https://googledownloads.cn/dl/android/aosp/qcom-blueline-rq3a.211001.001-cec8e6a7.tgz

tar xf google_devices-blueline-rq3a.211001.001-4c450e6d.tgz
tar xf qcom-blueline-rq3a.211001.001-cec8e6a7.tgz

cp extract-google_devices-blueline.sh ../aosp
cp extract-qcom-blueline.sh ../aosp

cd ~/aosp

# 按D翻页 输入 I ACCEPT 同意协议
./extract-google_devices-blueline.sh
./extract-qcom-blueline.sh

编译 ​

在 aosp11 容器内执行,repo 命令用法参考:https://source.android.com/docs/setup/reference/repo?hl=zh-cn

sh
cd ~/aosp

# 加载 shell 环境变量,只有加载了变量后,对应的命令才可以使用
source ./build/envsetup.sh

# 选择编译哪种版本,lunch 命令输出菜单,列出当前 Android 源码支持的所有设备代号和编译类型,输入相应数字选择
lunch
# lunch 给出的列表选项都是 debug 版本,如果想要纯粹的 user 版本,直接指定运行
lunch aosp_blueline-user

# 设置编译线程,12 代表 12 个线程同时编译
make -j12

# 遇到错误后清理再重新编译
make clean

不要删除 aosp/.repo 目录,否则相当于重新下载。

编译类型说明:

  • user:限制所有权限,用于发布给用户使用的最终版本
  • userdebug:开放部分权限,允许 root
  • eng:工程师模式,开放所有权限并且有额外的调试工具

启动模拟器 ​

运行模拟器需要硬件加速(KVM),先安装并验证:

sh
# 安装 kvm
sudo apt-get install cpu-checker
sudo chmod 777 -R /dev/kvm

# 测试 kvm
egrep -c '(vmx|svm)' /proc/cpuinfo
kvm-ok

cd ~/aosp
source ./build/envsetup.sh
lunch aosp_x86_64-eng
emulator

刷机 ​

编译好之后开始刷机,以 Pixel 3 为例,依次执行:

sh
adb reboot fastboot

# 等待手机进入 fastboot 界面之后
fastboot flashall -w

# 刷机完成之后,执行 fastboot reboot 进入系统
fastboot reboot

fastboot flashall -w 在工程外面执行时,要配置 $ANDROID_PRODUCT_OUT 目录环境

单独编译 ​

在 aosp11 容器内、~/aosp 目录下:

sh
# 设置环境
source ./build/envsetup.sh
lunch aosp_x86_64-eng

# 单独编译 framework
make framework-minus-apex

# 使用 make snod 命令重新生成 system.img,运行模拟器查看
make snod

# 清数据启动
emulator -wipe-data

其他相关编译命令 ​

部分编译

sh
# 编译指定目录且不编译依赖
mmm frameworks/base
# 编译当前路径下的模块且不编译依赖
mm
# 编译指定目录且编译依赖
mmma frameworks/base

# 修改隐藏 API:@hide,必须先执行以下命令
make update-api

# 将部分编译后的模块打包进 img
make snod

repo 分支操作

sh
# 创建分支
repo start YOURBRANCH --all

# 遍历并执行 git 命令
repo forall -c git xxx

# 切换分支
repo forall -c git checkout default

# 丢弃分支
repo forall -c git git reset --hard HEAD

# 查看每个目录下的分支并打印目录路径(-p 参数在遍历到每个仓库时先打印当前路径再执行 git 命令)
repo forall -p -c git branch

# 查看分支
repo branch

单独编译framework.jar ​

sh

source ./build/envsetup.sh

lunch aosp_blueline-user

make framework-minus-apex

参考 ​