注意:这篇文章上次更新于369天前,文章内容可能已经过时。
This article was last updated369 days ago, the content may be outdated.
本文记录如何在 Ubuntu 24.04 上编译 AOSP,并使用 Cuttlefish 模拟运行编译好的系统镜像。
在中国想要编译并模拟运行 AOSP,最好首先准备好一个质量不错的代理。因为无论是同步代码还是安装 Cuttlefish,都需要访问一些被屏蔽的服务器。
This article records how to compile AOSP on Ubuntu 24.04 and run the compiled system image in a Cuttlefish virtual device.
If you want to compile and emulate AOSP in China, it’s best to prepare a good-quality proxy first. Whether it’s syncing the source code or installing Cuttlefish, you’ll need to access some blocked servers.
AOSP(Android Open Source Project) 是 Android 系统的开源版本。
它的中文官网如下:https://source.android.com/?hl=zh-cn
本文的所有工作都是按照官网的教程进行,并记录一些踩坑。
下载 AOSP 源码
安装 Repo 工具
AOSP 项目由很多个 Git 仓库组成,Google 提供了一个名为 Repo 的工具来管理这些仓库。
在 Ubuntu 上安装 Repo 工具的步骤如下:
1 | sudo apt update |
同步代码
创建一个工作目录来存放 AOSP 源码:
1 | $ mkdir -p ~/AOSP |
使用 Repo 初始化工作目录:
1 | $ repo init --partial-clone -b main -u https://android.googlesource.com/platform/manifest |
终端最后输出 repo has been initialized in ~/AOSP 表示初始化成功。
然后就可以开始正式下载 AOSP 源码了:
1 | $ repo sync -c -j8 |
这一步会非常耗时,取决于你的网络速度和代理质量。
短则一个小时,长则几天。
中间可能会因为网络问题导致下载失败,重复执行 repo sync 命令即可继续下载。
安装 Cuttlefish
如果没有物理设备的话,可以使用 Cuttlefish 模拟运行 AOSP。
本节内容的原文在这里: https://source.android.com/docs/devices/cuttlefish/get-started?hl=zh-cn
Cuttlefish 和 Android 模拟器
Cuttlefish 与 Android 模拟器有许多相似之处,但 Cuttlefish 可以保证 Android 框架(无论这是纯 AOSP,还是您自己的树中的自定义实现)实现全保真。在实际应用中,这意味着 Cuttlefish 应该会在操作系统级别响应您的互动,就像使用相同的自定义或纯 Android OS 源代码构建的实体手机目标一样。Android 模拟器围绕简化应用开发的用例构建而成,它包含许多功能钩子来迎合 Android 应用开发者的用例。如果您要使用您的自定义 Android 框架来构建模拟器,这可能会带来一些挑战。如果您需要能够代表您的自定义平台/框架代码或 Android 树形结构的虚拟设备,那么 Cuttlefish 虚拟设备是理想的选择。它是用于表示当前 AOSP 开发状态的规范设备。
Cuttlefish 和物理设备
Cuttlefish 虚拟设备与实体设备之间的主要区别在于硬件抽象层 (HAL) 级别,以及与任何自定义硬件互动的任何软件。除了硬件专用实现之外,您应该会发现 Cuttlefish 和实体设备表现出在功能上等效的行为。
验证 KVM 可用性
Cuttlefish 是一种虚拟设备,依赖于宿主机上可用的虚拟化。
在宿主机上的终端中,确保可以在基于内核的虚拟机 (KVM) 上实现虚拟化:
1 | grep -c -w "vmx\|svm" /proc/cpuinfo |
此命令返回一个大于 0 的数字表示 KVM 可用。
下载、构建并安装 Cuttlefish
- 安装依赖
1 | sudo apt install -y git devscripts equivs config-package-dev debhelper-compat golang curl |
- 下载 Cuttlefish 源码
1 | git clone https://github.com/google/android-cuttlefish |
- 构建 Cuttlefish
1 | tools/buildutils/build_packages.sh |
- 安装 Cuttlefish
1 | sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f |
在 Ubuntu 24.04 上,在构建 Cuttlefish 时我遇到了一些问题,都在 AI 的帮助下解决了。
问题一 : bazel 未安装
点击查看报错详情:
1 | The package has been created. |
解决方案: 可以去 https://github.com/bazelbuild/bazel/releases 下载最新的 Bazel 安装包。
问题二 : 缺少 libtinfo5 依赖
点击查看报错详情:
1 | $ tools/buildutils/build_packages.sh |
问题原因是 Ubuntu 24.04(Noble)默认使用的是 libtinfo6,而 libtinfo5 在 Ubuntu 24.04 官方源中已被移除。然而,Cuttlefish 的依赖还在使用老版本的 libtinfo5。
解决方案:手动安装 libtinfo5
1 | sudo apt update |
问题三:网络连接问题
点击查看报错详情:
1 | INFO: Repository +_repo_rules3+selinux instantiated at: |
其实我已经是挂着代理在编译了,但还是遇到了网络连接问题。
解决方案:设置好全局代理,反复尝试。
编译 AOSP
下面开始正式编译 AOSP。
切换到 AOSP 源码目录并且初始化编译环境:
1 | cd ~/AOSP |
接下来使用 lunch 命令选择要编译的设备。
lunch 命令的规则是 lunch product_name-release_config-build_variant。
在 2024 年以前,在终端执行 lunch 命令会列出所有可用的设备和配置。
但在我同步的代码中,在终端执行 lunch 命令会提示 No target specified.
1 | $ lunch |
我们可以分别使用 list_products 来查看支持的产品列表:
1 | $ list_products |
为了能在 Cuttlefish 上运行 AOSP,我们应该选择带有 cf_ 前缀的产品。
在我这里我选择了 aosp_cf_x86_64_phone。
接下来选择 release_config,可以使用 list_releases aosp_cf_x86_64_phone 命令查看可用的 release 配置。
1 | $ list_releases aosp_cf_x86_64_phone |
我的理解是 aosp_current 相当于开发分支,ap2a、ap3a 、ap4a、bp1a 是 release 的版本,而 trunk_staging 暂存分支。
这里我们选择 trunk_staging。
最后还差 build_variant 的选择,可以使用 list_variants 来查看支持的 build 变体。
1 | $ list_variants |
user 版就是发布给用户的,权限最小。
userdebug 版是给开发者的,权限较大,适合调试。
eng 版是给工程师的,权限最大,适合开发。
这里我们选择 eng 版。
组合上面 3 个部分,我们最终在终端执行如下命令:
1 | $ lunch aosp_cf_x86_64_phone-trunk_staging-eng |
最后我们可以执行 m 命令来编译 AOSP,也可以执行 make -j$(nproc) 来编译。
正式编译开始之后,就会大量消耗 CPU 和内存。
这里遇到过一个坑,从 ubuntu 22 开始,编译进程会因为占用大量内存而被 OOM Killer 杀掉。
我们可以手动卸载
systemd-oomd
1 | sudo apt purge systemd-oomd -y |
在一开始做编译分析的时候会消耗大量的内存,我这里物理机是 32GB 内存,又开了 64GB 的交换分区,编译分析阶段最高消耗了 50GB 左右的内存。

