GUIDE · #224

从零编译 AOSP 实操:Ubuntu 22.04 下把 Android 14 跑起来

社区教程,每一步都请结合自己的机型与系统版本核对,刷机前务必备份数据。

GUIDE224 发布时间 2026/11/14 阅读次数 9 免费

开始之前

READ ME

教程来源于用户上传与互联网收集,真实性请自行斟酌。操作可能存在风险,请先保存资料。如教程侵犯您的权益,请邮件 fiimecn@163.com 下架。

教程正文

GUIDE

在 Ubuntu 22.04 上编译 AOSP

刷了这么多年别人做的 ROM,很多人会好奇:一个 Android 系统到底是怎么「造」出来的?答案就在 AOSP——Android Open Source Project。它不神秘,本质上就是一份接近 100GB 的源码,加上一套叫 soong + ninja 的构建系统,最后压成几个 .img。

这篇按实操顺序走一遍:装环境、拉源码、选目标、敲 m、拿产物、跑起来。所有命令都可以直接复制,坑也一并标出来了。

编译 AOSP 是典型的「一次性投入、长期受益」:第一次要几小时,之后改一行代码增量编译往往只要几分钟。

先确认机器扛不扛得住

AOSP 的构建系统会吃掉大量内存和磁盘。官方给的底线是 16GB 内存 + 250GB 可用空间,但以现在的代码量,这个配置非常容易在链接阶段被 OOM Killer 杀掉。

项目勉强能跑推荐配置
CPU4 核8 – 16 核
内存16 GB32 GB 及以上
磁盘250 GB500 GB SSD(NVMe 更好)
系统Ubuntu 20.04Ubuntu 22.04 LTS
网络能稳定访问源码仓库,下载量按 100GB 估

内存不足时不要硬撑,先加一块 16GB 的 swap 兜底,再把并行数降下来,比中途被 kill 强得多。

第一步:把编译环境装齐

1. 系统依赖

Ubuntu 22.04 上一次性装完这些包,缺一个都可能在 m 跑到一半时报错:

sudo apt update
sudo apt install -y git-core gnupg flex bison build-essential zip curl \
  zlib1g-dev libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev \
  libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip \
  fontconfig python3 python-is-python3 ccache rsync openjdk-17-jdk

2. 装 repo 工具

repo 是一个管理几百个 git 仓库的脚本,AOSP 全靠它同步:

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

git config --global user.name "your-name"
git config --global user.email "you@example.com"

把 export PATH=$HOME/bin:$PATH 写进 ~/.bashrc,否则新开终端会找不到 repo。

3. 打开 ccache

ccache 缓存 C/C++ 编译结果,能显著缩短重复构建时间,建议一开始就配好:

export USE_CCACHE=1
export CCACHE_EXEC=/usr/bin/ccache
ccache -M 50G

关于 JDK:Android 14 的构建系统会优先使用源码里自带的 prebuilts/jdk/jdk17,系统装 JDK 17 只是为了满足一些宿主工具。不要手动把 JAVA_HOME 指到 JDK 8——那是 Android 8 及更早版本才需要的老做法。

4. 连接真机的话,补 udev 规则

sudo apt install -y android-sdk-platform-tools-common

装完重新插拔数据线,adb devices 里不再出现 no permissions 即可。

第二步:同步源码

建目录、初始化清单、开始拉取。清单分支决定了你编的是哪个版本:

mkdir -p ~/aosp && cd ~/aosp

repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r1

repo sync -c -j8 --no-tags --no-clone-bundle

几个参数值得解释:

  • -c:只拉当前分支,不拉所有分支的历史。
  • -j8:并发数,按带宽和 CPU 调整,8 – 16 比较常见。
  • --no-tags:跳过 tag,能省下不少对象。
  • --no-clone-bundle:不走打包下载,网络差时反而更稳。

如果中途断了,直接重跑 repo sync,它是增量续传的。想固定到某个已知可用的版本,用 repo init -b 指定 tag 或分支即可;官方目前主推 android-latest-release 清单分支,始终指向最新一次发布的代码。

建议把整个同步挂到 screen 里,几十 GB 的下载断一次很肉疼:

screen -S aosp
# 掉线后
screen -r aosp

第三步:初始化构建环境

进入源码根目录,source 一次环境脚本。每开一个新 shell 都要重新执行,否则后面的 lunch 根本不存在:

cd ~/aosp
source build/envsetup.sh
hmm            # 查看所有可用命令

hmm 会列出 lunch、m、mm、mmm 等命令的简表,忘了名字的时候比翻文档快。

第四步:用 lunch 选目标

目标字符串决定了「编给谁、编成什么权限级别」。格式固定为三段:

