工欲善其事 必先利其器
本篇将会搭建一个完美的Linux Kernel及其内核模块的源码阅读开发环境
当我们开始研究Android Kernel,想要优雅的阅读源码好像是一件费劲的事情。
因为Kernel源码实在是太庞大了,打开一个c文件,想要详细的研究研究,甚至上手写两句代码,即没有高亮提示,也没有代码跳转。在这种情况下,想要理清楚内核源码,相当不易。
用CLion? 貌似不太行。
Kernel的构建体系是make而不是类似于LLVM的CMake。Clion直接打开Kernel源码是无法被CLion解析的。
用Source Insight?貌似不是非常完美。
对于Kernel源码来说,很多函数symbols一样,只是适用于不同架构罢了。Source Insight在跳转的时候,全源引索,并不会帮我们加以区分。诸如此类的问题,Source Insight还有很多...强迫症患者表示很难受~
用VsCode?貌似更不行?
VsCode对C/C++代码的高亮提示,依托于C/C++ Extension Pack
这个插件,我不清楚别人体验如何,至少对我来说,这个插件有多烂,我都不想多做评价....
为什么IDE集成开发环境可以完美的索引项目代码?
参考于微软的一篇文档,我了解到了语言服务器这个东西。
什么是语言服务器,有什么作用?
CLion对代码索引的功能 貌似就是通过clangd实现的。
如何让语言服务器运作起来?
我们现在知道了,想要对c语言的代码做解析,就需要clangd这个语言服务器。那么,如何让clangd运作起来呢?clangd对代码做解析,需要compile_commands.json
文件。
该文件是什么作用?
这个文件记录着我们对源码编译时候的每个命令,用的什么编译器,提供的什么编译参数,链接了哪些库,设置了什么宏,编译的什么源码文件等等。
如此,clangd就可以通过编译命令,详细的了解到整个编译流程。
如何生成该文件?
这里特别提一嘴,对于mk体系编译的的项目
mk脚本,其本质上是make,但是对于安卓的来说,生成编译描述文件非常简单
官方有文档提供命令
所以,理论上来说,搭建的这套代码解析方案,不仅仅适用于Kernel源码阅读。也适用于各种交叉编译
毫无疑问 Kernel的源码大多是c文件,以及少部分的汇编文件,设备树文件......
Kernel正好是make体系,理论上是可以用Bear的。
由于我做教程的时候,已经把内核编译结束了,实在不想重新编译内核,理论上选哪个都一样,我们只是要个编译描述文件罢。
虽然C/C++ Extension Pack相当的烂,但是部分C/C++方面的东西,还需他提供支持。
所以这里依然需要安装该插件,后续在设置中禁用掉他的代码提示服务,转交给clangd插件即可。
关于clangd插件
完整编译内核
这里默认读者会换源或者其他手法保持网络通畅
生成编译描述文件
对于Out-of-tree编译的内核模块
详细见原项目地址的Out-of-tree module development
这一套代码解析方案也完美的适用于Out-of-tree的内核模块
配置VsCode
对于VsCode来说.vscode
目录下,是一些配置文件。
我们修改原项目的setting.json
文件,内容修改成如下:
注释已经写到相当清楚,这里不再赘述。
打开Kernel根目录,等待索引结束
你发现会报很多无关痛痒的警告:
内核源码根目录下,新建一个文件.clangd
,内容如下:
make
bear make
set
(CMAKE_EXPORT_COMPILE_COMMANDS
True
)
set
(CMAKE_EXPORT_COMPILE_COMMANDS
True
)
ndk
-
build GEN_COMPILE_COMMANDS_DB
=
true
ndk
-
build GEN_COMPILE_COMMANDS_DB
=
true
repo init
-
u https:
/
/
android.googlesource.com
/
kernel
/
manifest
-
b common
-
android12
-
5.10
repo init
-
u https:
/
/
android.googlesource.com
/
kernel
/
manifest
-
b common
-
android12
-
5.10
repo sync
BUILD_CONFIG
=
common
/
build.config.gki.aarch64 build
/
build.sh
BUILD_CONFIG
=
common
/
build.config.gki.aarch64 build
/
build.sh
cd common
git clone
-
-
depth
=
1
https:
/
/
github.com
/
amezin
/
vscode
-
linux
-
kernel.git .vscode
cd common
git clone
-
-
depth
=
1
https:
/
/
github.com
/
amezin
/
vscode
-
linux
-
kernel.git .vscode
python .vscode
/
generate_compdb.py
-
O ..
/
out
/
android12
-
5.10
/
common
/
ls
-
al | grep compile_commands.json
python .vscode
/
generate_compdb.py
-
O ..
/
out
/
android12
-
5.10
/
common
/
ls
-
al | grep compile_commands.json
{
"files.associations"
: {
"iostream"
:
"cpp"
,
"intrinsics.h"
:
"c"
,
"ostream"
:
"cpp"
,
"vector"
:
"cpp"
},
"editor.formatOnPaste"
: true,
"editor.formatOnSave"
: true,
"editor.formatOnType"
: true,
/
/
关闭 C
/
C
+
+
Extension Pack 插件的提示 防止其与clangd冲突
"C_Cpp.errorSquiggles"
:
"Disabled"
,
"C_Cpp.intelliSenseEngineFallback"
:
"Disabled"
,
"C_Cpp.intelliSenseEngine"
:
"Disabled"
,
"C_Cpp.autocomplete"
:
"Disabled"
,
/
/
So you don't get autocomplete
from
both extensions.
/
/
指向clangd路径
"clangd.path"
:
"/tmp/NDK/ndk-r25b/toolchains/llvm/prebuilt/linux-x86_64/bin/clangd"
,
"clangd.arguments"
: [
/
/
compelie_commands.json 文件的目录位置
"--compile-commands-dir=${workspaceFolder}/"
,
/
/
让 Clangd 生成更详细的日志
"--log=verbose"
,
/
/
输出的 JSON 文件更美观
"--pretty"
,
/
/
全局补全
"--all-scopes-completion"
,
/
/
建议风格:打包(重载函数只会给出一个建议)相反可以设置为detailed
"--completion-style=bundled"
,
/
/
跨文件重命名变量
"--cross-file-rename"
,
/
/
允许补充头文件
"--header-insertion=iwyu"
,
/
/
输入建议中,已包含头文件的项与还未包含头文件的项会以圆点加以区分
"--header-insertion-decorators"
,
/
/
在后台自动分析文件 基于 complie_commands
"--background-index"
,
/
/
启用 Clang
-
Tidy 以提供「静态检查」
"--clang-tidy"
,
/
/
Clang
-
Tidy 静态检查的参数,指出按照哪些规则进行静态检查
/
/
参数后部分的
*
表示通配符
/
/
在参数前加入
-
,如
-
modernize
-
use
-
trailing
-
return
-
type
,将会禁用某一规则
"--clang-tidy-checks=cppcoreguidelines-*,performance-*,bugprone-*,portability-*,modernize-*,google-*"
,
/
/
默认格式化风格: 谷歌开源项目代码指南
"--fallback-style=file"
,
/
/
同时开启的任务数量
"-j=2"
,
/
/
pch优化的位置(memory 或 disk,选择memory会增加内存开销,但会提升性能)
"--pch-storage=disk"
,
/
/
启用这项时,补全函数时,将会给参数提供占位符
/
/
我选择禁用
"--function-arg-placeholders=false"
],
}
{
"files.associations"
: {
"iostream"
:
"cpp"
,
"intrinsics.h"
:
"c"
,
"ostream"
:
"cpp"
,
"vector"
:
"cpp"
},
"editor.formatOnPaste"
: true,
"editor.formatOnSave"
: true,
"editor.formatOnType"
: true,
/
/
关闭 C
/
C
+
+
Extension Pack 插件的提示 防止其与clangd冲突
"C_Cpp.errorSquiggles"
:
"Disabled"
,
"C_Cpp.intelliSenseEngineFallback"
:
"Disabled"
,
"C_Cpp.intelliSenseEngine"
:
"Disabled"
,
"C_Cpp.autocomplete"
:
"Disabled"
,
/
/
So you don't get autocomplete
from
both extensions.
/
/
指向clangd路径
"clangd.path"
:
"/tmp/NDK/ndk-r25b/toolchains/llvm/prebuilt/linux-x86_64/bin/clangd"
,
"clangd.arguments"
: [
/
/
compelie_commands.json 文件的目录位置
"--compile-commands-dir=${workspaceFolder}/"
,
/
/
让 Clangd 生成更详细的日志
"--log=verbose"
,
/
/
输出的 JSON 文件更美观
"--pretty"
,
/
/
全局补全
"--all-scopes-completion"
,
/
/
建议风格:打包(重载函数只会给出一个建议)相反可以设置为detailed
"--completion-style=bundled"
,
/
/
跨文件重命名变量
"--cross-file-rename"
,
/
/
允许补充头文件
"--header-insertion=iwyu"
,
/
/
输入建议中,已包含头文件的项与还未包含头文件的项会以圆点加以区分
"--header-insertion-decorators"
,
/
/
在后台自动分析文件 基于 complie_commands
"--background-index"
,
/
/
启用 Clang
-
Tidy 以提供「静态检查」
"--clang-tidy"
,
/
/
Clang
-
Tidy 静态检查的参数,指出按照哪些规则进行静态检查
/
/
参数后部分的
*
表示通配符
/
/
在参数前加入
-
,如
-
modernize
-
use
-
trailing
-
return
-
type
,将会禁用某一规则
"--clang-tidy-checks=cppcoreguidelines-*,performance-*,bugprone-*,portability-*,modernize-*,google-*"
,
/
/
默认格式化风格: 谷歌开源项目代码指南
"--fallback-style=file"
,
/
/
同时开启的任务数量
"-j=2"
,
/
/
pch优化的位置(memory 或 disk,选择memory会增加内存开销,但会提升性能)
"--pch-storage=disk"
,
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-11-30 21:52
被Ssage泓清编辑
,原因: 修正