0


使用vscode+clangd远程精准浏览linux kernel源码(原创)

vscode是一个编辑器,可以调用各种插件来完成更多高级功能,clangd是一个代码解析工具,是clang的一个子项目。vscode中集成clangd以后,就可以精准的查看代码的调用情况,因为clangd对整个编译过程进行了跟踪(使用compile_commands.json文件实现),对于linux kernel这种复杂的项目非常适合,放弃source insight吧,那玩意儿没啥用,一个宏定义你能找出来几百个定义,鬼知道哪个是实际的定义来源。

下面按照步骤来搞一下:

1 安装vscode

这个自行搜索

2 在linux系统中安装cmake

安装clangd的时候有两种方法,一种是ubuntu中直接apt-get install,但是这种的clangd版本较低,一种是直接编译clangd的代码安装,编译代码用的cmake,所以还得装cmake,自行搜索,最好也编译代码安装,因为apt-get的cmake版本很低。参考如下文章:Linux编译安装cmake源码_回忆丿从前的博客-CSDN博客

3 在linux系统中安装clangd

这个估计可以使用apt-get install来安装,参考官网:Getting started (llvm.org)

Installing the

clangd

package will usually give you a slightly older version.

Try to install a packaged release (12.0):

sudo apt-get install clangd-12

If that’s not found, at least

clangd-9

or

clangd-8

should be available. Versions before 8 were part of the

clang-tools

package.

This will install clangd as

/usr/bin/clangd-12

. Make it the default

clangd

:

sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-12 100

但是我是直接下的代码编译后安装的,可以参考这个文章:ubuntu 安装 Clang/LLVM 15.0.4_llvm下载_525小白菜的博客-CSDN博客

这个文章里面编译代码安装了clang,因为clangd是clang的子项目,所以过程类似,clangd的安装过程参考这个:llvm-project/clang-tools-extra/clangd at main · llvm/llvm-project (github.com)

Building and testing clangd

For a minimal setup on building clangd:

  • Clone the LLVM repo to $LLVM_ROOT.
  • Create a build directory, for example at $LLVM_ROOT/build.
  • Inside the build directory run: cmake $LLVM_ROOT/llvm/ -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra".- We suggest building in Release mode as building DEBUG binaries requires considerably more resources. You can check Building LLVM with CMake documentation for more details about cmake flags.- In addition to that using Ninja as a generator rather than default make is preferred. To do that consider passing -G Ninja to cmake invocation.- Finally, you can turn on assertions via -DLLVM_ENABLE_ASSERTS=On.
  • Afterwards you can build clangd with cmake --build $LLVM_ROOT/build --target clangd, similarly run tests by changing target to check-clangd.

4 vscode中安装clangd插件

vscode中的clangd插件跟linux系统中的clangd是前后台程序的关系,vscode中的clangd插件其实是调用ubuntu的clangd程序的功能而已,说直白点,有点类似命令行调用,你看vscode中的clangd插件的配置,其实就是ubuntu中clangd程序的输入参数。

注意,如果你vscode中安装了“Microsoft C/C++”插件,请卸掉或者禁止掉。

参考:Getting started (llvm.org)中vscode部分

The official extension is vscode-clangd and can be installed from within VSCode.

Choose View –> Extensions, then search for “clangd”. (Make sure the Microsoft C/C++ extension is not installed).

After restarting, you should see red underlines underneath errors, and you should get rich code completions including e.g. function parameters.

