AOSP阅读环境配置

android_stack

硬件环境

DIY主机

CPU:AMD R9 7950X

内存:光威 6400Hz 32G(16G * 2)

主板:GIGABYTE 冰雕小板

硬盘:ZhiTai TiPlus 7100 Gen4 2TB

软件配置

系统:Ubuntu 24.04

源代码安装

具体流程可分为

1.repo工具下载

2.源代码下载

安装流程可参考

清华镜像源帮助问题

工程基础配置

注意这里不是说repo工具需要做一些配置。

而是说需要使用repo做一些工程上的配置。

1.repo start branchName –all

将所有工程开启新分支(方便后续拉取多分支)

2.配置脚本

可将常用的脚本书写复用

如下是笔者封装的lunch脚本。(用于source aosp脚本)

1
2
3
source build/envsetup.sh
# 自定义output路径,防止在不同分支check的时候输出相互覆盖。打包异常。
export OUT_DIR=out/$(repo branch | grep "\*" | awk -F ' ' '{print $2}') && lunch aosp_redfin-userdebug

3.zshrc配置

aosp soong build system配置,用于方便调试。

1
2
3
4
5
# aosp soong 
# 生成compile_commands.json
# ref https://android.googlesource.com/platform/build/soong/+show/master/docs/compdb.md
export SOONG_GEN_COMPDB=1
export SOONG_GEN_COMPDB_DEBUG=1

源码阅读环境配置

现在是2025/1/12日

AOSP的源代码主要是C++/Java, 目前没找到特别满意的能同时阅读 C++ & Java的工具。所以C++ Java环境目前是单独配置的。

其中Java使用的是ASfp, C++使用的VsCode + Clangd + LLDB

java环境

1.Asfp配置

安装过程略。

具体可见Andriod Developer官网

简单介绍下Asfp.(Android Studio for Platform)其实就是Android Studio. (只有Linux可以安装)

差别就是这个Android Studio兼容了soong构建系统,可以用于直接阅读 aosp source code

ASfp其实就比普通Android Studio多了一个tab.

image-20250112180210389

图一 Asfp tab

使用方式就简单说下可以通过图一的 Asfp new Project开启一个弹窗,填写部分信息等待Sync完成就好了~

a. 输入aosp路径

image-20250112180659865

图二Asfp WorkSpace设置

b.填写lunch target,阅读源码的路径(一般都是frameworks/base, 按需填写)

image-20250112180845308

图三 Asfp 打开模块配置

2.配置asfp json文件(如果你跟我一样自定义了OUT_DIR或者其他路径)

image-20250112182709597

图四 config.json配置

到这就基本上配置好了~

native环境

0.安装vscode

1.插件安装

CodeLLDB

Clangd

2.配置Clangd

配置如下XXX.code-workspace文件

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
{
"folders": [
{
"name": "android13-r78",
"path": "/Users/rose/aosp/source/"
}
],
"settings": {
// 开启粘贴保存自动格式化
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"C_Cpp.errorSquiggles": "Disabled",
"C_Cpp.intelliSenseEngineFallback": "Disabled",
"C_Cpp.intelliSenseEngine": "Disabled",
// 由于需系统版本原因,可能路径有一定差异,可以在prebuilts/clang/host/linux-x86/找找
"clangd.path": "/Users/rose/aosp/source/prebuilts/clang/host/linux-x86/clang-r450784d/bin/clangd",
// Clangd 运行参数(在终端/命令行输入 clangd --help-list-hidden 可查看更多)
"clangd.arguments": [
// compile_commands.json 生成文件夹
"--compile-commands-dir=/Users/rose/aosp/source/out/android13-r78/soong/development/ide/compdb/",
// 让 Clangd 生成更详细的日志
"--log=verbose",
// 输出的 JSON 文件更美观
"--pretty",
// 全局补全(输入时弹出的建议将会提供 CMakeLists.txt 里配置的所有文件中可能的符号,会自动补充头文件)
"--all-scopes-completion",
// 建议风格:打包(重载函数只会给出一个建议)
// 相反可以设置为detailed
"--completion-style=bundled",
// 跨文件重命名变量
"--cross-file-rename",
// 允许补充头文件
"--header-insertion=iwyu",
// 输入建议中,已包含头文件的项与还未包含头文件的项会以圆点加以区分
"--header-insertion-decorators",
// 在后台自动分析文件(基于 complie_commands,我们用CMake生成)
"--background-index",
// 启用 Clang-Tidy 以提供「静态检查」
"--clang-tidy",
// Clang-Tidy 静态检查的参数,指出按照哪些规则进行静态检查,详情见「与按照官方文档配置好的 VSCode 相比拥有的优势」
// 参数后部分的*表示通配符
// 在参数前加入-,如-modernize-use-trailing-return-type,将会禁用某一规则
"--clang-tidy-checks=cppcoreguidelines-*,performance-*,bugprone-*,portability-*,modernize-*,google-*",
// 默认格式化风格: 谷歌开源项目代码指南
// "--fallback-style=file",
// 同时开启的任务数量, 可以依据核心数调节
"-j=32",
// pch优化的位置(memory 或 disk,选择memory会增加内存开销,但会提升性能) 推荐在板子上使用disk
"--pch-storage=disk",
// 启用这项时,补全函数时,将会给参数提供占位符,键入后按 Tab 可以切换到下一占位符,乃至函数末
// 我选择禁用
"--function-arg-placeholders=false"
],
"lldb.displayFormat": "auto",
"lldb.showDisassembly": "auto",
"lldb.dereferencePointers": true,
"lldb.consoleMode": "commands",
},
"launch": {
"configurations": [

]
}
}

