本文记录如何在 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
2
sudo apt update
sudo apt install repo

同步代码

创建一个工作目录来存放 AOSP 源码:

1
2
$ mkdir -p ~/AOSP
$ cd ~/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. 安装依赖
1
sudo apt install -y git devscripts equivs config-package-dev debhelper-compat golang curl
  1. 下载 Cuttlefish 源码
1
2
git clone https://github.com/google/android-cuttlefish
cd android-cuttlefish
  1. 构建 Cuttlefish
1
tools/buildutils/build_packages.sh
  1. 安装 Cuttlefish
1
2
3
4
sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f
sudo dpkg -i ./cuttlefish-user_*_*64.deb || sudo apt-get install -f
sudo usermod -aG kvm,cvdnetwork,render $USER
sudo reboot

在 Ubuntu 24.04 上,在构建 Cuttlefish 时我遇到了一些问题,都在 AI 的帮助下解决了。

问题一 : bazel 未安装

点击查看报错详情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
The package has been created.
Attention, the package has been created in the current directory,
not in ".." as indicated by the message above!
正在选中未选择的软件包 cuttlefish-common-build-deps。
(正在读取数据库 ... 系统当前共安装有 230043 个文件和目录。)
准备解压 cuttlefish-common-build-deps_1.18.0_amd64.deb ...
正在解压 cuttlefish-common-build-deps (1.18.0) ...
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
正在修复依赖关系...Starting pkgProblemResolver with broken count: 1
Starting 2 pkgProblemResolver with broken count: 1
Investigating (0) cuttlefish-common-build-deps:amd64 < 1.18.0 @iU K Nb Ib >
Broken cuttlefish-common-build-deps:amd64 依赖 on bazel:amd64 < none @un H >
Removing cuttlefish-common-build-deps:amd64 because I can't find bazel:amd64
Done
完成
Starting pkgProblemResolver with broken count: 0
Starting 2 pkgProblemResolver with broken count: 0
Done
下列软件包将被【卸载】:
cuttlefish-common-build-deps
升级了 0 个软件包,新安装了 0 个软件包,要卸载 1 个软件包,有 4 个软件包未被升级。
有 1 个软件包没有被完全安装或卸载。
解压缩后将会空出 9,216 B 的空间。
(正在读取数据库 ... 系统当前共安装有 230047 个文件和目录。)
正在卸载 cuttlefish-common-build-deps (1.18.0) ...
mk-build-deps: Unable to install cuttlefish-common-build-deps at /usr/bin/mk-build-deps line 460.
mk-build-deps: Unable to install all build-dep packages

解决方案: 可以去 https://github.com/bazelbuild/bazel/releases 下载最新的 Bazel 安装包。

问题二 : 缺少 libtinfo5 依赖

点击查看报错详情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
$ tools/buildutils/build_packages.sh
+++ dirname tools/buildutils/build_packages.sh
++ realpath tools/buildutils/../..
+ REPO_DIR=/home/wgxls/AOSP/Cuttlefish/android-cuttlefish
++ dirname tools/buildutils/build_packages.sh
+ INSTALL_BAZEL=tools/buildutils/installbazel.sh
++ dirname tools/buildutils/build_packages.sh
+ BUILD_PACKAGE=tools/buildutils/build_package.sh
+ command -v bazel
+ install_debuild_dependencies
+ echo 'Installing debuild dependencies'
Installing debuild dependencies
+ sudo apt-get update
命中:1 https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble InRelease
命中:3 https://dl.winehq.org/wine-builds/ubuntu noble InRelease
命中:4 https://nvidia.github.io/libnvidia-container/stable/deb/amd64 InRelease
命中:5 https://dl.google.com/linux/chrome/deb stable InRelease
命中:6 https://packages.microsoft.com/repos/code stable InRelease
命中:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble InRelease
命中:7 http://security.ubuntu.com/ubuntu noble-security InRelease
获取:8 https://repo.steampowered.com/steam stable InRelease [2,858 B]
命中:9 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates InRelease
命中:10 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-backports InRelease
已下载 2,858 B,耗时 4秒 (644 B/s)
正在读取软件包列表... 完成
+ sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef upgrade
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
正在计算更新... 完成
下列软件包新版本的升级因阶段更新而被推迟:
ubuntu-drivers-common
下列软件包的版本将保持不变:
linux-generic-hwe-24.04 linux-headers-generic-hwe-24.04 linux-image-generic-hwe-24.04
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 4 个软件包未被升级。
N: Some packages may have been kept back due to phasing.
+ sudo apt-get install -y devscripts config-package-dev debhelper-compat equivs
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
注意,选中 'debhelper' 而非 'debhelper-compat'
devscripts 已经是最新版 (2.23.7)。
config-package-dev 已经是最新版 (5.5)。
debhelper 已经是最新版 (13.14.1ubuntu5)。
equivs 已经是最新版 (2.3.1)。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 4 个软件包未被升级。
+ tools/buildutils/build_package.sh /home/wgxls/AOSP/Cuttlefish/android-cuttlefish/base
~/AOSP/Cuttlefish/android-cuttlefish/base ~/AOSP/Cuttlefish/android-cuttlefish
Installing package dependencies
dpkg-buildpackage: info: 源码包 cuttlefish-common-build-deps
dpkg-buildpackage: info: 源码版本 1.18.0
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: 源码修改者 Equivs Dummy Package Generator <root@wgxls-desktop>
dpkg-buildpackage: info: 主机架构 amd64
dpkg-source --before-build .
debian/rules clean
dh clean
dh_clean
debian/rules binary
dh binary
dh_update_autotools_config
dh_autoreconf
create-stamp debian/debhelper-build-stamp
dh_prep
dh_auto_install --destdir=debian/cuttlefish-common-build-deps/
dh_install
dh_installdocs
dh_installchangelogs
dh_perl
dh_link
dh_strip_nondeterminism
dh_compress
dh_fixperms
dh_missing
dh_dwz
dh_strip
dh_makeshlibs
dh_shlibdeps
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
dpkg-deb: 正在 '../cuttlefish-common-build-deps_1.18.0_amd64.deb' 中构建软件包 'cuttlefish-common-build-deps'
dpkg-genbuildinfo --build=binary -O../cuttlefish-common-build-deps_1.18.0_amd64.buildinfo
dpkg-genchanges --build=binary -O../cuttlefish-common-build-deps_1.18.0_amd64.changes
dpkg-genchanges: info: binary-only upload (no source code included)
dpkg-source --after-build .
dpkg-buildpackage: info: binary-only upload (no source included)