vscode-clangd has excellent support for all clangd features, including:

  • code completion
  • diagnostics and fixes
  • find declarations, references, and definitions
  • find symbol in file (Ctrl-P @foo) or workspace (Ctrl-P #foo)
  • hover and highlights
  • code actions

Under the hood#

  • Debug logs: when clangd is running, you should see “Clang Language Server” in the dropdown of the Output panel (View -> Output).
  • Command-line flags: these can be passed in the clangd.arguments array in your settings.json. (File -> Preferences -> Settings).
  • Alternate clangd binary: set the clangd.path string in settings.json.

5 vscode中安装“remote - ssh”插件

这个是为了能远程登录到linux服务器或者虚拟机上去,因为你代码都是在linux上编译的,本地是windows,所以只能远程上去,这个插件怎么用的自行搜索吧。

6 编译代码并生成compile_commands.json

clangd能精准的浏览代码,依赖的是compile_commands.json这个文件,这个文件生成有好多方法,我用的方法是使用bear工具生成,安装方法:

sudo apt-get install bear

现在假设要编译一个uboot,具体的使用流程如下:

sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
sudo bear -- make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12

上面的编译命令很简单,这就是普通的交叉编译流程,注意到最后编译的时候前面加了bear,这就是用来跟踪编译过程生成compile_commands.json

编译完成后,你就会看到目录下有这些文件了:

7 远程连接linux浏览代码

现在打开vscode,使用“remote - ssh”连到远程服务器上,打开对应的文件夹,打开vscode的output窗口,“ctrl+shift+p”执行下“clangd:restart language server”,

从第二个图可以看到,clangd运行正常对吧,这个时候选择一个c文件,看看效果呗

I[22:12:14.343] <-- shutdown(75)

I[22:12:14.343] --> reply:shutdown(75) 0 ms

I[22:12:14.348] <-- exit

I[22:12:14.348] LSP finished, exiting with status 0

I[22:12:14.357] clangd version 16.0.0

I[22:12:14.357] Features: linux

I[22:12:14.357] PID: 114268

I[22:12:14.357] Working directory: /home/imx6/work/uboot

I[22:12:14.357] argv[0]: /usr/local/bin/clangd

I[22:12:14.357] argv[1]: -compile-commands-dir=/home/imx6/work/uboot

I[22:12:14.357] argv[2]: --background-index

I[22:12:14.357] argv[3]: --completion-style=detailed

I[22:12:14.357] argv[4]: --header-insertion=never

I[22:12:14.357] argv[5]: -log=info

I[22:12:14.357] Starting LSP over stdin/stdout

I[22:12:14.357] <-- initialize(0)

I[22:12:14.358] --> reply:initialize(0) 0 ms

I[22:12:14.359] <-- initialized

I[22:14:37.129] <-- shutdown(1)

I[22:14:37.129] --> reply:shutdown(1) 0 ms

I[22:14:37.129] <-- exit

I[22:14:37.129] LSP finished, exiting with status 0

I[22:14:37.137] clangd version 16.0.0

I[22:14:37.138] Features: linux

I[22:14:37.138] PID: 115137

I[22:14:37.138] Working directory: /home/imx6/work/uboot

I[22:14:37.138] argv[0]: /usr/local/bin/clangd

I[22:14:37.138] argv[1]: -compile-commands-dir=/home/imx6/work/uboot

I[22:14:37.138] argv[2]: --background-index

I[22:14:37.138] argv[3]: --completion-style=detailed

I[22:14:37.138] argv[4]: --header-insertion=never

I[22:14:37.138] argv[5]: -log=info

I[22:14:37.138] Starting LSP over stdin/stdout

I[22:14:37.138] <-- initialize(0)

I[22:14:37.138] --> reply:initialize(0) 0 ms

I[22:14:37.139] <-- initialized

I[22:14:56.763] <-- textDocument/didOpen

I[22:14:56.763] <-- textDocument/documentSymbol(1)

I[22:14:56.763] <-- textDocument/documentHighlight(2)

I[22:14:56.763] <-- textDocument/semanticTokens/full(3)

I[22:14:56.763] <-- textDocument/codeAction(4)

I[22:14:56.766] Loaded compilation database from /home/imx6/work/uboot/compile_commands.json

I[22:14:56.767] --> window/workDoneProgress/create(0)

I[22:14:56.767] Enqueueing 257 commands for indexing

I[22:14:56.767] ASTWorker building file /home/imx6/work/uboot/common/autoboot.c version 1 with command

[/home/imx6/work/uboot]

/usr/local/bin/cc -c -Wp,-MD,common/.autoboot.o.d -nostdinc -isystem /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/include -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -D__KERNEL__ -D__UBOOT__ -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -Os -fno-stack-protector -fno-delete-null-pointer-checks -g -fstack-usage -Wno-format-nonliteral -Werror=date-time -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -march=armv7-a -DKBUILD_STR(s)=#s -DKBUILD_BASENAME=KBUILD_STR(autoboot) -DKBUILD_MODNAME=KBUILD_STR(autoboot) -o common/autoboot.o -resource-dir=/usr/local/lib/clang/16 -- /home/imx6/work/uboot/common/autoboot.c

I[22:14:56.770] --> textDocument/clangd.fileStatus

E[22:14:56.770] Could not build a preamble for file /home/imx6/work/uboot/common/autoboot.c version 1: CreateTargetInfo() return null

E[22:14:56.770] error: unknown target CPU 'armv7-a'

I[22:14:56.770] --> workspace/semanticTokens/refresh(1)

I[22:14:56.771] <-- reply(0)

I[22:14:56.771] --> $/progress

I[22:14:56.771] --> $/progress

E[22:14:56.771] Failed to prepare a compiler instance: valid target CPU values are: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, rocketlake, icelake-server, tigerlake, sapphirerapids, alderlake, raptorlake, meteorlake, sierraforest, grandridge, graniterapids, emeraldrapids, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, znver4, x86-64, x86-64-v2, x86-64-v3, x86-64-v4

I[22:14:56.771] --> textDocument/publishDiagnostics

I[22:14:56.771] --> reply:textDocument/documentSymbol(1) 7 ms, error: invalid AST

I[22:14:56.771] --> reply:textDocument/documentHighlight(2) 7 ms, error: invalid AST

I[22:14:56.771] --> reply:textDocument/semanticTokens/full(3) 7 ms, error: invalid AST

I[22:14:56.771] --> reply:textDocument/codeAction(4) 7 ms, error: invalid AST

I[22:14:56.771] --> textDocument/clangd.fileStatus

I[22:14:56.771] <-- reply(1)

[Error - 10:14:56 PM] Request textDocument/documentSymbol failed.

[object Object]

[Error - 10:14:56 PM] Request textDocument/documentHighlight failed.

[object Object]

[Error - 10:14:56 PM] Request textDocument/semanticTokens/full failed.

[object Object]

[Error - 10:14:56 PM] Request textDocument/codeAction failed.

[object Object]

解析文件的时候是有问题的,根本跑不起来,但是这不是clangd不行,是参数没配好,这里可以看到不支持这个“armv7-a”架构,那就是架构配置出问题了。

那么现在来配clangd的参数,参考:Configuration (llvm.org)

CompileFlags#

Affects how a source file is parsed.

CompileFlags:                     # Tweak the parse settings
  Add: [-xc++, -Wall]             # treat all files as C++, enable more warnings
  Remove: -W*                     # strip all other warning-related flags
  Compiler: clang++               # Change argv[0] of compile flags to `clang++`

clangd emulates how clang would interpret a file. By default, it behaves roughly as

clang $FILENAME

, but real projects usually require setting the include path (with the

-I

flag), defining preprocessor symbols, configuring warnings etc.

Often, a compilation database specifies these compile commands. clangd searches for

compile_commands.json

in parents of the source file.

This section modifies how the compile command is constructed.

所以,配置流程就是:

1 在代码目录下新建文件“.clangd”

2 在其中假如刚才的架构配置

CompileFlags: # Tweak the parse settings
Add: [--target=arm] # treat all files as C++, enable more warnings

vscode中“ctrl+shift+p”执行下“clangd:restart language server”,再次进入一个c文件,你会发现,可以了。

现在可以愉快的阅读内核代码了。

标签: vscode ide 编辑器

本文转载自: https://blog.csdn.net/oushaojun2/article/details/129877412
版权归原作者 oushaojun2 所有, 如有侵权,请联系我们删除。

“使用vscode+clangd远程精准浏览linux kernel源码(原创)”的评论:

还没有评论