3.配置LLDB

在aosp root路径下下配置lldb init file

1
2
3
4
# 排除SIGSTOP,SIGSEGV断点
process handle SIGSTOP -n true -p true -s false
process handle SIGSEGV -n true -p true -s false

具体调试流程不做详细介绍,具体可见Andriod Developer 官网

Art 调试环境

art中的很多代码是做了优化的,这会导致。我们断点无法对应上。

需要做如下修改以防止代码优化。

art/build/Android.bp

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
art_module_art_global_defaults {
// Additional flags are computed by art.go

name: "art_defaults",

// ......

cflags: [
// Base set of cflags used by all things ART.
"-fno-rtti",
"-ggdb3",
"-Wall",
"-Werror",
"-Wextra",
"-Wstrict-aliasing",
"-fstrict-aliasing",
"-Wunreachable-code",
"-Wredundant-decls",
"-Wshadow",
"-Wunused",
"-fvisibility=protected",
"-O0", // 启用基础优化以减少栈使用
"-fno-inline", // 可选:禁用函数内联
"-fno-inline-functions-called-once", // 进一步禁用内联
"-fno-optimize-sibling-calls", // 进一步禁用内联
"-Wno-error=frame-larger-than", // 堆栈大小超出不报错
"-Wno-frame-larger-than", // 关闭堆栈大小检查
"-fno-omit-frame-pointer", // 保留栈针
"-g3", // 生成调试信息

// Warn about thread safety violations with clang.
"-Wthread-safety",
// TODO(b/144045034): turn on -Wthread-safety-negative
//"-Wthread-safety-negative",

// Warn if switch fallthroughs aren't annotated.
"-Wimplicit-fallthrough",

// Enable float equality warnings.
"-Wfloat-equal",

// Enable warning of converting ints to void*.
"-Wint-to-void-pointer-cast",

// Enable warning of wrong unused annotations.
"-Wused-but-marked-unused",

// Enable warning for deprecated language features.
"-Wdeprecated",

// Enable warning for unreachable break & return.
"-Wunreachable-code-break",
"-Wunreachable-code-return",

// Disable warning for use of offsetof on non-standard layout type.
// We use it to implement OFFSETOF_MEMBER - see macros.h.
"-Wno-invalid-offsetof",

// Enable inconsistent-missing-override warning. This warning is disabled by default in
// Android.
"-Winconsistent-missing-override",

// Enable thread annotations for std::mutex, etc.
"-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
],

// ......

}

art/runtime/Android.bp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Properties common to `libart` and `libart-broken`.
art_cc_defaults {
name: "libart_common_defaults",
// ....
target: {
android: {
lto: {
thin: false,
},
},
},

// .....
}

在配置修改完成以后需要编译一个apex,然后安装。

具体流程可参考 (如果想集成到系统镜像中,也可以参考,但是安装起来需要刷机,挺麻烦的)

art/build/README.md

1
2
3
4
5
6
7
8
9
10
# 编译apex(测试版将pkg 替换为 com.android.art.debug)
banchan com.android.art <arch>
export SOONG_ALLOW_MISSING_DEPENDENCIES=true

# 编译
m apps_only dist

# 安装 & 重启
adb install out/dist/com.android.art.apex
adb reboot

Linux Kernel 阅读环境