lunch product_name-release_config-build_variant

例如运行一个虚拟设备目标:

lunch aosp_cf_x86_64_phone-trunk_staging-userdebug

执行后终端会打印一串配置摘要,重点看这几行:TARGET_PRODUCT、TARGET_BUILD_VARIANT、TARGET_ARCH、OUT_DIR。任何一项和你预期不符,说明目标写错了。

lunch 目标字符串的三个组成部分

不确定有哪些目标可用?直接敲 lunch 不带参数,会列出当前源码支持的全部组合。想看当前选中的是什么:

echo "$TARGET_PRODUCT-$TARGET_BUILD_VARIANT"

三种构建变体怎么选

变体特点适用场景
user权限受限,接近量产版验证正式体验、性能功耗
userdebug可 adb root、可 remount,性能接近正式版日常开发,首选
eng额外调试工具与日志,构建最快只验证代码能否编译通过

第五步:开始构建

一条命令开跑:

m -j16

m 从源码树顶开始构建,所以在任何子目录里执行效果都一样;不写 -j 时,构建系统会自动判断并行数。首次全量构建视机器而定,通常 1 到 3 小时。

几个实用姿势:

  • m nothing:什么都不编,只解析和校验构建结构。改完 Android.bp 先跑它,几秒钟就能发现语法错误。
  • m <模块名>:只编某个模块,比如 m Settings,比全量快一个数量级。
  • m help:列出所有伪目标,忘了模块名时很有用。
  • 构建中断后直接重跑 m,已完成的部分不会重编。

查看进度和错误:

tail -f out/verbose.log.gz 2>/dev/null
ls -t out/error.log 2>/dev/null | head

第六步:产物在哪,怎么跑起来

构建成功后,所有镜像都在 out/target/product/<目标名>/ 下。system.img、vendor.img、boot.img 这些是分区镜像,整个包则是一个 zip。

AOSP 构建产物目录与 m 命令用法

方案 A:Cuttlefish 虚拟设备(不用真机)

如果选的是 aosp_cf_x86_64_phone 这类 cf 目标,直接在源码目录里启动即可:

launch_cvd --daemon
# 浏览器打开 https://localhost:8443 或使用 adb 连接
adb devices

Cuttlefish 依赖 KVM。云主机需要开启嵌套虚拟化,本机则确认 /dev/kvm 存在且当前用户在 kvm 组里。

方案 B:刷到真机

以 Pixel 为例,构建前必须先解压对应机型与版本的驱动包,否则镜像里缺 vendor 组件,开机直接黑屏。产物齐了以后:

cd out/target/product/<目标名>/
adb reboot bootloader
fastboot flashall -w

-w 会清空 userdata,相当于恢复出厂。只想更新系统分区的话去掉 -w,但跨版本升级失败率会高一些。

常见问题速查

现象原因处理
Killed 或构建进程突然消失内存不足被 OOM Killer 杀掉降低 -j,加 swap,或升级内存
No space left on deviceout/ 增长远超预期至少留 250GB,建议 500GB SSD
ninja: build stopped: subcommand failed某个模块编译失败往上翻日志找第一个 error:,只修那一处
repo sync 长时间卡住并发过高或网络抖动降到 -j4,或加 --force-sync 重试
提示 Java 版本不正确仅 Android 8 及更早版本会出现装对应 JDK 并放到 PATH 最前
Cuttlefish 启动失败无 KVM 或未开嵌套虚拟化检查 /dev/kvm 权限与宿主设置

时间与经验参考

阶段耗时(16 核 / 32G / NVMe)说明
装环境10 分钟依赖 + repo + ccache
repo sync40 分钟 – 2 小时约 100GB,看带宽
首次全量构建1 – 3 小时ccache 冷启动
增量构建几分钟到 20 分钟改一个模块
启动验证2 – 5 分钟Cuttlefish 首次启动偏慢

最后给三条建议:

  • 先跑通再改:第一次构建不要动任何配置,确认能出包,再去改框架代码。
  • 固定版本:把 repo manifest -r > manifest.xml 存一份,出问题能精确回滚。
  • 增量优先:改一个 App 就用 m <模块>,别每次都全量,时间差得非常夸张。

如果你更关心「编完怎么刷进手机」,可以接着看 类原生 AOSP 刷机全流程;想给老机型出包,参考 老平板编译 LineageOS 的实操记录;只对通用编译流程感兴趣,LineageOS 编译入门 也可以一起看。

编译 AOSP 的意义不在于「造一个能用的系统」——那部分 Google 早就做好了。真正的价值是:你从此可以改任何一行系统代码,然后亲眼看到它在设备上生效。

提交我的评价


*文明理性,友善沟通.