Back

/ 9 min read

优雅的使用VSCode进行C++开发调试

标准C++开发配置

依赖安装

此处的依赖安装命令,仅适用于ArchLinux系统,其他系统请按照包管理器中的软件包进行安装,此处先将所有依赖列出来:

  • VSCode代码编辑器,以及以下插件:
    • clangd,使用clangd作为代码补全、语法检查工具。
    • clang-format,使用clang-format作为代码格式化工具。
    • C++,安装它主要是为了使用问题match。
    • CMakeCMake Tools,用于CMake项目的支持。
    • CodeLLDB,用于调试。
  • CMakeNinja,用于编译。(一般系统自带)

VSCode安装

Terminal window
sudo pacman -S code

创建一个工作区

VSCode中打开一个文件夹,这个文件夹就是我们的工作区,我们需要在这个文件夹下面编写一些测试用的代码。

Terminal window
mkdir -p ~/workspace/cpp
code ~/workspace/cpp

VSCode编辑器设置

  • 安装插件clangdC++CMakeCMake ToolsCodeLLDB
  1. 关闭C++intelliSenseEngine功能,因为我们要使用clangd作为补全工具。

ctrl+shift+p打开命令面板,输入json, 找到首选项:打开用户设置。,添加如下配置:

{
"C_Cpp.intelliSenseEngine": "disabled"
}
  1. 配置clangd

在刚才的json配置文件中添加如下配置:

"clangd.fallbackFlags": ["--std=c++23"],
"clangd.arguments": [
"-j=6",
"--background-index",
"--completion-style=detailed",
],
  • clangd.fallbackFlags: 用于指定clangd的编译标准。
  • clangd.arguments: 用于指定clangd的参数。
    • -j=6: 指定clangd的线程数。
    • --background-index: 后台索引,用于加速补全。
    • --completion-style=detailed: 补全风格设置为更为详细

然后,我们新建一个main.cpp文件,编写一个简单的C++代码,用来检查我们代码提示是否正确配置。

#include <iostream>
int main(){
std::cout << "Hello World!" << std::endl;
return 0;
}

CMake编译与调试

我们需要使用CMake Tools给的快速创建CMake项目的功能,这样我们就可以使用CMake来管理我们的项目。 使用ctrl+shift+p打开命令面板,输入cmake, 选择CMake: Quick Start,创建一个可执行的CMake项目。并根据提示创建一个CMakePresets.json预设文件。 如果一起正常,我们的项目目录结构应该是这样的:

Terminal window
.
├── CMakeLists.txt
├── CMakePresets.json
├── main.cpp

然后我们需要修改CMakeLists.txt文件,使其能够生成一个可执行项目。

cmake_minimum_required(VERSION 3.5.0)
project(test_cpp VERSION 0.1.0 LANGUAGES C CXX)
SET(CMAKE_CXX_STANDARD 23)
add_executable(test_cpp main.cpp) # 填写你的源文件

命令行编译配置

修改CMakePresets.json文件,使其能够编译我们的代码。注意你的name字段。

{
"version": 8,
"configurePresets": [
{
"name": "GCC",
"displayName": "GCC预设",
"description": "使用编译器: C = /usr/bin/gcc, CXX = /usr/bin/g++",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
"CMAKE_C_COMPILER": "/usr/bin/gcc",
"CMAKE_CXX_COMPILER": "/usr/bin/g++",
"CMAKE_BUILD_TYPE": "Debug"
}
}
],
// 增加的配置
"buildPresets": [
{
"name": "build-g++",
"configurePreset": "GCC",
"jobs": 4
}
]
}

如果配置一切正常,我们通过命令行来进行一个检查。

Terminal window
cmake --preset GCC # 生成项目
cmake --build --preset build-g++ # 编译项目

如果执行正常,我们在out/build/GCC目录下会生成一个可执行文件。 最后我们删除out目录,因为后面我们需要验证使用VSCodeCMake Tools插件来编译我们的项目。

使用VSCode编译

配置完CMake之后,我们可以使用VSCodeCMake Tools插件来编译我们的项目。但是我们需要修改一下VSCodetasks配置。

使用命令面板输入tasks,找到任务:打开用户任务。增加两个tasks项:

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "cmake",
"label": "CMake: 配置",
"command": "configure",
"preset": "${command:cmake.activeConfigurePresetName}",
"group": "build",
"problemMatcher": [
"$gcc"
],
"detail": "CMake 生成配置项"
},
{
"type": "cmake",
"label": "CMake: 构建",
"command": "build",
"targets": [
"all"
],
"preset": "${command:cmake.activeBuildPresetName}",
"group": "build",
"problemMatcher": [
"$gcc" // 这里的gcc就是为什么我们需要安装C++插件的原因
],
"detail": "CMake 构建任务"
}
]
}

配置完成后,我们使用快捷键ctrl+shift+b,选择CMake: 配置,先生成项目,之后再次使用ctrl+shift+b,选择CMake: 构建,编译项目。如果一切正常,就会和命令行一样得到可执行文件。

调试配置

使用ctrl+shift+p打开命令面板,输入json, 找到首选项:打开用户设置。,增加一个configurations项:

{
"launch": {
"configurations": [
// 新增的配置
{
"name": "C++ (gdb) Launch",
"type": "lldb",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [],
"cwd": "${workspaceFolder}",
},
// ....... 你的其他设置
]
},
}