更新时间:2026/3/17

Android13-5.10中已经有生成compile_commands.json的脚本

1
prebuilts/clang/host/linux-x86/clang-r450784e/python3/bin/python3 aosp/scripts/clang-tools/gen_compile_commands.py
  • 配置vscode 文件
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
{
"folders": [
{
"name": "android13_5.10",
"path": "/mnt/data/code/android-kernel"
}
],
"settings": {
// 开启粘贴保存自动格式化
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"C_Cpp.errorSquiggles": "Disabled",
"C_Cpp.intelliSenseEngineFallback": "Disabled",
"C_Cpp.intelliSenseEngine": "Disabled",
"clangd.path": "/mnt/data/code/android-kernel/prebuilts/clang/host/linux-x86/clang-r450784e/bin/clangd",
// Clangd 运行参数(在终端/命令行输入 clangd --help-list-hidden 可查看更多)
"clangd.arguments": [
// compile_commands.json 生成文件夹
"--compile-commands-dir=${workspaceFolder}",
// 让 Clangd 生成更详细的日志
"--log=verbose",
// 输出的 JSON 文件更美观
"--pretty",
// 全局补全(输入时弹出的建议将会提供 CMakeLists.txt 里配置的所有文件中可能的符号,会自动补充头文件)
"--all-scopes-completion",
// 建议风格:打包(重载函数只会给出一个建议)
// 相反可以设置为detailed
"--completion-style=bundled",
// 跨文件重命名变量
"--cross-file-rename",
// 允许补充头文件
"--header-insertion=iwyu",
// 输入建议中,已包含头文件的项与还未包含头文件的项会以圆点加以区分
"--header-insertion-decorators",
// 在后台自动分析文件(基于 complie_commands,我们用CMake生成)
"--background-index",
// 启用 Clang-Tidy 以提供「静态检查」
"--clang-tidy",
// Clang-Tidy 静态检查的参数,指出按照哪些规则进行静态检查,详情见「与按照官方文档配置好的 VSCode 相比拥有的优势」
// 参数后部分的*表示通配符
// 在参数前加入-,如-modernize-use-trailing-return-type,将会禁用某一规则
"--clang-tidy-checks=cppcoreguidelines-*,performance-*,bugprone-*,portability-*,modernize-*,google-*",
// 默认格式化风格: 谷歌开源项目代码指南
// "--fallback-style=file",
// 同时开启的任务数量
"-j=32",
// pch优化的位置(memory 或 disk,选择memory会增加内存开销,但会提升性能) 推荐在板子上使用disk
"--pch-storage=disk",
// 启用这项时,补全函数时,将会给参数提供占位符,键入后按 Tab 可以切换到下一占位符,乃至函数末
// 我选择禁用
"--function-arg-placeholders=false"
],
"lldb.displayFormat": "auto",
"lldb.showDisassembly": "auto",
"lldb.dereferencePointers": true,
"lldb.consoleMode": "commands",
"go.delveConfig": {
"debugAdapter": "dlv-dap",
"dlvLoadConfig": {
"path": "/home/rose/go/bin/dlv",
"followPointers": true,
"maxVariableRecurse": 1,
"maxStringLen": 64,
"maxArrayValues": 64,
"maxStructFields": -1
}
},
"go.toolsManagement.go": "/usr/bin/go"
},
"launch": {
"configurations": [
{
"name": "(lldbclient.py) Attach app_process64 (port: 5039)",
"type": "lldb",
"request": "attach",
"relativePathBase": "/mnt/data/code/android-kernel",
"sourceMap": {
"/b/f/w": "/mnt/data/code/android-kernel",
"": "/mnt/data/code/android-kernel",
".": "/mnt/data/code/android-kernel"
},
"initCommands": [
"settings append target.exec-search-paths /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/ /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/hw /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/ssl/engines /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/drm /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/egl /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/soundfx /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib64/ /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib64/hw /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib64/egl /mnt/data/code/android-kernel/out/target/product/oriole/symbols/apex/com.android.runtime/bin",
"command source ${workspaceFolder}/.lldbinit"
],
"targetCreateCommands": [
"target create /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/bin/app_process64",
"target modules search-paths add / /mnt/data/code/android-kernel/out/target/product/module_arm64/symbols",
"target modules search-paths add / /mnt/data/code/android-kernel/out/target/product/oriole/symbols/",
// "command source ${workspaceFolder}/targetCreate.lldbinit"
],
"processCreateCommands": [
"gdb-remote 5039"
]
},
{
"name": "(lldbclient.py) Attach mediaserver (port: 5039)",
"type": "lldb",
"request": "attach",
"relativePathBase": "/mnt/data/code/android-kernel",
"sourceMap": {
"/b/f/w": "/mnt/data/code/android-kernel",
"": "/mnt/data/code/android-kernel",
".": "/mnt/data/code/android-kernel"
},
"initCommands": [
"settings append target.exec-search-paths /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib/ /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib/hw /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib/ssl/engines /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib/drm /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib/egl /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib/soundfx /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib/ /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib/hw /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib/egl /mnt/data/code/android-kernel/out/target/product/oriole/symbols/apex/com.android.runtime/bin /mnt/data/code/android-kernel/out/target/product/module_arm64/symbols/",
"command source ${workspaceFolder}/.lldbinit"
],
"targetCreateCommands": [
"target create /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/bin/mediaserver",
"target modules search-paths add / /mnt/data/code/android-kernel/out/target/product/oriole/symbols/"
],
"processCreateCommands": [
"gdb-remote 5039"
]
},
{
"name": "(lldbclient.py) Attach surfaceflinger (port: 5039)",
"type": "lldb",
"request": "attach",
"relativePathBase": "/mnt/data/code/android-kernel",
"sourceMap": {
"/b/f/w": "/mnt/data/code/android-kernel",
"": "/mnt/data/code/android-kernel",
".": "/mnt/data/code/android-kernel"
},
"initCommands": [
"settings append target.exec-search-paths /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/ /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/hw /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/ssl/engines /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/drm /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/egl /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/lib64/soundfx /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib64/ /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib64/hw /mnt/data/code/android-kernel/out/target/product/oriole/symbols/vendor/lib64/egl /mnt/data/code/android-kernel/out/target/product/oriole/symbols/apex/com.android.runtime/bin"
],
"targetCreateCommands": [
"target create /mnt/data/code/android-kernel/out/target/product/oriole/symbols/system/bin/surfaceflinger",
"target modules search-paths add / /mnt/data/code/android-kernel/out/target/product/oriole/symbols/"
],
"processCreateCommands": [
"gdb-remote 5039"
]
},
{
"debugAdapter": "legacy",
"name": "attach soong_ui",
"type": "go",
"request": "attach",
"mode": "remote",
"host": "127.0.0.1",
"port": 2345,
"asRoot": true,
"cwd": "${workspaceFolder}",
"apiVersion": 2,

// "mode": "local",
// "processId": 0,
// "asRoot": true,
// "apiVersion": 2,
// "logOutput": "dap"
}

],
},
}

