vscode编译调试C\C++项目(直接使用gcc/g++/gdb 或者使用 CMAKE)(探索)

一直不太会用VSCODE来运行与调试项目(或者说之前一直都是按默认的来, 能用就行, Ubuntu和Win系统一般默认的问题也不大, 实在不行的就直接命令行了), 这次上网上找了配置教程, 作为记录.

主要包含两部分内容:

  1. 直接配置gcc\g++,gdb命令这种
  2. CMAKE方法(目前使用)

最终, 我是形成了一套目前我自己觉得还可以的使用方案, 使用(CMKAE), 但也不完全是, 简称是(乱七八槽)2333, 其实我也就相当于用Vscode来调试了hh.

我用的是centos7系统, 有关Vscode需要的C++插件也不再提.(PS: 记得安装gcc/g++/gdb)(我之前安装的时候忘记安装gbd了(因为一直也不咋调试), 结果需要调试的时候, 看错误看了半天才知道自己是没安装gdb)

默认的配置文件配置方法(不全, 仅仅是能用)

都说在.vscode文件夹下会有三个文件(都有默认生成的版本):

c_cpp_properties.json launch.json tasks.json

c_cpp_properties.json

c_cpp_properties.json:假如我们只是想能用的话, 这个文件可以没有.(对这个文件不需要过多在意)

只要我们安装好了gcc/g++/gdb并且有全局变量的话, C++插件一般是可以自动检测的(或者运行前给你选择你要使用的编译器版本).

tasks.json

这个文件也可以默认生成, 其主要作用就是配置编译的过程, 生成可执行文件的. 默认生成的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ 生成活动文件",
"command": "/opt/rh/devtoolset-9/root/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
},
]
}

这里主要注意两行:

1
2
3
4
5
6
7
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}", // 还有这一行 是 源文件的名字
"-o",
"${fileDirname}/${fileBasenameNoExtension}" // 这一行用来控制生成的可执行文件的位置和名字
],

举个例子, 假如我们要编译main.cpp, main.cpp中需要用到swap.cpp的源文件, 生成的可执行文件名字是main, 可以直接在命令行中输入以下命令: g++ -g .\main.cpp .\swap.cpp -o main

那么在多文件编译运行的情况下, 这个默认的json是有问题的, 需要你自己添加. 有个解决方法如下:

1
2
3
4
5
6
7
8
"args": [
"-fdiagnostics-color=always",
"-g",
// "${file}", // 还有这一行 是 源文件的名字
"${fildDirname}/*.cpp" // 包含这一目录下的所有cpp文件
"-o",
"${fileDirname}/${fileBasenameNoExtension}" // 这一行用来控制生成的可执行文件的位置和名字
],

但这样也并不是完全没问题, 比如:

在这个文件夹下我有俩main(), 一个client一个server, 需要特别安排文件排放

C++模板的问题, 参考连接, 但我也没遇到过.

反正, 多文件编译运行需要这样的修改. 不算麻烦, 但也不是很方便.

launch.cpp

我这里认为这个文件就是主要用来调试的, 其实也可以包含编译的过程, 但我就按它是来调试来理解. 默认生成代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"name": "C/C++: g++ 生成和调试活动文件(but CMAKE)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/build/bin/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为 Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "build",
"miDebuggerPath": "gdb"
},

这个文件, 我目前认为比较主要的几句话是下面这几句:

1
2
3
4
5
6
// 这一行, 就是写了你的可执行文件的位置, 就是上一个tasks.json中生成的可执行文件的位置
"program": "${workspaceRoot}/build/bin/${fileBasenameNoExtension}",
// 可执行文件运行时需要从命令行接受的参数
"args": [],
// 在这个调试运行之前, 要不要执行你之前设置的编译过程 tasks.json 中的, 如果需要: 就把名字放在这里, 其实就是包含了编译的过程.
"preLaunchTask": "build",

如果希望编译和运行的过程合起来, 就需要加preLaunchTask.

但假如编译和运行(调试)时分开的话, 其实不用这句也行.

CMAKE(MAKEFILE)

CMAKE其实没有简单多少, 但是CMAKE对于管理大型项目总归是简单些的

(其实我现在也没啥大型项目, 但总要学一学CMAKE的)

首先, 我讲一讲我的工作流: 编译和运行(调试)分开. 目前一般都是Cmake编译, 然后命令行运行了. 除非说我需要调试才用vscode, 命令行调试emmmm

所以有了CMAKEVSCODE插件之后, 我一般直接通过这个齿轮符号直接编译了, 并生成可执行文件.

然后直接修改launch.json中的argv 和 program即可, preLaunchTask 可直接注释掉.

编译和运行(调试)一起进行的方法(tasks.json中添加如下几行):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// tasks.json
// 参考链接: https://zhuanlan.zhihu.com/p/618043511
{
"label": "cmake",
"type": "shell",
"command": "cmake",
"args": [
".."
],
"options": {
"cwd": "${workspaceRoot}/build"
}
},
{
"label": "make",
"type": "shell",
"command": "make",
"args": [],
"options": {
"cwd": "${workspaceRoot}/build"
}
},
{
"label": "build",
"dependsOn": [
"cmake",
"make"
]
}
//launch
{"preLaunchTask": "build",}

这其实是我在知乎的一篇解决方案[https://zhuanlan.zhihu.com/p/618043511]中看到的, 其实这个也有自动生成的代码, 但一来那个我看不懂, 二来那个我运行有问题.

这样写的缺陷: 自己先在目录下新建build目录

其实也可以通过自己写一个sh的文件, 并在tasks.json中运行来实现.(各有各的方法.)

为啥选择CMAKE

没别的, Cmake写着也不简单(好像可以直接生成, 不太清楚), 但是想想总要多写的, 写的多就会写了.