正式开始编译就会把整个 CPU 性能吃满,风扇转速拉到极限。

整体的编译时长取决于电脑的配置,我的电脑大概用了 2 个小时左右。
最后在终端看到如下内容,整个编译就结束了。

使用 Cuttlefish 运行 AOSP
在使用 Cuttlefish 测试我们编译好的镜像之前,先确保已经安装好的 Cuttlefish 可以正确运行。
首先从安卓 CI 平台上下载已经编译好的镜像。
下载地址在这里:https://ci.android.com/builds/branches/aosp-android-latest-release/grid?legacy=1

然后点击下载 aosp_cf_x86_64_only_phone-img-xxxxxx.zip

在面板中向下滚动,然后下载 cvd-host_package.tar.gz。请务必从与映像相同的 build 中下载主机软件包。
如果你从 Google 的网站上下载困难,也可以尝试从我这里下载:
下载完成后,在本地创建一个目录作为容器文件夹:
1 | mkdir cf |
启动 Cuttlefish:
1 | HOME=$PWD ./bin/launch_cvd --daemon |

然后就可以访问 https://localhost:8443 来进行手机操作了。

可以使用 adb 命令来连接 Cuttlefish:
1 | ./bin/adb devices |
停止 Cuttlefish:
1 | HOME=$PWD ./bin/stop_cvd |
如果能够成功运行 Cuttlefish,那么理论上你就可以运行自己编译的 AOSP 镜像。
为了对环境进行隔离,我们创建一个新的目录来启动自编译的 AOSP 镜像。
1 | mkdir cf2 |
并不是 vsoc_x86_64 下的所有文件都需要拷贝过来,其实把所有的 .img 文件拷贝过来即可。
最后使用如下命令启动 Cuttlefish:
1 | HOME=$PWD ./bin/launch_cvd --daemon |
AOSP (Android Open Source Project) is the open source version of the Android system.
Its official website (Chinese) is: https://source.android.com/?hl=zh-cn
All the work in this article follows the official tutorials, with some pitfalls I encountered recorded along the way.
Downloading the AOSP Source Code
Installing the Repo Tool
The AOSP project consists of many Git repositories, and Google provides a tool called Repo to manage them.
The steps to install Repo on Ubuntu are as follows:
1 | sudo apt update |
Syncing the Source Code
Create a working directory to store the AOSP source code:
1 | $ mkdir -p ~/AOSP |
Initialize the working directory with Repo:
1 | $ repo init --partial-clone -b main -u https://android.googlesource.com/platform/manifest |
If the terminal finally prints repo has been initialized in ~/AOSP, the initialization succeeded.
Then you can start downloading the AOSP source code for real:
1 | $ repo sync -c -j8 |
This step is very time-consuming, depending on your network speed and proxy quality.
It can take anywhere from an hour to several days.
If downloads fail midway due to network issues, just re-run repo sync to continue.
Installing Cuttlefish
If you don’t have a physical device, you can use Cuttlefish to emulate AOSP.
The original text for this section is here: https://source.android.com/docs/devices/cuttlefish/get-started?hl=zh-cn
Cuttlefish vs. the Android Emulator
Cuttlefish shares many similarities with the Android Emulator, but Cuttlefish guarantees full fidelity for the Android framework — whether it’s pure AOSP or a custom implementation in your own tree. In practice, this means that Cuttlefish should respond to your interactions at the OS level just like a physical phone built from the same custom or pure Android OS source code.The Android Emulator is built around use cases that simplify app development, and it contains many feature hooks to cater to Android app developers. If you’re building the emulator with your custom Android framework, this can present some challenges. If you need a virtual device that represents your custom platform/framework code or Android tree, the Cuttlefish virtual device is ideal. It’s the canonical device for representing the current state of AOSP development.
Cuttlefish vs. a Physical Device
The main differences between a Cuttlefish virtual device and a physical device are at the Hardware Abstraction Layer (HAL) level, and in any software that interacts with custom hardware. Except for hardware-specific implementations, you should find that Cuttlefish and a physical device exhibit functionally equivalent behavior.
Verifying KVM Availability
Cuttlefish is a virtual device that depends on virtualization available on the host machine.
In a terminal on the host machine, make sure you can virtualize on the Kernel-based Virtual Machine (KVM):
1 | grep -c -w "vmx\|svm" /proc/cpuinfo |
If this command returns a number greater than 0, KVM is available.
Downloading, Building, and Installing Cuttlefish
- Install dependencies
1 | sudo apt install -y git devscripts equivs config-package-dev debhelper-compat golang curl |
- Download the Cuttlefish source code
1 | git clone https://github.com/google/android-cuttlefish |
- Build Cuttlefish
1 | tools/buildutils/build_packages.sh |
- Install Cuttlefish
1 | sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f |
On Ubuntu 24.04, I encountered some problems while building Cuttlefish, and all of them were resolved with the help of AI.
Problem 1: bazel not installed
Click to view the error details:
1 | The package has been created. |
Solution: You can download the latest Bazel package from https://github.com/bazelbuild/bazel/releases.
Problem 2: Missing libtinfo5 dependency
Click to view the error details:
1 | $ tools/buildutils/build_packages.sh |
The problem is that Ubuntu 24.04 (Noble) uses libtinfo6 by default, and libtinfo5 has been removed from Ubuntu 24.04’s official repositories. However, Cuttlefish’s dependencies still use the old libtinfo5.
Solution: Manually install libtinfo5
1 | sudo apt update |
Problem 3: Network connection issues
Click to view the error details:
1 | INFO: Repository +_repo_rules3+selinux instantiated at: |
I was actually building with a proxy already, but I still ran into network connection issues.
Solution: Set up a global proxy and keep retrying.
Compiling AOSP
Now let’s officially compile AOSP.
Switch to the AOSP source directory and initialize the build environment:
1 | cd ~/AOSP |
Next, use the lunch command to choose the device to build.
The lunch command follows the format lunch product_name-release_config-build_variant.
Before 2024, running lunch in the terminal would list all available devices and configurations.
But in the code I synced, running lunch in the terminal shows No target specified.
1 | $ lunch |
We can use list_products to view the supported product list:
1 | $ list_products |
To run AOSP on Cuttlefish, we should choose a product with the cf_ prefix.
I chose aosp_cf_x86_64_phone.
Next, choose the release_config; you can use the list_releases aosp_cf_x86_64_phone command to view the available release configurations.
1 | $ list_releases aosp_cf_x86_64_phone |
My understanding is that aosp_current is equivalent to the development branch, ap2a, ap3a, ap4a, and bp1a are release versions, and trunk_staging is the staging branch.
Here we choose trunk_staging.
Finally, we need to choose the build_variant; you can use list_variants to view the supported build variants.
1 | $ list_variants |
The user build is for end users and has the least privileges.
The userdebug build is for developers, with more privileges, suitable for debugging.
The eng build is for engineers, with the most privileges, suitable for development.
Here we choose the eng build.
Combining the three parts above, we finally run the following command in the terminal:
1 | $ lunch aosp_cf_x86_64_phone-trunk_staging-eng |
Finally, we can run the m command to compile AOSP, or use make -j$(nproc).
Once the real compilation starts, it will consume a lot of CPU and memory.
Here I hit a pitfall: starting from Ubuntu 22, the build process can be killed by the OOM Killer because it consumes too much memory.
We can manually uninstall
systemd-oomd
1 | sudo apt purge systemd-oomd -y |
The build analysis phase consumes a lot of memory at the beginning. My physical machine has 32GB of RAM plus a 64GB swap partition, and the analysis phase peaked at around 50GB of memory usage.