其他

repo技巧

repo其实本质上就是通过manifest组织多个git repository, 通过统一对仓库执行git指令实现管理

1.repo forall

repo forall是一个非常有用的指令他可以实现特别多想法。

1
2
3
4
5
6
7
8
9
# 清除untrack commit(清除以前记得做check, 不可回滚!!!)
repo forall -c "git clean -dfn"

# stash所有变更
repo forall -c "git stash push -m XXX"

# 查看所有project路径
repo forall -c "pwd"

2.repo init

init不仅仅能用于初始化下载源码,还能用于切换分支。

假如有一个场景:我现在下载了android13的源码,如果我想且回去。就可以使用如下指令实现

1
2
3
4
5
6
7
8
9
10
11
12
# 下载android13源码
repo init -u https://XXX -b android-13.0.0_r78

# 下载
repo sync

# 切换分支
repo init -b android-11.0.0_r48

# checkout到制定的指定的分支
# 这里-l是指 `不使用network,本地同步修改工作区`
repo sync -l

3.repo checkout

用于将所有的project切换到特定分支

等价于repo forall -c "git checkout XXX"

总结

1.主要针对于Java & C++源码阅读环境 & 调试环境进行了配置。

2.其中Java可以使用Asfp进行源码查阅以及调试

Asfp其实也可以阅读C++代码,只是阅读体验不佳。

代码中会有很多报错。语法提示,代码跳转都存在一些问题。

不过好在Java源码阅读、debug特别给力。(很吃性能,内存20G以下电脑就别尝试了,32G勉强能用)

3.C++需要使用Vscode + LLDB + Clangd

LLDB用于调试,Clangd用于解析源码查阅,阅读体验不逊于Clion, 而且不吃性能

缺点很多,主要是配置比较繁琐,不过反过来看定制性很强~