开始之前
READ ME教程来源于用户上传与互联网收集,真实性请自行斟酌。操作可能存在风险,请先保存资料。如教程侵犯您的权益,请邮件 fiimecn@163.com 下架。
教程正文
GUIDE
刷了这么多年别人做的 ROM,很多人会好奇:一个 Android 系统到底是怎么「造」出来的?答案就在 AOSP——Android Open Source Project。它不神秘,本质上就是一份接近 100GB 的源码,加上一套叫 soong + ninja 的构建系统,最后压成几个 .img。
这篇按实操顺序走一遍:装环境、拉源码、选目标、敲 m、拿产物、跑起来。所有命令都可以直接复制,坑也一并标出来了。
编译 AOSP 是典型的「一次性投入、长期受益」:第一次要几小时,之后改一行代码增量编译往往只要几分钟。
先确认机器扛不扛得住
AOSP 的构建系统会吃掉大量内存和磁盘。官方给的底线是 16GB 内存 + 250GB 可用空间,但以现在的代码量,这个配置非常容易在链接阶段被 OOM Killer 杀掉。
| 项目 | 勉强能跑 | 推荐配置 |
|---|---|---|
| CPU | 4 核 | 8 – 16 核 |
| 内存 | 16 GB | 32 GB 及以上 |
| 磁盘 | 250 GB | 500 GB SSD(NVMe 更好) |
| 系统 | Ubuntu 20.04 | Ubuntu 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 不带参数,会列出当前源码支持的全部组合。想看当前选中的是什么:
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。

方案 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 device | out/ 增长远超预期 | 至少留 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 sync | 40 分钟 – 2 小时 | 约 100GB,看带宽 |
| 首次全量构建 | 1 – 3 小时 | ccache 冷启动 |
| 增量构建 | 几分钟到 20 分钟 | 改一个模块 |
| 启动验证 | 2 – 5 分钟 | Cuttlefish 首次启动偏慢 |
最后给三条建议:
- 先跑通再改:第一次构建不要动任何配置,确认能出包,再去改框架代码。
- 固定版本:把
repo manifest -r > manifest.xml存一份,出问题能精确回滚。 - 增量优先:改一个 App 就用
m <模块>,别每次都全量,时间差得非常夸张。
如果你更关心「编完怎么刷进手机」,可以接着看 类原生 AOSP 刷机全流程;想给老机型出包,参考 老平板编译 LineageOS 的实操记录;只对通用编译流程感兴趣,LineageOS 编译入门 也可以一起看。
编译 AOSP 的意义不在于「造一个能用的系统」——那部分 Google 早就做好了。真正的价值是:你从此可以改任何一行系统代码,然后亲眼看到它在设备上生效。
工具 & 教程 · 矩阵
更多工具与教程
工具、教程、Gapps 与视频,一站配齐。
提交我的评价