万变不离其宗:利用VSCode进行花式编译与调试
今天终于有心思来写这篇VSCode相关的博客。上次在这篇博客VSCode的launch.json和task.json解读中谈到了VSCode的launch.json和task.json两个文件的各字段含义,事实上,有了这两个文件,我们就可以针对任意项目,进行VSCode的花式编译与调试了。本文以一个FUSE(File System in User Space)项目为例进行对上篇博客进行实例介绍,说明对任意结构的项目都可以以相同或类似的思路进行VSCode的配置,从而解放双手,一键编译。此外,为了进一步参透launch.json和task.json文件原理,本文将二者的操作以脚本的方式翻译出来,以期更利于读者理解。
1. 样例项目结构、编译与运行
项目结构如下,由于该项目暂时闭源,因此某些文件用...
代替。
.
├──.vscode
│ ├── launch.json
│ └── tasks.json
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── compile_commands.json
│ ├── program (二进制文件名)
│ └── Makefile
├── CMake
│ ├── FindFUSE.cmake
│ ├── FindGlib.cmake
│ └── LibFindMacros.cmake
├── CMakeLists.txt
├── ... (C文件)
├── scripts
│ ├── auto_passwd.sh
│ ├── clean.sh
│ ├── gdb.sh
│ ├── quick-start.sh
│ └── setup.sh
└── Makefile
编译该项目需要多个步骤:
- 运行清理脚本:
./scripts/clean.sh
- 运行配置脚本:
./scripts/setup.sh
- 运行CMake编译:
cd build && cmake ../ && make
运行该项目的命令为(/dev/xx
为设备地址,/mnt/yy
为挂载地址,如果没有接触过文件系统,这里不用尝试理解):
./build/program -f -d -s --device=/dev/xx /mnt/yy
2. VSCode配置一键编译
首先,回顾一下VSCode的launch.json和task.json解读:
launch.json
文件是VSCode启动程序的配置文件,着重关注以下几个参数:
- program:代表要运行的二进制文件(也就是你的C代码编译出来的程序)所在路径
- miDebuggerPath:代表调试器(GDB)所在路径
- preLaunchTask:在运行program前要做的前置任务,比如编译,task.json就是用于定义前置任务
tasks.json
是前置任务的配置文件,有几个重要参数:
- label:指定前置任务(比如:“C/C++: gcc 生成活动文件”)名称
- command:任务执行命令,一般来说执行编译命令:gcc
- args:用于command后面的参数,比如:-g(debug选项),-f等
2.1 launch.json配置
VSCode根据launch.json
配置进行任务的启动,我们可以简单把launch.json
配置文件理解为封装如下操作:
find label preLaunchTask in tasks.json # 在task.json定义中找到label为preLaunchTask的前置任务
bash preLaunchTask # 执行前置任务
cd cwd # 切换到用户定义的当前目录
program args # 执行命令
样例项目的launch.json
配置如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/program", //二进制路径
"args": [
"--device=/dev/xx",
"-f",
"-d",
"-s",
"/mnt/yy"
], //启动参数
"stopAtEntry": false,
"cwd": "${workspaceFolder}", //当前目录位置
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Formmater",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "Compile", // 前置任务(运行前的一系列准备操作)
"miDebuggerPath": "gdb",
}
]
}
翻译过来,该配置文件的含义是:
find label Compile in tasks.json # 在tasks.json中找到label为Compile的前置任务
bash Compile # 执行Compile前置任务 (2.2节讲到)
cd ${workspaceFolder} # 切换到用户定义的当前目录
${workspaceFolder}/build/program \
--device=/dev/xx \
-f \
-d \
-s \
/mnt/yy # 展开并执行命令 program args
2.2 task.json配置
VSCode在根据launch.json
启动之前会根据task.json
的定义执行前置任务,我们可以简单把task.json
配置文件理解为封装如下操作:
cd options.cwd # 切换到用户定义的目录
command args # 执行前置任务命令
样例项目的tasks.json
配置如下:
{
"tasks": [
{
"type": "cppbuild",
"label": "Compile",
"command": "./scripts/clean.sh && ./scripts/setup.sh && cd build && cmake ../ && make", //单行书写所有命令
"args": [],
"options": {
"cwd": "${workspaceFolder}" //当前目录. ${workspaceFolder}代表当前VSCode打开的根目录
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "Compiler generation task"
}
],
"version": "2.0.0"
}
翻译过来,该配置文件的含义是:
cd ${workspaceFolder} # 切换到用户定义的当前目录
./scripts/clean.sh && ./scripts/setup.sh && cd build && cmake ../ && make
# 展开并执行命令 command args
2.3 整合起来
将launch.json
与tasks.json
整合起来,编译FUSE样例项目可理解为:
find label Compile in task.json # 在task.json中找到label为Compile的前置任务
# 执行前置任务
cd ${workspaceFolder} # 切换到用户定义的当前目录
./scripts/clean.sh && ./scripts/setup.sh && cd build && cmake ../ && make
# 执行运行命令
cd ${workspaceFolder} # 切换到用户定义的当前目录
${workspaceFolder}/build/program \
--device=/dev/xx \
-f \
-d \
-s \
/mnt/yy # 展开并执行命令 program args
3. Sudo权限问题
事实上,在某些启动脚本中可能存在sudo
权限,如果VSCode没有root
权限,那就会报错(可以自行尝试)。那要如何操作呢?现有的方法参考如下:
- https://stackoverflow.com/questions/40033311/how-to-debug-programs-with-sudo-in-vscode
- https://blog.csdn.net/u010947832/article/details/119052453
博主用了一种更为简单的方法,单独写一个auto_passwd.sh
文件:
#!/usr/bin/bash
echo "你的密码" | sudo -S echo ""
然后将该文件导入到每个需要sudo
的脚本内,例如,setup.sh
需要sudo权限:
# 导入自动密码
source auto_passwd.sh
# setup.sh内容
...
sudo mount /dev/xx /mnt/zz
4. 总结
一旦理解了VSCode的launch.json
和tasks.json
在干嘛,配置任何项目都会变得容易起来,万变不离其宗,VSCode只是帮我们在脚本之上包装了一层。
Ok,今天的内容就到这里,🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