想要在 VScode 上使用 clang 编译 + LLDB 调试 + clangd 自动补全这一套工具链。
理由是上述工具链是比 gcc+gdb更新的工具链,在各方面都更好,如 clang 比 gcc 报错更友好等。而且 VScode 自带补全很捞,很难用,因此想用 clangd 代替。
可惜 LLDB 在今天(2021年12月)在 Windows 平台上并没有很好的支持,再考虑到很多代码都是 Linux 上跑的,不如直接配一个 Linux 环境,因此使用 WSL(Windows Subsystem for Linux)。
WSL 安装可以自行百度,还是比较简单的。
在这里使用 WSL 的 Ubuntu 系统,本来想用自己移植的 openEuler 的,但是 openEuler 很多软件比较旧,因此用 Ubuntu。
环境:WSL of Ubuntu
操作系统版本:20.04.3 LTS (Focal Fossa)
当前工具链版本最新为 13,但是 20.04 版本的 Ubuntu 最新为 12,默认为 10。
sudo apt install clang clangd llvm liblldb-dev
我用的是最新 12 版本的
使用 update-alternative 来设置 clang 默认使用 12 版本
sudo apt install clang-12 clangd-12 llvm-12 liblldb-12-dev
可选:
如果你想后续均使用 12 版本,可以使用以下命令,默认将 clang 指向 12 版本。
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-12 100
sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-12 100
sudo update-alternatives --install /usr/bin/llvm-dis llvm-dis /usr/bin/llvm-dis-12 100
必装:
选装:
这里安装后需要下载一个包,一般会超时。
uname -m
# x86_64
wget https://github.com/vadimcn/vscode-lldb/releases/download/v1.6.10/codelldb-x86_64-linux.vsix
按下 Ctrl+Shift+P,输入 setting,找到 WSL 的选项
粘贴以下配置:
{
// code runner
"code-runner.runInTerminal": true,
"code-runner.saveFileBeforeRun": true, // run code前保存
"code-runner.clearPreviousOutput": true, // 每次run code前清空属于code runner的终端消息,默认false
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/build",//指定配置文件compelie_commands.json所在目录,这里有三种方法生成
// 在后台自动分析文件(基于complie_commands)
"--background-index",
// 同时开启的任务数量
"-j=12",
// "--folding-ranges"
// 告诉clangd用那个clang进行编译,路径参考which clang++的路径
"--query-driver=/usr/bin/clang++",
// clang-tidy功能
"--clang-tidy",
"--clang-tidy-checks=performance-*,bugprone-*",
// 全局补全(会自动补充头文件)
"--all-scopes-completion",
// 更详细的补全内容
"--completion-style=detailed",
"--function-arg-placeholders",
// 补充头文件的形式
"--header-insertion=iwyu",
// pch优化的位置
"--pch-storage=memory",
],
}
clangd 对每个项目都需要生成一个名为 compile_commands.json 的配置文件,参见官方文档
一共有以下三种方式
在CMakeLists.txt文件中添加
set(CMAKE_EXPORT_COMPILECOMMANDS ON)
运行
mkdir -p build
cd build && cmake ..
可以发现在 build目录下已经生成了 compile_commands.json文件
sudo apt install bear
bear make
点击运行和调试按钮 -> C++(GDB/LLDB) 会生成默认模板,可以修改如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Launch", // 配置名称,将会在启动配置的下拉菜单中显示
"type": "lldb", // 配置类型,不同编程语言不同,该项由CodeLLDB插件提供
"request": "launch", // 可以为launch(启动)或attach(附加)
"program": "${fileDirname}/${fileBasenameNoExtension}.out", // 将要进行调试的程序的路径
"args": [], // 程序调试时传递给程序的命令行参数,一般设为空
"stopAtEntry": false, // 设为true时程序将暂停在程序入口处,相当于在main上打断点
"cwd": "${fileDirname}", // 调试程序时的工作目录,此为工作区文件夹;改成${fileDirname}可变为文件所在目录
"environment": [], // 环境变量
"externalConsole": false, // 使用单独的cmd窗口,与其它IDE一致;为false时使用内置终端
"internalConsoleOptions": "neverOpen", // 如果不设为neverOpen,调试时会跳到“调试控制台”选项卡,你应该不需要对gdb/lldb手动输命令吧?
"MIMode": "lldb", // 指定连接的调试器,可以为gdb或lldb,因为使用llvm工具链,所以使用lldb
"miDebuggerPath": "/usr/bin/lldb", // lldb调试器路径,通过在终端输入 which lldb 命令得到
"setupCommands": [
{ // 模板自带,好像可以更好地显示STL容器的内容
"description": "Enable pretty-printing for lldb",
"text": "-enable-pretty-printing",
"ignoreFailures": false
}
],
"preLaunchTask": "Compile" // 调试前执行的任务,一般为编译程序。与tasks.json的label相对应
}
]
}
按下 Ctrl+Shift+P
粘贴以下作为 tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile", // 任务名称,与launch.json的preLaunchTask相对应
"type": "process", // 可以为process或shell
"command": "clang++", // 要使用的编译器,C语言用clang
"args": [
"${file}",
"-g", // 生成和调试有关的信息, 如果加上该参数,编译后不仅会生成.out可执行文件,还会生成后缀为.out.dSYM的文件夹,如果不加,调试器会忽略你设的断点
"-o", // 指定输出文件名,os X和Linux下不加该参数则默认输出a.out,win下默认a.exe
"${fileDirname}/${fileBasenameNoExtension}.out", // 指定编译生成结果(.out文件和.out.dSYM文件夹)
"-Wall", // 开启额外警告
"-std=c++17", // 这里采用c++17标准(推荐),C语言改成"-std=c11"
], // 编译的命令,其实相当于VSC帮你在终端中输了这一串东西
"group": {
"kind": "build",
"isDefault": true // 不为true时command shift B快捷键就要手动选择了
},
"options": {
"cwd": "${fileDirname}"
},
"presentation": {
"echo": true,
"reveal": "always", // 执行任务时是否跳转到终端面板,可以为always,silent,never。具体参见VSC的文档,即使设为never,手动点进去还是可以看到
"focus": false, // 设为true后可以使执行task时焦点聚集在终端,但对编译C/C++来说,设为true没有意义
"panel": "shared" // 不同的文件的编译信息共享一个终端面板
}
}
]
}
即可使用调试