背景: 在开发大型工程例如Android或Linux时若我们使用vscode搭配官方的C/C++插件使用发现,经常很多代码都无法跳转,代码补全功能几乎是废的,通过网友以及同事身边了解之后发现vscode+clangd可以实现代码任意跳转补全等功能,因此本文通过讲解如何配置clangd相关环境实现高效开发。

一、准备工作

首先自然就是卸载vscode官方提供的C/C++因为功能和clangd会有冲突,建议直接删除(禁用)
准备所需插件:主要有两个clangd以及SSH(按需求安装)
1.clangd
在这里插入图片描述
2.SSH(使用远程服务器配置)
在这里插入图片描述

二、本地vscode链接到远程服务器(本地配置过可跳过)

参考:vscode连接SSH远程服务器(详细版)

三、clangd配置

3.1下载clangd

安装好clangd插件之后只是一个套壳现在代码是不能跳转的,需要通过clangd language的支持来完成跳转,clangd language的下载方式有两种方法
方式一:
下载好之后任意打开一个C/CPP文件,vscode下方会出现弹窗直接install即可(若网络原因或其他原因这里一直下载不出来请参考方式二)
在这里插入图片描述
方式二:
从GitHub上下载clangd-language
在这里插入图片描述
选择最新的版本即可,开发环境是linux选择linux即可,博主这里选用的就是linux,其他系统同理。
将下载好的clangd解压到任意一个path下,如下

cd /home/zly/tools/
unzip clangd_16.0.2.zip

在vscode上按住ctrl+,进入配置选项,如下在clangd中填写我们下载好的language的path。
在这里插入图片描述

3.2配置clangd(重点)

clangd准备工作在上述,虽然已经基本完成,但是如果打开工程代码还是会发现代码还是不能够任意跳转,这是因为clangd查询不到对应的工程头文件,因此需要生成compile_commands.json,使用compile_commands.json文件来生成索引文件,这样当我们点击某个函数时可以飞快跳转到它定义的地方。

compile_commands.json文件中记录的是每个文件的编译选项,样式如下:

    {
        "arguments": [
            "/home/zly/work/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc",
            "-c",
            "-Wp,-MD,cmd/.test.o.d",
            "-nostdinc",
            "-isystem",
            "/home/zly/work/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/6.3.1/include",
            "-Iinclude",
            "-I./arch/arm/include",
            "-include",
            "./include/linux/kconfig.h",
            "-D__KERNEL__",
            "-D__UBOOT__",
            "-Wall",
            "-Wstrict-prototypes",
            "-Wno-format-security",
            "-fno-builtin",
            "-ffreestanding",
            "-fshort-wchar",
            "-Werror",
            "-Os",
            "-fno-stack-protector",
            "-fno-delete-null-pointer-checks",
            "-g",
            "-fstack-usage",
            "-Wno-format-nonliteral",
            "-Werror=date-time",
            "-D__ARM__",
            "-Wa,-mimplicit-it=always",
            "-mthumb",
            "-mthumb-interwork",
            "-mabi=aapcs-linux",
            "-mword-relocations",
            "-fno-pic",
            "-mno-unaligned-access",
            "-mabi=aapcs-linux",
            "-funwind-tables",
            "-ffunction-sections",
            "-fdata-sections",
            "-fno-common",
            "-ffixed-r9",
            "-msoft-float",
            "-pipe",
            "-march=armv7-a",
            "-D__LINUX_ARM_ARCH__=7",
            "-I./arch/arm/mach-rockchip/include",
            "-DKBUILD_STR(s)=#s",
            "-DKBUILD_BASENAME=KBUILD_STR(test)",
            "-DKBUILD_MODNAME=KBUILD_STR(test)",
            "-o",
            "cmd/test.o",
            "cmd/test.c"
        ],
        "directory": "/home/zly/work/u-boot",
        "file": "cmd/test.c"
    },

生成compile_commands.json

compile_commands.json(也就是compilationdatabase,具体详细规范可以参考clangd说明)给clangd传递这些参数。
接下来通过kernel以及Android工程来分别生成compile_commands.json,
一、kernel中生成compile_commands.json

方法a:(注意!进行以下操作前需要确保工程提前被编译过
kernel中自带了scripts/clang-tools/gen_compile_commands.py可以直接生成(低内核版本没有该脚本,可以从网上下载一个)

  • 编译一遍kernel
zly@zly-machine:~/work$ ./build.sh kernel
  • 通过find -name "*.cmd"确认是否生成
........................................
./kernel/arch/arm/lib/.memchr.o.cmd
./kernel/arch/arm/lib/.lib1funcs.o.cmd
./kernel/arch/arm/lib/.call_with_stack.o.cmd
........................................
  • 执行gen_compile_commands.py在当前目录下生成compile_commands.json
zly@zly-machine:~/work/kernel$ python3 ./scripts/clang-tools/gen_compile_commands.py

  • cp compile_commands.json到kernel目录下

方法b:(注意工程要没有编译过!若编译过make clean一下)
通过使用bear来生成:Bear 是一个用于生成编译器的工具,它可以将编译器前端的源代码转换成抽象语法树(AST)并输出到一个JSON文件中。

  • 安装bear
zly@zly-machine:~$ sudo apt-get install bear
  • 使用bear命令来生成compile_commands.json
    用法如下:
bear make [其他make本身的参数]

它会记录make过程编译文件时用到的命令。
所以我们编译内核的目的是生成compile_commands.json,执行如下命令:

zly@zly-machine:~/work$ bear ./build.sh kernel

同样会生成compile_commands.json,将该json,cp到我们对应的工程下即可。

二、Android中生成compile_commands.json
安卓和kernel其实是同理的,但是安卓工程更加庞大,在安卓7之后基本工程直接使用ninja来进行编译构建的,因此我们可以直接通过ninjia快速构建同步生成对应的compile_commands.json.
ninja提供了一个工具(-t commands)可以生成特点目标的编译命令:

ninja -f combined-hal.ninja -t commands MODULES-IN-vendor-rockchip > commands.txt

使用gen_compdb:
gen_compdb: -c -i commands.txt -o compile_commands.json
cp compile_commands.json ./work

restart clangd server

综上将compile_commands.json生成好并且放到相关工程中即可,正式使用了,使用前,在vscode重启下clangd:ctrl+shift+p
在这里插入图片描述
之后就可以实现代码的任意跳转了~,clangd功能十分强大!不单单只有代码跳转那么简单,还可以为代码提供补全、错误提示、跳转、导航等功能。

四、clangd简介

clangd是一个C/C++语言的基于LSP的语言服务实现,可以为代码提供补全、错误提示、跳转、导航等功能。

1.代码补全、跳转、导航、查看引用、查看实现

代码补全:
在这里插入图片描述
转到定义、引用、实现:
在这里插入图片描述
快速定位:(ctrl+shift+o、ctrl+T)
在这里插入图片描述

2.错误提示、静态检查

错误提示:
在这里插入图片描述
静态检查:快速修复
在这里插入图片描述

3.格式化代码

对整个文件(Shitft+Alt+F),选中区域格式化(Ctrl+K Ctrl+F)
在这里插入图片描述

4.重构

5.悬浮提示

在这里插入图片描述
按住ctrl+左键即可跳跃到对应函数

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