Once the real build starts, it saturates the entire CPU, and the fans spin up to the limit.

The total build time depends on your machine’s configuration; mine took about 2 hours.
When you finally see the following in the terminal, the build is complete.

Running AOSP with Cuttlefish
Before using Cuttlefish to test our compiled image, make sure the installed Cuttlefish can run correctly first.
First, download a prebuilt image from the Android CI platform.
Download link: https://ci.android.com/builds/branches/aosp-android-latest-release/grid?legacy=1

Then click to download aosp_cf_x86_64_only_phone-img-xxxxxx.zip

Scroll down in the panel and download cvd-host_package.tar.gz. Be sure to download the host package from the same build as the image.
If you have trouble downloading from Google’s website, you can also try downloading from my server:
After downloading, create a local directory as the container folder:
1 | mkdir cf |
Launch Cuttlefish:
1 | HOME=$PWD ./bin/launch_cvd --daemon |

Then you can visit https://localhost:8443 to operate the phone.

You can use adb commands to connect to Cuttlefish:
1 | ./bin/adb devices |
Stop Cuttlefish:
1 | HOME=$PWD ./bin/stop_cvd |
If Cuttlefish can run successfully, then in theory you can run your own compiled AOSP image.
To isolate the environment, we create a new directory to launch our self-compiled AOSP image.
1 | mkdir cf2 |
Not all files under vsoc_x86_64 need to be copied — actually, just copying all the .img files is enough.
Finally, launch Cuttlefish with the following command:
1 | HOME=$PWD ./bin/launch_cvd --daemon |