The package has been created.
Attention, the package has been created in the current directory,
not in ".." as indicated by the message above!
正在选中未选择的软件包 cuttlefish-common-build-deps。
(正在读取数据库 ... 系统当前共安装有 230331 个文件和目录。)
准备解压 cuttlefish-common-build-deps_1.18.0_amd64.deb ...
正在解压 cuttlefish-common-build-deps (1.18.0) ...
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
正在修复依赖关系...Starting pkgProblemResolver with broken count: 1
Starting 2 pkgProblemResolver with broken count: 1
Investigating (0) cuttlefish-common-build-deps:amd64 < 1.18.0 @iU K Nb Ib >
Broken cuttlefish-common-build-deps:amd64 依赖 on libtinfo5:amd64 < none @un H >
Removing cuttlefish-common-build-deps:amd64 because I can't find libtinfo5:amd64
Done
完成
Starting pkgProblemResolver with broken count: 0
Starting 2 pkgProblemResolver with broken count: 0
Done
下列软件包将被【卸载】:
cuttlefish-common-build-deps
升级了 0 个软件包,新安装了 0 个软件包,要卸载 1 个软件包,有 4 个软件包未被升级。
有 1 个软件包没有被完全安装或卸载。
解压缩后将会空出 9,216 B 的空间。
(正在读取数据库 ... 系统当前共安装有 230335 个文件和目录。)
正在卸载 cuttlefish-common-build-deps (1.18.0) ...
mk-build-deps: Unable to install cuttlefish-common-build-deps at /usr/bin/mk-build-deps line 460.
mk-build-deps: Unable to install all build-dep packages

问题原因是 Ubuntu 24.04(Noble)默认使用的是 libtinfo6,而 libtinfo5 在 Ubuntu 24.04 官方源中已被移除。然而,Cuttlefish 的依赖还在使用老版本的 libtinfo5。

解决方案:手动安装 libtinfo5

1
2
3
sudo apt update
wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb
sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb

问题三:网络连接问题

