EN

Android 系统开发源码环境搭建

字数统计: 3.5k阅读时长: 13 min
2018/11/01
loading

不管是 Android App 开发工程师还是 Android 系统开发工程师,对 Android 系统有一定的了解是很有必要的,正好我这几天在家里搭建了个开发环境,把过程分享出来,有需要的人可以看一下。

大概的步骤包含下面几个:

  1. 安装 Ubuntu 系统
  2. 配置 Ubuntu 系统
  3. 安装必备的软件
  4. 配置网络访问环境 (可选)
  5. 下载 AOSP 代码
  6. 配置编译环境并编译 Pixel 的代码
  7. 刷机
  8. 修改和编译 Framework 、Service、Res

版本说明(2026-10-13 核查):原文是 2018 年的环境记录。截图可见 Ubuntu 18.04.1、PLATFORM_VERSION_CODENAME=Q、aosp_sailfish-userdebug,但未保存完整 manifest,不能重建当时的 master 提交。旧 Pixel/刷机部分作为历史流程保留;新增示例固定 Android 16 的 android-16.0.0_r1、Ubuntu 22.04 x86_64、Cuttlefish x86_64,不代表最新发布,也不是给初代 Pixel 刷 Android 16 的教程。

原来建议的“512 GB SSD + 一台 Pixel”要分情况看。新建现代 AOSP 工作站时,可以参考当前官方环境要求:64 位 x86 Linux、至少 400 GB 可用空间和 64 GB RAM。磁盘标称 512 GB 不等于还有 400 GB 可用,多源码树和输出会继续占空间;这些是工作站规划基线,不是所有旧版本的硬性门槛。仅阅读源码可以少配一些;运行本文的 Cuttlefish 示例还需要可用的 KVM,真机不是必需品。

安装 Ubuntu 系统

原文使用 Ubuntu 18.04,它的常规安全维护已于 2023 年 5 月结束,扩展维护另有条件,见 Ubuntu 生命周期。新示例选用 Ubuntu 22.04 LTS,而不是继续使用那条旧 18.04.1 ISO 镜像链接。

  1. 从 Ubuntu 22.04 官方发行目录获取 amd64 安装镜像,按目录中的校验信息检查下载。
  2. 制作启动 U 盘,并在分区前备份原系统数据。
  3. 安装到准备好的 Linux 主机;虚拟机也可以使用,但要分配足够磁盘和内存,运行 Cuttlefish 时还需向客体提供 KVM/嵌套虚拟化。虚拟机里能编译,不代表一定能运行虚拟设备。

下面是我当时的桌面。当前 AOSP 主机要求以 Linux 为准,不能把本文命令直接当成 macOS 或 Apple Silicon 的原生构建流程。

2018 年的 Ubuntu 桌面

配置 Ubuntu 系统

输入法和编辑器按个人习惯选择。Vim 可用 sudo apt install vim 安装;adb、fastboot 可通过 Android Studio SDK Manager 或官方 SDK Platform-Tools获取。构建 AOSP 后也会得到主机工具,使用时先确认终端实际找到的是哪一份,避免混用旧工具:

1
2
3
4
command -v adb
adb --version
command -v fastboot
fastboot --version

Linux 真机连接还要完成 USB 调试授权和设备访问权限配置;能列出设备后,再进行后面的部署。

安装必备的软件

我当时列的 VS Code、Android Studio、Meld 是编辑/比较工具;Wine、WPS 和搜狗输入法是自己的桌面使用习惯,都不是 AOSP 编译依赖。按自己需要安装即可,系统构建依赖见后面的章节。

配置网络访问环境 (可选)

根据本地环境准备稳定的源码访问方式。Repo 自身的下载源与 AOSP manifest/项目镜像是不同入口,只替换 manifest 地址未必解决所有连接问题。

下载 AOSP 代码

官方下载说明支持用 -b 选择标签或分支。下面使用固定标签 android-16.0.0_r1;它对应 Android 16,见版本与构建号表。不要像旧文那样省略分支,再把后来下载的内容当成当年的环境。

repo 下载

Ubuntu 上可先安装发行版提供的 Repo launcher:

1
2
3
sudo apt update
sudo apt install repo
repo version

官方目前要求 launcher 2.4 或更高。若发行版软件源没有合适的包,使用官方手动安装步骤,包括签名校验;旧文直接下载到 ~/bin/repo 的几行不再作为完整安装流程。

建立工作目录

选择空间足够的新目录;已有其他版本源码时,不要直接在原树里换标签:

1
2
mkdir -p ~/aosp-16-r1
cd ~/aosp-16-r1

初始化仓库

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

如果需要清华镜像,按镜像站当前说明把上面命令的 -u 改为 https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest,保留同一个 -b。选择一个入口初始化即可,镜像同步时间也可能影响某个标签是否已可用。

下载代码(-c --no-tags 能下载更少的代码)

旧标题中的参数不是版本锁定手段。-c 缩小到 manifest 所需的分支/修订;--no-tags 只影响标签抓取,不能代替 -b。下面沿用官方的同步形式,-j8 是同步并发示例,可按网络和主机资源降低:

1
2
repo sync -c -j8
repo manifest -r -o manifest-pinned.xml

同步成功后再导出 manifest,记录每个项目的实际提交。任何项目同步失败都应先处理,不要带着不完整源码进入编译。

配置编译环境并编译 Pixel 的代码

这一节区分两个目标:原图中的初代 Pixel sailfish 是历史案例;新增命令编译 Cuttlefish。产品名、源码、专有二进制和输出必须匹配,不能把两个目标的步骤拼起来执行。

配置编译环境

安装jdk

原文安装 openjdk-8-jdk 的做法不能通用于现代 AOSP。本文固定的 Android 16 源码由构建系统选择 Java 工具链;envsetup.sh 设置 ANDROID_JAVA_HOME/JAVA_HOME,不要强行覆盖成系统 JDK 8。旧版本需要什么 JDK,应按对应分支要求配置。编译 AOSP 也不是用 Android Studio 自带的 Gradle 去构建整棵源码树。

安装相关依赖

在本文选定的 Ubuntu 22.04 环境中,参考官方 Linux 依赖清单:

1
2
3
4
sudo apt update
sudo apt install git-core gnupg flex bison build-essential zip curl \
zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev lib32z1-dev \
libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3

这里修正了原文的 lib32z-dev,不再照搬旧 lib32ncurses5-dev 等包名。其他发行版或旧 Android 分支应使用自己的依赖清单,不能混装后假定结果相同。

下载 Pixel 的驱动

历史 Pixel 流程:专有硬件支持文件要与设备代号和 Android 构建号匹配。正式版本驱动下载页按设备与构建号列出文件;不能把旧 blobs-preview 页中的“最新预览驱动”与任意源码混用。按随包说明在对应源码根目录提取,并阅读许可条件;文件通常进入 vendor/。原文没有记录下载包的完整版本,因此不能据旧截图补造它的配套标签。

下面是当时的高通二进制提取结果:

历史 sailfish 高通二进制提取结果

历史 sailfish Google 设备文件提取结果

本文的 Android 16 Cuttlefish 目标不使用这些 sailfish 二进制,无需下载旧 Pixel 驱动包。

编译 Pixel 的系统镜像

原来的 lunch 菜单和 make -j8 如下,图中选中的是 aosp_sailfish-userdebug,平台代号为开发中的 Q:

2018 年的 lunch 交互菜单

2018 年的 sailfish 构建配置

新增的 Android 16 Cuttlefish 示例,在同步完成的源码根目录、同一个 Bash 会话里执行:

1
2
3
source build/envsetup.sh
lunch aosp_cf_x86_64_only_phone-aosp_current-userdebug
m -j8

目标和参数按 android-16.0.0_r1 的 envsetup.sh核对:该版本已移除旧交互菜单,无参数 lunch 会报错;三段式是产品、release 配置、构建变体。aosp_current 在这个标签中映射到 bp2a,不是让源码自动追到今天的最新版本。userdebug 适合平台调试,量产 user 不能默认获得同样的调试权限。

m 是构建入口,-j8 表示最多 8 个并行任务,不是 CPU 必须有 8 个线程;内存不足时要降低并发。不要根据一张进度截图认定整个构建已经成功。

编译成功

以构建进程成功退出为前提,再查看 $ANDROID_PRODUCT_OUT 中本次目标的镜像。只看到 out/ 里有文件,不能排除上次构建遗留的产物。下面仍是原来的 out/target/product/sailfish,不是新增 Cuttlefish 的输出:

历史 sailfish 输出目录

要运行本地 Cuttlefish 构建,先完成官方主机准备步骤:KVM 可用,安装 Cuttlefish 主机包,并使用户组/udev 设置生效。在完成构建并保留上述 envsetup/lunch 环境的终端中启动:

1
2
launch_cvd --daemon
adb devices

如果改用 CI 下载包,镜像与 cvd-host_package.tar.gz 必须来自同一个 build,不能拿最新 host 包随意配旧镜像。需要检查虚拟设备是否实际启动、能通过 ADB 连接,以及修改后的功能是否生效;编译通过不等于运行通过。

刷机

此节仅用于已有匹配设备源码、专有文件和镜像的真机目标。上面的 Cuttlefish 镜像不能刷进 Pixel。 原文漏掉了设备解锁和数据处理前提。

先备份数据,确认设备允许 OEM 解锁、USB 调试已授权、源码产品与真机匹配,再按官方 Fastboot 流程进入 bootloader。需要解锁的设备通常要在机身确认;解锁会清除用户数据,不能当作普通重启。解锁方式仍以具体机型为准。

原图中的 fastboot devices 只证明当时工具识别到了设备:

历史 fastboot 设备列表

在正确 lunch 目标的构建环境中,原文使用的是:

1
fastboot flashall

官方首次完整刷入示例使用 fastboot flashall -w,其中 -w 会擦除 /data。原命令不带 -w,但这不保证跨版本数据兼容,更不保证解锁或其他刷机步骤不会清数据。不要把擦除参数隐藏在“一键命令”里,也不要将不同机型/构建的分区文件混刷。