这个配置主要是用来配置VSCode的调试功能,有了这个我们就可以使用F5进行调试。打上断点后F5

番外NDK编译

想要让一个项目可以输出Androidso文件,我们需要使用NDK来编译我们的项目。如果按照上面的步骤,我们只需要在CMakePresets.json文件中添加一个预设。

{
"version": 8,
"configurePresets": [
{
"name": "GCC",
"displayName": "GCC预设",
"description": "使用编译器: C = /usr/bin/gcc, CXX = /usr/bin/g++",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
"CMAKE_C_COMPILER": "/usr/bin/gcc",
"CMAKE_CXX_COMPILER": "/usr/bin/g++",
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "android-ndk",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "/home/asahi/Android/Sdk/ndk/28.0.12433566/build/cmake/android.toolchain.cmake",
"ANDROID_ABI": "arm64-v8a",
"ANDROID_PLATFORM": "android-21",
"ANDROID_STL": "c++_static"
}
}
],
"buildPresets": [
{
"name": "build-g++",
"configurePreset": "GCC",
"jobs": 4
},
{
"name": "build-android",
"configurePreset": "android-ndk",
"jobs": 4
}
]
}

使用VSCodeCMake插件,在左侧面板中可以切换预设。 切换预设后,我们可以使用ctrl+shift+b来编译我们的项目,如果一切正常,我们的项目就会生成so文件。

远程调试

  1. Android设备上安装lldb-server,并且开启lldb-server服务。
Terminal window
emulator -avd Pixel_2_API_30 -writable-system -selinux permissive # 启动模拟器 并且开启adb root权限和关闭selinux
adb root # 开启adb root权限
adb push lldb-server /data/local/tmp/ # 将lldb-server推送到模拟器
adb shell chmod +x /data/local/tmp/lldb-server # 添加执行权限
  1. 启动lldb-server服务
Terminal window
adb shell /data/local/tmp/lldb-server platform --listen localhost:12305 --server # 这个命令也可以写到vscode的配置文件中
Terminal window
# 转发端口
adb forward tcp:12305 tcp:12305
  1. 配置VSCode
{
"launch": {
"configurations": [
{
"name": "C++ (gdb) Launch",
"type": "lldb",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [],
"cwd": "${workspaceFolder}"
},
// 新增
{
"name": "LLDB 远程调试Android (Launch)",
"type": "lldb",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"initCommands": [
"platform select remote-android", // For example: 'remote-linux', 'remote-macosx', 'remote-android', etc.
"platform connect connect://localhost:12305", // platform connect connect://localhost:12305
"settings set target.inherit-env false" // See note below.
],
},
]
},
}

拓展-自动启动lldb-server

  1. 编写启动lldb-server的脚本

文件名: start-lldb-server.sh

#!/bin/sh
# 启动 lldb-server 并将其放到后台,同时记录它的 PID
nohup /data/local/tmp/lldb-server platform --listen localhost:12305 --server > /dev/null 2>&1 &
# 将 lldb-server 的进程 ID 保存到 /data/local/tmp/lldb-server.pid 文件中
echo $! > /data/local/tmp/lldb-server.pid
echo "lldb-server started with PID $(cat /data/local/tmp/lldb-server.pid)"
  1. 编写停止lldb-server的脚本

文件名: stop-lldb-server.sh

#!/bin/sh
# 检查 pid 文件是否存在,并根据 pid 终止 lldb-server
if [ -f /data/local/tmp/lldb-server.pid ]; then
# 读取 PID 并终止进程
PID=$(cat /data/local/tmp/lldb-server.pid)
kill $PID
echo "lldb-server with PID $PID stopped"
# 删除 PID 文件
rm /data/local/tmp/lldb-server.pid
else
echo "No lldb-server PID file found, server may not be running."
fi
  1. 将脚本发送到模拟器
Terminal window
adb root # 默认以root启动
adb push start-lldb-server.sh /data/local/tmp/
adb push stop-lldb-server.sh /data/local/tmp/
  1. 编写VSCodetasks.json

增加两个任务:

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
// .... 其他任务
{
"label": "start-remote-lldb-server",
"type": "shell",
"command": "adb",
"args": [
"shell",
"/data/local/tmp/start-lldb-server.sh",
"&"
],
"group": "none",
"hide": true,
"problemMatcher": []
},
{
"label": "stop-remote-lldb-server",
"type": "shell",
"command": "adb",
"args": [
"shell",
"/data/local/tmp/stop-lldb-server.sh",
],
"group": "none",
"hide": true,
"problemMatcher": []
}
]
}
  1. 修改VSCodelaunch
{
"launch": {
"configurations": [
// .... 其他配置
{
"name": "LLDB 远程调试Android (Launch)",
"type": "lldb",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
// 我想在这里打开一个远程调试的lldb-server
"preLaunchTask": "start-remote-lldb-server",
"postDebugTask": "stop-remote-lldb-server",
"initCommands": [
"platform select remote-android", // For example: 'remote-linux', 'remote-macosx', 'remote-android', etc.
"platform connect connect://localhost:12305", // platform connect connect://localhost:12305
"settings set target.inherit-env false" // See note below.
],
},
]
},
}

这样,我们想要远程调试的时候,只需要:

  1. 启动模拟器。
  2. F5断点调试。 就可以了,非常方便。