点击查看报错详情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
INFO: Repository +_repo_rules3+selinux instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+android_system_core instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+swiftshader instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+mkbootimg instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+mesa instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+wmediumd instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+avb instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+android_system_extras instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
ERROR: /home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl:318:9: An error occurred during the fetch of repository '+_repo_rules3+avb':
Traceback (most recent call last):
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl", line 197, column 35, in _git_repository_implementation
update = _clone_or_update_repo(ctx)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl", line 43, column 20, in _clone_or_update_repo
git_ = git_repo(ctx, directory)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 98, column 12, in git_repo
_update(ctx, git_repo)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 138, column 10, in _update
fetch(ctx, git_repo)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 188, column 13, in fetch
_git(
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 224, column 15, in _git
_error(ctx.name, ["git"] + start + list(args), st.stderr)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 318, column 9, in _error
fail("error running '%s' while working with @%s:\n%s" % (command_text, name, stderr))
Error in fail: error running 'git fetch origin refs/heads/*:refs/remotes/origin/* refs/tags/*:refs/tags/*' while working with @+_repo_rules3+avb:
fatal: 无法访问 'https://android.googlesource.com/platform/external/avb/':Failed to connect to android.googlesource.com port 443 after 135162 ms: Couldn't connect to server
ERROR: no such package '@@+_repo_rules3+avb//': error running 'git fetch origin refs/heads/*:refs/remotes/origin/* refs/tags/*:refs/tags/*' while working with @+_repo_rules3+avb:
fatal: 无法访问 'https://android.googlesource.com/platform/external/avb/':Failed to connect to android.googlesource.com port 443 after 135162 ms: Couldn't connect to server
ERROR: /home/wgxls/AOSP/Cuttlefish/android-cuttlefish/base/cvd/cuttlefish/package/BUILD.bazel:3:14: //cuttlefish/package:cvd depends on @@+_repo_rules3+avb//:avbtool.py in repository @@+_repo_rules3+avb which failed to fetch. no such package '@@+_repo_rules3+avb//': error running 'git fetch origin refs/heads/*:refs/remotes/origin/* refs/tags/*:refs/tags/*' while working with @+_repo_rules3+avb:
fatal: 无法访问 'https://android.googlesource.com/platform/external/avb/':Failed to connect to android.googlesource.com port 443 after 135162 ms: Couldn't connect to server
ERROR: Analysis of target '//cuttlefish/package:cvd' failed; build aborted: Analysis failed
INFO: Elapsed time: 403.699s, Critical Path: 0.04s
INFO: 1 process: 1 internal.
ERROR: Build did NOT complete successfully
FAILED:
make[1]: *** [debian/rules:79:override_dh_auto_build] 错误 1
make[1]: 离开目录“/home/wgxls/AOSP/Cuttlefish/android-cuttlefish/base”
make: *** [debian/rules:69:binary] 错误 2
dpkg-buildpackage: 错误: debian/rules binary subprocess returned exit status 2
debuild: fatal error at line 1184:
dpkg-buildpackage -us -uc -ui -i -b failed

其实我已经是挂着代理在编译了,但还是遇到了网络连接问题。

解决方案:设置好全局代理,反复尝试。

编译 AOSP

下面开始正式编译 AOSP。

切换到 AOSP 源码目录并且初始化编译环境:

1
2
cd ~/AOSP
source build/envsetup.sh

接下来使用 lunch 命令选择要编译的设备。

lunch 命令的规则是 lunch product_name-release_config-build_variant

在 2024 年以前,在终端执行 lunch 命令会列出所有可用的设备和配置。

但在我同步的代码中,在终端执行 lunch 命令会提示 No target specified.

1
2
$ lunch
No target specified. See lunch --help

我们可以分别使用 list_products 来查看支持的产品列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
$ list_products 
22:14:41 Build sandboxing disabled due to nsjail error.
aosp_64bitonly_x86_64
aosp_akita
aosp_akita_16k
aosp_akita_fullmte
aosp_arm
aosp_arm64
aosp_arm64_fullmte
aosp_arm64_plus_armv7
aosp_bluejay
aosp_bluejay_car
aosp_bluejay_hwasan
aosp_caiman
aosp_caiman_16k
aosp_caiman_fullmte
aosp_cf_arm64_auto
aosp_cf_arm64_minidroid
aosp_cf_arm64_only_phone
aosp_cf_arm64_only_phone_hwasan
aosp_cf_arm64_only_phone_vendor
aosp_cf_arm64_phone
aosp_cf_arm64_phone_fullmte
aosp_cf_arm64_phone_hwasan
aosp_cf_arm64_phone_pgagnostic
aosp_cf_arm64_phone_vendor
aosp_cf_arm64_slim
aosp_cf_arm_minidroid
aosp_cf_riscv64_minidroid
aosp_cf_riscv64_phone
aosp_cf_riscv64_slim
aosp_cf_riscv64_wear
aosp_cf_x86_64_auto
aosp_cf_x86_64_auto_dd
aosp_cf_x86_64_auto_md
aosp_cf_x86_64_auto_mdnd
aosp_cf_x86_64_auto_portrait
aosp_cf_x86_64_foldable
aosp_cf_x86_64_host
aosp_cf_x86_64_minidroid
aosp_cf_x86_64_only_phone
aosp_cf_x86_64_only_phone_hsum
aosp_cf_x86_64_pc
aosp_cf_x86_64_phone
aosp_cf_x86_64_phone_pgagnostic
aosp_cf_x86_64_phone_soong_system
aosp_cf_x86_64_phone_vendor
aosp_cf_x86_64_slim
aosp_cf_x86_64_ssi
aosp_cf_x86_64_tv
aosp_cf_x86_64_wear
aosp_cf_x86_go_phone
aosp_cf_x86_tv
aosp_cf_x86_wear
aosp_cheetah
aosp_cheetah_car
aosp_cheetah_hwasan
aosp_cloudripper
aosp_comet
aosp_felix
aosp_felix_hwasan
aosp_husky
aosp_husky_car
aosp_husky_fullmte
aosp_husky_pgagnostic
aosp_komodo
aosp_komodo_16k
aosp_komodo_fullmte
aosp_lynx
aosp_lynx_hwasan
aosp_oriole
aosp_oriole_64
aosp_oriole_car
aosp_oriole_hwasan
aosp_oriole_pgagnostic_64
aosp_oriole_pkvm
aosp_panther
aosp_panther_car
aosp_panther_hwasan
aosp_raven
aosp_raven_64
aosp_raven_car
aosp_raven_hwasan
aosp_raven_pgagnostic_64
aosp_raven_pkvm
aosp_ravenclaw
aosp_redfin_car
aosp_ripcurrent
aosp_ripcurrent24
aosp_ripcurrent24_fullmte
aosp_ripcurrent_fullmte
aosp_ripcurrentpro
aosp_ripcurrentpro_fullmte
aosp_riscv64
aosp_shiba
aosp_shiba_fullmte
aosp_shiba_pgagnostic
aosp_slider
aosp_slider_hwasan
aosp_sunfish_car
aosp_tangorpro
aosp_tangorpro_car
aosp_tangorpro_hwasan
aosp_tokay
aosp_tokay_16k
aosp_tokay_fullmte
aosp_trout_arm64
aosp_trout_x86_64
aosp_tv_arm64
aosp_tv_x86
aosp_whitefin
aosp_whitefin_64
aosp_whitefin_hwasan
aosp_whitefin_pkvm
aosp_x86
aosp_x86_64
aosp_x86_arm
arm_krait
arm_v7_v8
armv8
armv8_cortex_a55
armv8_kryo385
csi_arm
csi_arm64
csi_x86
csi_x86_64
db845c
db845c_mini
factory_akita
factory_bluejay
factory_caiman
factory_cheetah
factory_cloudripper
factory_comet
factory_felix
factory_husky
factory_komodo
factory_lynx
factory_oriole
factory_panther
factory_raven
factory_ravenclaw
factory_ripcurrent
factory_ripcurrent24
factory_ripcurrentpro
factory_shiba
factory_slider
factory_tangorpro
factory_tokay
factory_whitefin
full
full_slider
full_x86
fvp
fvp_mini
generic
generic_system_arm64
generic_system_x86
generic_system_x86_64
generic_system_x86_arm
generic_x86
gsi_arm
gsi_arm64
gsi_car_arm64
gsi_car_x86_64
gsi_tv_arm
gsi_tv_arm64
gsi_x86
gsi_x86_64
haiku
hikey
hikey32
hikey64_only
hikey960
hikey960_tv
hikey_tv
linaro_swr
linux_bionic
mainline_sdk
mainline_system_arm64
mainline_system_x86
mainline_system_x86_64
mainline_system_x86_arm
mgsi_arm
mgsi_arm64
mgsi_x86
mgsi_x86_64
mini_arm64
mini_armv7a_neon
mini_x86
mini_x86_64
module_arm
module_arm64
module_arm64only
module_riscv64
module_x86
module_x86_64
module_x86_64only
ndk
poplar
qemu_trusty_arm64
riscv64
sdk
sdk_atv64_arm64
sdk_atv_x86
sdk_car_arm64
sdk_car_cw_x86_64
sdk_car_md_arm64
sdk_car_md_x86_64
sdk_car_x86_64
sdk_phone16k_arm64
sdk_phone16k_x86_64
sdk_phone64_arm64
sdk_phone64_arm64_minigbm
sdk_phone64_arm64_riscv64
sdk_phone64_x86_64
sdk_phone64_x86_64_minigbm
sdk_phone64_x86_64_riscv64
sdk_slim_arm64
sdk_slim_x86_64
sdk_tablet_arm64
sdk_tablet_x86_64
sdk_with_runtime_apis
silvermont
sm8450_mini
sm8x50
trout_arm64_ds
yukawa

为了能在 Cuttlefish 上运行 AOSP,我们应该选择带有 cf_ 前缀的产品。

在我这里我选择了 aosp_cf_x86_64_phone

接下来选择 release_config,可以使用 list_releases aosp_cf_x86_64_phone 命令查看可用的 release 配置。

1
2
3
4
5
6
7
8
$ list_releases aosp_cf_x86_64_phone
22:18:01 Build sandboxing disabled due to nsjail error.
aosp_current
ap2a
ap3a
ap4a
bp1a
trunk_staging

我的理解是 aosp_current 相当于开发分支,ap2aap3aap4abp1a 是 release 的版本,而 trunk_staging 暂存分支。

这里我们选择 trunk_staging

最后还差 build_variant 的选择,可以使用 list_variants 来查看支持的 build 变体。

1
2
3
4
$ list_variants 
user
userdebug
eng

user 版就是发布给用户的,权限最小。

userdebug 版是给开发者的,权限较大,适合调试。

eng 版是给工程师的,权限最大,适合开发。

这里我们选择 eng 版。

组合上面 3 个部分,我们最终在终端执行如下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ lunch aosp_cf_x86_64_phone-trunk_staging-eng
22:23:25 Build sandboxing disabled due to nsjail error.

============================================
PLATFORM_VERSION_CODENAME=Baklava
PLATFORM_VERSION=Baklava
TARGET_PRODUCT=aosp_cf_x86_64_phone
TARGET_BUILD_VARIANT=eng
TARGET_ARCH=x86_64
TARGET_ARCH_VARIANT=silvermont
TARGET_2ND_ARCH=x86
TARGET_2ND_ARCH_VARIANT=silvermont
HOST_OS=linux
HOST_OS_EXTRA=Linux-6.14.0-27-generic-x86_64-Ubuntu-24.04.2-LTS
HOST_CROSS_OS=windows
BUILD_ID=MAIN
OUT_DIR=out
SOONG_ONLY=true
============================================

最后我们可以执行 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
2
3
4
mkdir cf
cd cf
tar -xzvf ~/Downloads/cvd-host_package.tar.gz
unzip ~/Downloads/aosp_cf_x86_64_only_phone-img-13912524.zip

启动 Cuttlefish:

1
HOME=$PWD ./bin/launch_cvd --daemon

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

可以使用 adb 命令来连接 Cuttlefish:

1
2
./bin/adb devices
./bin/adb root

停止 Cuttlefish:

1
HOME=$PWD ./bin/stop_cvd

如果能够成功运行 Cuttlefish,那么理论上你就可以运行自己编译的 AOSP 镜像。

为了对环境进行隔离,我们创建一个新的目录来启动自编译的 AOSP 镜像。

1
2
3
4
5
6
mkdir cf2
cd cf2
tar -xzvf ~/Downloads/cvd-host_package.tar.gz

# 拷贝编译好的镜像到当前目录
cp -r ~/AOSP/out/target/product/vsoc_x86_64/* ./

并不是 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
2
sudo apt update
sudo apt install repo

Syncing the Source Code

Create a working directory to store the AOSP source code:

1
2
$ mkdir -p ~/AOSP
$ cd ~/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

  1. Install dependencies
1
sudo apt install -y git devscripts equivs config-package-dev debhelper-compat golang curl
  1. Download the Cuttlefish source code
1
2
git clone https://github.com/google/android-cuttlefish
cd android-cuttlefish
  1. Build Cuttlefish
1
tools/buildutils/build_packages.sh
  1. Install Cuttlefish
1
2
3
4
sudo dpkg -i ./cuttlefish-base_*_*64.deb || sudo apt-get install -f
sudo dpkg -i ./cuttlefish-user_*_*64.deb || sudo apt-get install -f
sudo usermod -aG kvm,cvdnetwork,render $USER
sudo reboot

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
The package has been created.
Attention, the package has been created in the current directory,
not in ".." as indicated by the message above!
正在选中未选择的软件包 cuttlefish-common-build-deps。
(正在读取数据库 ... 系统当前共安装有 230043 个文件和目录。)
准备解压 cuttlefish-common-build-deps_1.18.0_amd64.deb ...
正在解压 cuttlefish-common-build-deps (1.18.0) ...
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
正在修复依赖关系...Starting pkgProblemResolver with broken count: 1
Starting 2 pkgProblemResolver with broken count: 1
Investigating (0) cuttlefish-common-build-deps:amd64 < 1.18.0 @iU K Nb Ib >
Broken cuttlefish-common-build-deps:amd64 依赖 on bazel:amd64 < none @un H >
Removing cuttlefish-common-build-deps:amd64 because I can't find bazel:amd64
Done
完成
Starting pkgProblemResolver with broken count: 0
Starting 2 pkgProblemResolver with broken count: 0
Done
下列软件包将被【卸载】:
cuttlefish-common-build-deps
升级了 0 个软件包,新安装了 0 个软件包,要卸载 1 个软件包,有 4 个软件包未被升级。
有 1 个软件包没有被完全安装或卸载。
解压缩后将会空出 9,216 B 的空间。
(正在读取数据库 ... 系统当前共安装有 230047 个文件和目录。)
正在卸载 cuttlefish-common-build-deps (1.18.0) ...
mk-build-deps: Unable to install cuttlefish-common-build-deps at /usr/bin/mk-build-deps line 460.
mk-build-deps: Unable to install all build-dep packages

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
$ tools/buildutils/build_packages.sh
+++ dirname tools/buildutils/build_packages.sh
++ realpath tools/buildutils/../..
+ REPO_DIR=/home/wgxls/AOSP/Cuttlefish/android-cuttlefish
++ dirname tools/buildutils/build_packages.sh
+ INSTALL_BAZEL=tools/buildutils/installbazel.sh
++ dirname tools/buildutils/build_packages.sh
+ BUILD_PACKAGE=tools/buildutils/build_package.sh
+ command -v bazel
+ install_debuild_dependencies
+ echo 'Installing debuild dependencies'
Installing debuild dependencies
+ sudo apt-get update
命中:1 https://mirrors.aliyun.com/docker-ce/linux/ubuntu noble InRelease
命中:3 https://dl.winehq.org/wine-builds/ubuntu noble InRelease
命中:4 https://nvidia.github.io/libnvidia-container/stable/deb/amd64 InRelease
命中:5 https://dl.google.com/linux/chrome/deb stable InRelease
命中:6 https://packages.microsoft.com/repos/code stable InRelease
命中:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble InRelease
命中:7 http://security.ubuntu.com/ubuntu noble-security InRelease
获取:8 https://repo.steampowered.com/steam stable InRelease [2,858 B]
命中:9 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates InRelease
命中:10 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-backports InRelease
已下载 2,858 B,耗时 4秒 (644 B/s)
正在读取软件包列表... 完成
+ sudo DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef upgrade
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
正在计算更新... 完成
下列软件包新版本的升级因阶段更新而被推迟:
ubuntu-drivers-common
下列软件包的版本将保持不变:
linux-generic-hwe-24.04 linux-headers-generic-hwe-24.04 linux-image-generic-hwe-24.04
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 4 个软件包未被升级。
N: Some packages may have been kept back due to phasing.
+ sudo apt-get install -y devscripts config-package-dev debhelper-compat equivs
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
注意,选中 'debhelper' 而非 'debhelper-compat'
devscripts 已经是最新版 (2.23.7)。
config-package-dev 已经是最新版 (5.5)。
debhelper 已经是最新版 (13.14.1ubuntu5)。
equivs 已经是最新版 (2.3.1)。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 4 个软件包未被升级。
+ tools/buildutils/build_package.sh /home/wgxls/AOSP/Cuttlefish/android-cuttlefish/base
~/AOSP/Cuttlefish/android-cuttlefish/base ~/AOSP/Cuttlefish/android-cuttlefish
Installing package dependencies
dpkg-buildpackage: info: 源码包 cuttlefish-common-build-deps
dpkg-buildpackage: info: 源码版本 1.18.0
dpkg-buildpackage: info: source distribution unstable
dpkg-buildpackage: info: 源码修改者 Equivs Dummy Package Generator <root@wgxls-desktop>
dpkg-buildpackage: info: 主机架构 amd64
dpkg-source --before-build .
debian/rules clean
dh clean
dh_clean
debian/rules binary
dh binary
dh_update_autotools_config
dh_autoreconf
create-stamp debian/debhelper-build-stamp
dh_prep
dh_auto_install --destdir=debian/cuttlefish-common-build-deps/
dh_install
dh_installdocs
dh_installchangelogs
dh_perl
dh_link
dh_strip_nondeterminism
dh_compress
dh_fixperms
dh_missing
dh_dwz
dh_strip
dh_makeshlibs
dh_shlibdeps
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
dpkg-deb: 正在 '../cuttlefish-common-build-deps_1.18.0_amd64.deb' 中构建软件包 'cuttlefish-common-build-deps'
dpkg-genbuildinfo --build=binary -O../cuttlefish-common-build-deps_1.18.0_amd64.buildinfo
dpkg-genchanges --build=binary -O../cuttlefish-common-build-deps_1.18.0_amd64.changes
dpkg-genchanges: info: binary-only upload (no source code included)
dpkg-source --after-build .
dpkg-buildpackage: info: binary-only upload (no source included)

The package has been created.
Attention, the package has been created in the current directory,
not in ".." as indicated by the message above!
正在选中未选择的软件包 cuttlefish-common-build-deps。
(正在读取数据库 ... 系统当前共安装有 230331 个文件和目录。)
准备解压 cuttlefish-common-build-deps_1.18.0_amd64.deb ...
正在解压 cuttlefish-common-build-deps (1.18.0) ...
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
正在修复依赖关系...Starting pkgProblemResolver with broken count: 1
Starting 2 pkgProblemResolver with broken count: 1
Investigating (0) cuttlefish-common-build-deps:amd64 < 1.18.0 @iU K Nb Ib >
Broken cuttlefish-common-build-deps:amd64 依赖 on libtinfo5:amd64 < none @un H >
Removing cuttlefish-common-build-deps:amd64 because I can't find libtinfo5:amd64
Done
完成
Starting pkgProblemResolver with broken count: 0
Starting 2 pkgProblemResolver with broken count: 0
Done
下列软件包将被【卸载】:
cuttlefish-common-build-deps
升级了 0 个软件包,新安装了 0 个软件包,要卸载 1 个软件包,有 4 个软件包未被升级。
有 1 个软件包没有被完全安装或卸载。
解压缩后将会空出 9,216 B 的空间。
(正在读取数据库 ... 系统当前共安装有 230335 个文件和目录。)
正在卸载 cuttlefish-common-build-deps (1.18.0) ...
mk-build-deps: Unable to install cuttlefish-common-build-deps at /usr/bin/mk-build-deps line 460.
mk-build-deps: Unable to install all build-dep packages

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
2
3
sudo apt update
wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb
sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb

Problem 3: Network connection issues

Click to view the error details:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
INFO: Repository +_repo_rules3+selinux instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+android_system_core instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+swiftshader instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+mkbootimg instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+mesa instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+wmediumd instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+avb instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
INFO: Repository +_repo_rules3+android_system_extras instantiated at:
<builtin>: in <toplevel>
Repository rule git_repository defined at:
/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl:208:33: in <toplevel>
ERROR: /home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl:318:9: An error occurred during the fetch of repository '+_repo_rules3+avb':
Traceback (most recent call last):
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl", line 197, column 35, in _git_repository_implementation
update = _clone_or_update_repo(ctx)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git.bzl", line 43, column 20, in _clone_or_update_repo
git_ = git_repo(ctx, directory)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 98, column 12, in git_repo
_update(ctx, git_repo)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 138, column 10, in _update
fetch(ctx, git_repo)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 188, column 13, in fetch
_git(
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 224, column 15, in _git
_error(ctx.name, ["git"] + start + list(args), st.stderr)
File "/home/wgxls/.cache/bazel/_bazel_wgxls/24350124ac429acfb39356c1da64cfde/external/bazel_tools/tools/build_defs/repo/git_worker.bzl", line 318, column 9, in _error
fail("error running '%s' while working with @%s:\n%s" % (command_text, name, stderr))
Error in fail: error running 'git fetch origin refs/heads/*:refs/remotes/origin/* refs/tags/*:refs/tags/*' while working with @+_repo_rules3+avb:
fatal: 无法访问 'https://android.googlesource.com/platform/external/avb/':Failed to connect to android.googlesource.com port 443 after 135162 ms: Couldn't connect to server
ERROR: no such package '@@+_repo_rules3+avb//': error running 'git fetch origin refs/heads/*:refs/remotes/origin/* refs/tags/*:refs/tags/*' while working with @+_repo_rules3+avb:
fatal: 无法访问 'https://android.googlesource.com/platform/external/avb/':Failed to connect to android.googlesource.com port 443 after 135162 ms: Couldn't connect to server
ERROR: /home/wgxls/AOSP/Cuttlefish/android-cuttlefish/base/cvd/cuttlefish/package/BUILD.bazel:3:14: //cuttlefish/package:cvd depends on @@+_repo_rules3+avb//:avbtool.py in repository @@+_repo_rules3+avb which failed to fetch. no such package '@@+_repo_rules3+avb//': error running 'git fetch origin refs/heads/*:refs/remotes/origin/* refs/tags/*:refs/tags/*' while working with @+_repo_rules3+avb:
fatal: 无法访问 'https://android.googlesource.com/platform/external/avb/':Failed to connect to android.googlesource.com port 443 after 135162 ms: Couldn't connect to server
ERROR: Analysis of target '//cuttlefish/package:cvd' failed; build aborted: Analysis failed
INFO: Elapsed time: 403.699s, Critical Path: 0.04s
INFO: 1 process: 1 internal.
ERROR: Build did NOT complete successfully
FAILED:
make[1]: *** [debian/rules:79:override_dh_auto_build] 错误 1
make[1]: 离开目录“/home/wgxls/AOSP/Cuttlefish/android-cuttlefish/base”
make: *** [debian/rules:69:binary] 错误 2
dpkg-buildpackage: 错误: debian/rules binary subprocess returned exit status 2
debuild: fatal error at line 1184:
dpkg-buildpackage -us -uc -ui -i -b failed

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
2
cd ~/AOSP
source build/envsetup.sh

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
2
$ lunch
No target specified. See lunch --help

We can use list_products to view the supported product list:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
$ list_products 
22:14:41 Build sandboxing disabled due to nsjail error.
aosp_64bitonly_x86_64
aosp_akita
aosp_akita_16k
aosp_akita_fullmte
aosp_arm
aosp_arm64
aosp_arm64_fullmte
aosp_arm64_plus_armv7
aosp_bluejay
aosp_bluejay_car
aosp_bluejay_hwasan
aosp_caiman
aosp_caiman_16k
aosp_caiman_fullmte
aosp_cf_arm64_auto
aosp_cf_arm64_minidroid
aosp_cf_arm64_only_phone
aosp_cf_arm64_only_phone_hwasan
aosp_cf_arm64_only_phone_vendor
aosp_cf_arm64_phone
aosp_cf_arm64_phone_fullmte
aosp_cf_arm64_phone_hwasan
aosp_cf_arm64_phone_pgagnostic
aosp_cf_arm64_phone_vendor
aosp_cf_arm64_slim
aosp_cf_arm_minidroid
aosp_cf_riscv64_minidroid
aosp_cf_riscv64_phone
aosp_cf_riscv64_slim
aosp_cf_riscv64_wear
aosp_cf_x86_64_auto
aosp_cf_x86_64_auto_dd
aosp_cf_x86_64_auto_md
aosp_cf_x86_64_auto_mdnd
aosp_cf_x86_64_auto_portrait
aosp_cf_x86_64_foldable
aosp_cf_x86_64_host
aosp_cf_x86_64_minidroid
aosp_cf_x86_64_only_phone
aosp_cf_x86_64_only_phone_hsum
aosp_cf_x86_64_pc
aosp_cf_x86_64_phone
aosp_cf_x86_64_phone_pgagnostic
aosp_cf_x86_64_phone_soong_system
aosp_cf_x86_64_phone_vendor
aosp_cf_x86_64_slim
aosp_cf_x86_64_ssi
aosp_cf_x86_64_tv
aosp_cf_x86_64_wear
aosp_cf_x86_go_phone
aosp_cf_x86_tv
aosp_cf_x86_wear
aosp_cheetah
aosp_cheetah_car
aosp_cheetah_hwasan
aosp_cloudripper
aosp_comet
aosp_felix
aosp_felix_hwasan
aosp_husky
aosp_husky_car
aosp_husky_fullmte
aosp_husky_pgagnostic
aosp_komodo
aosp_komodo_16k
aosp_komodo_fullmte
aosp_lynx
aosp_lynx_hwasan
aosp_oriole
aosp_oriole_64
aosp_oriole_car
aosp_oriole_hwasan
aosp_oriole_pgagnostic_64
aosp_oriole_pkvm
aosp_panther
aosp_panther_car
aosp_panther_hwasan
aosp_raven
aosp_raven_64
aosp_raven_car
aosp_raven_hwasan
aosp_raven_pgagnostic_64
aosp_raven_pkvm
aosp_ravenclaw
aosp_redfin_car
aosp_ripcurrent
aosp_ripcurrent24
aosp_ripcurrent24_fullmte
aosp_ripcurrent_fullmte
aosp_ripcurrentpro
aosp_ripcurrentpro_fullmte
aosp_riscv64
aosp_shiba
aosp_shiba_fullmte
aosp_shiba_pgagnostic
aosp_slider
aosp_slider_hwasan
aosp_sunfish_car
aosp_tangorpro
aosp_tangorpro_car
aosp_tangorpro_hwasan
aosp_tokay
aosp_tokay_16k
aosp_tokay_fullmte
aosp_trout_arm64
aosp_trout_x86_64
aosp_tv_arm64
aosp_tv_x86
aosp_whitefin
aosp_whitefin_64
aosp_whitefin_hwasan
aosp_whitefin_pkvm
aosp_x86
aosp_x86_64
aosp_x86_arm
arm_krait
arm_v7_v8
armv8
armv8_cortex_a55
armv8_kryo385
csi_arm
csi_arm64
csi_x86
csi_x86_64
db845c
db845c_mini
factory_akita
factory_bluejay
factory_caiman
factory_cheetah
factory_cloudripper
factory_comet
factory_felix
factory_husky
factory_komodo
factory_lynx
factory_oriole
factory_panther
factory_raven
factory_ravenclaw
factory_ripcurrent
factory_ripcurrent24
factory_ripcurrentpro
factory_shiba
factory_slider
factory_tangorpro
factory_tokay
factory_whitefin
full
full_slider
full_x86
fvp
fvp_mini
generic
generic_system_arm64
generic_system_x86
generic_system_x86_64
generic_system_x86_arm
generic_x86
gsi_arm
gsi_arm64
gsi_car_arm64
gsi_car_x86_64
gsi_tv_arm
gsi_tv_arm64
gsi_x86
gsi_x86_64
haiku
hikey
hikey32
hikey64_only
hikey960
hikey960_tv
hikey_tv
linaro_swr
linux_bionic
mainline_sdk
mainline_system_arm64
mainline_system_x86
mainline_system_x86_64
mainline_system_x86_arm
mgsi_arm
mgsi_arm64
mgsi_x86
mgsi_x86_64
mini_arm64
mini_armv7a_neon
mini_x86
mini_x86_64
module_arm
module_arm64
module_arm64only
module_riscv64
module_x86
module_x86_64
module_x86_64only
ndk
poplar
qemu_trusty_arm64
riscv64
sdk
sdk_atv64_arm64
sdk_atv_x86
sdk_car_arm64
sdk_car_cw_x86_64
sdk_car_md_arm64
sdk_car_md_x86_64
sdk_car_x86_64
sdk_phone16k_arm64
sdk_phone16k_x86_64
sdk_phone64_arm64
sdk_phone64_arm64_minigbm
sdk_phone64_arm64_riscv64
sdk_phone64_x86_64
sdk_phone64_x86_64_minigbm
sdk_phone64_x86_64_riscv64
sdk_slim_arm64
sdk_slim_x86_64
sdk_tablet_arm64
sdk_tablet_x86_64
sdk_with_runtime_apis
silvermont
sm8450_mini
sm8x50
trout_arm64_ds
yukawa

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
2
3
4
5
6
7
8
$ list_releases aosp_cf_x86_64_phone
22:18:01 Build sandboxing disabled due to nsjail error.
aosp_current
ap2a
ap3a
ap4a
bp1a
trunk_staging

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
2
3
4
$ list_variants 
user
userdebug
eng

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ lunch aosp_cf_x86_64_phone-trunk_staging-eng
22:23:25 Build sandboxing disabled due to nsjail error.

============================================
PLATFORM_VERSION_CODENAME=Baklava
PLATFORM_VERSION=Baklava
TARGET_PRODUCT=aosp_cf_x86_64_phone
TARGET_BUILD_VARIANT=eng
TARGET_ARCH=x86_64
TARGET_ARCH_VARIANT=silvermont
TARGET_2ND_ARCH=x86
TARGET_2ND_ARCH_VARIANT=silvermont
HOST_OS=linux
HOST_OS_EXTRA=Linux-6.14.0-27-generic-x86_64-Ubuntu-24.04.2-LTS
HOST_CROSS_OS=windows
BUILD_ID=MAIN
OUT_DIR=out
SOONG_ONLY=true
============================================

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
2
3
4
mkdir cf
cd cf
tar -xzvf ~/Downloads/cvd-host_package.tar.gz
unzip ~/Downloads/aosp_cf_x86_64_only_phone-img-13912524.zip

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
2
./bin/adb devices
./bin/adb root

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
2
3
4
5
6
mkdir cf2
cd cf2
tar -xzvf ~/Downloads/cvd-host_package.tar.gz

# Copy the compiled image to the current directory
cp -r ~/AOSP/out/target/product/vsoc_x86_64/* ./

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