历史 flashall 输出,显示分区写入与重启

这张图证明的是当次命令的写入结果,没有系统启动完成或功能测试的证据。现代设备的动态分区、fastbootd、AVB 和 A/B 槽位也要按目标设备流程处理,不能照抄旧图中的分区列表。

修改和编译 Framework 、Service、Res

先完成同一源码树、同一目标的完整构建,再做增量修改。目录名不等于模块名,模块编译完成也不一定已经生成可刷镜像。

修改代码 IDE

java代码

Java/Kotlin 可以用 Android Studio 编辑。整棵 AOSP 不是普通 Gradle 项目,代码索引和依赖可参考分支中的 AIDEGen或该分支支持的 IDE 工程生成方式;编辑器能打开文件不代表能正确解析所有平台符号。

c/cpp代码

C/C++ 可继续用熟悉的编辑器,如 VS Code。Source Insight、Eclipse 是原文当时的选择,不是系统构建要求;补全和跳转需要与实际编译配置匹配。

编译 Framework

原文 mmm framework/base 少了一个 s。旧分支的目录构建应写作 mmm frameworks/base,但不要把这个旧入口直接套到 Android 16。本文标签中用于安装的非 APEX framework 模块是:

1
m framework-minus-apex

Android 16 的模块定义说明,它安装时文件名为 framework;另一个名为 framework 的模块是 build-only,不能因为名字相同就把产物当成可部署的 jar。位于 APEX 的代码需构建其所属模块。

编译 Services

原文旧目录入口是 mmm frameworks/base/services。本文 Android 16 标签提供名为 services 的可安装模块:

1
m services

编译 res

原文旧目录入口是 mmm frameworks/base/core/res。对应现代模块示例是:

1
m framework-res

API、资源 ID、bootclasspath、APEX 或跨分区接口发生变化时,应重建依赖和完整镜像,再验证启动与对应功能;不能只替换单个文件就判定完成。

root && remount

下面是历史 userdebug 设备的成功输出,不能套到普通量产 user 系统。Bootloader 解锁也不等于 adb root 一定可用:

历史 adb root 与 remount 输出

Android 16 的调试构建可能通过 OverlayFS 提供可写层。同版本 remount 说明给出了 verity、重启和挂载顺序。仅在自己的测试设备/虚拟设备上、明确允许修改系统分区的调试环境中逐步执行:

1
2
3
4
5
adb root
adb remount -R
adb wait-for-device
adb root
adb remount

-R 可能安排必要的 verity 状态变更和重启;这些是调试配置,不是量产使用建议。若任一步失败,先处理权限、构建类型或设备支持问题,不要继续假定分区已可写。

push

adb sync system 同步当前构建输出的 system 文件,不能保证其他分区、APEX、boot 镜像或预优化产物都更新了。对同一构建上的兼容 system 文件小改动,可参考分步流程:

1
2
3
4
adb shell stop
adb sync system
adb shell start
adb reboot

每步检查结果;同步失败时应先恢复已停止的 Android 服务(adb shell start)并处理错误,不能把失败当更新成功。这里的 stop/start 控制 Android 服务,不是退出再打开终端 shell。涉及初始化、bootclasspath 或其他分区的变化时,应按完整重建/部署流程处理。

重启后检查实际文件或版本标记,并运行相关功能验证。OverlayFS 覆盖层与 OTA 更新存在限制,刷回镜像后也要确认没有残留覆盖;“命令返回成功”只是一部分证据。

关于我 && 博客

下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!

  1. 博主个人介绍 :里面有个人的微信和微信群链接。
  2. 本博客内容导航 :个人博客内容的一个导航。
  3. 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
  4. Android性能优化知识星球:付费社群已于 2026 年停止运营,不再招收新成员;此处保留历史介绍。

一个人可以走的更快 , 一群人可以走的更远

微信扫一扫

CATALOG
  1. 1. 安装 Ubuntu 系统
  2. 2. 配置 Ubuntu 系统
  3. 3. 安装必备的软件
  4. 4. 配置网络访问环境 (可选)
  5. 5. 下载 AOSP 代码
    1. 5.1. repo 下载
    2. 5.2. 建立工作目录
    3. 5.3. 初始化仓库
    4. 5.4. 下载代码(-c --no-tags 能下载更少的代码)
  6. 6. 配置编译环境并编译 Pixel 的代码
    1. 6.1. 配置编译环境
      1. 6.1.1. 安装jdk
      2. 6.1.2. 安装相关依赖
    2. 6.2. 下载 Pixel 的驱动
    3. 6.3. 编译 Pixel 的系统镜像
    4. 6.4. 编译成功
  7. 7. 刷机
  8. 8. 修改和编译 Framework 、Service、Res
    1. 8.1. 修改代码 IDE
      1. 8.1.1. java代码
      2. 8.1.2. c/cpp代码
    2. 8.2. 编译 Framework
    3. 8.3. 编译 Services
    4. 8.4. 编译 res
    5. 8.5. root && remount
    6. 8.6. push
  9. 9. 关于我 && 博客