B站 xiaobing1016 VScode_C++环境搭建课程学习笔记
MINGW、CMake (需要设置环境变量,bin文件夹)
插件:C/C++ 、 CMake、 CMake Tools
C/C++插件的1.8.4版本可以自动生成调试相关的一些信息。
main.cpp
文件如下:
#include
using namespace std;
void swap(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
int main(int argc, char **argv)
{
int val1 = 10;
int val2 = 20;
cout << "Before swap: " ;
cout << "val1 = " << val1 << " val2 = " << val2 << endl;
swap(val1,val2);
cout << "After swap: " ;
cout << "val1 = " << val1 << " val2 = " << val2 << endl;
return 0;
}
然后使用./a.exe
就可以执行该文件。
只使用g++ 命令生成的可执行文件是不带调试信息的,如果想要得到带有调试信息的可执行文件,需要使用如下命令:
g++ -g main.cpp -o main.exe
使用上述命令得到的文件信息如下:
可以看出,main.exe 文件更大。
选择VScode最左边 Run and Debug,快捷键是 Ctrl + Shift + D
因为是新文件,所以选择creat a launch.json file
添加断点 快捷键是 F9 添加或取消断点
然后 run> start debugging 开始调试 ,或者使用快捷键 F5
F10 单步调试 (step over不会进入具体调用函数内部)
F11 (setp info)会进入函数内部
对于单个文件,使用vscode可以直接调试,这是因为vscode自动生成了调试相关的信息。
可以看到,在文件部分,自动生成了一个main.exe。这个是vscode自动生成的,用于调试的信息。
调试的时候是需要先生成一个可执行文件的。
编译、链接、生成可执行文件的过程是vscode自动完成的。
vscode自动生成了 launh.json 文件,自动完成调试任务,如下:
“program” 一行表示的就是main.exe 的路径,调试的时候,链接到了带有调试信息的可执行文件。
“preLaunchTask” 表示调试之前的任务,这里就是生成main.exe文件。
将之前的例程修改为多文件结构,删除第一次生成的的可执行文件。
然后使用如下g++ -g
编译多个文件,得到可执行文件带有调试信息。
(之前这里是会有一个main.exe文件的,现在没有了)
这个时候 会报错,如下:
错误原因就是没有main.exe文件,调试相关部分配置(launch.json)如下:
可以看到,“program” 所在行信息和之前是一样的,它还是要连接到 main.exe文件,但是此时没有该文件,所以就出错了,也就是说工具自动生成的lunch.json的配置不支持多文件的编译,需要自己修改该文件。
修改如下:
此时就可以正常调试了。
PS:我第一次这样搞得时候,它不会再断点停止,直接执行结束了,找了半天不知道为什么。然后我改回单文件,可以正常调试,又改为多文件,重新跑了一遍,又可以了。。。 ??? 也不知道怎么回事。
CMake是帮助生成 makefile文件的工具,生成了调试需要的可执行文件。
写一个简单的Cmake文件,文件名称为CMakeLists.txt,文件内容如下:
project(MYSWAP) # 指定工程名称
add_executable(my_cmake_swap main.cpp swap.cpp) # 生成 CMake 的 exe
然后 ctrl + shift + P ,输入cmake,点击cmake configure ,选择 gcc ,第一次使用要选择编译器。
选择编译器之后,自动生成一个build文件夹,先知道这个是cmake需要的(外部构建)。
vscode底部还会有一些其他信息,如下:
然后再终端执行以下操作:
进入build文件夹,输入 cmake ..
命令。
然后执行make
命令,这里需要注意的是linux下的make命令在 windows 下是mingw32-make.exe
(Tab自动补全)。
绿色的前两行是编译两个cpp文件。
第三行是连接起来。
最后一行 Built target my_cmake_swap 就是生成的cmake所需要的可执行文件。(add_executable命令执行的结果)
my_cmake_swap 在build文件夹下:
下一步就是调试,需要在launch.json(之前生成的)中进行修改,这个时候是关联到 my_cmake_swap.exe文件,如下:
回到main.cpp,打断点,F5 就可以正常调试。
之前第一次使用的时候,是选择cmake编译器之后,自动生成了build文件夹,后面是保存CMakeLists.txt文件之后,vscode就自动创建了build文件夹。
其实也可以自己创建该文件夹的,具体操作如下:
这个时候,接下来应该执行cmake ..
命令,执行之后如下:
执行出错了,这是因为电脑安装了visual studio,执行该命令的时候,默认使用了微软的MSVC编译器,这个时候需要使用如下命令代替:
cmake -G "MinGW Makefiles" ..
(只需要在第一次使用cmake的时候,使用命令,后面可以正常使用cmake。)
使用上述命令之后,执行过程如下:
后续使用make
命令,也完成了可执行文件的创建。
调试过程其实依赖的是launch.json和tasks.json文件。之前的过程都涉及到了launch.json文件中的修改,主要是对以下两部分的修改:
"program": "${fileDirname}/build/my_cmake_swap.exe",
"preLaunchTask": "C/C++: g++.exe 生成活动文件"
第一行的意思连接到带有调试信息的可执行文件。
第二行的意思其实就是执行一个名叫 C/C++: g++.exe 生成活动文件 (引号中的内容) 的task,生成了调试所需要的可执行文件。
在对多文件进行调试的时候,我们没有使用改命令,而是自己手动使用 g++ -g
生成了带有调试信息的可执行文件,然后将其连接到 "program"部分。
如果自己生成了带有调试信息的可执行文件,那么"preLaunchTask"这一行的内容是可以注释掉(或者叫屏蔽)了。
但是这也带来一个新的问题:
如果第一次调试结束之后,对源代码进行了修改并保存,在没有重新生成可执行文件的情况下再次进入调试环境(修改后直接按F5),这个时候所作出的修改是无效的。也就是说,调试的时候使用的仍然是之前的可执行文件。
那我们把"preLaunchTask"打开,然后一次执行 cmake ..
和 mingw32-make.exe
,然后F5调试的时候,就会出现如下错误:
即,没有执行名称为 “C/C++: g++.exe 生成活动文件” 的 Task。
其实,preLaunchTask是执行一个名字为"C/C++: g++.exe 生成活动文件"的task,该任务在tasks.json 文件中指定。
写一个tasks.json 文件,就可以解决上述问题:
使用如下操作,生成一个tasks.json 文件模板:
Ctrl + Shift + P,输入task,选择 Task: configure Task ,然后选择g++ ,这样就得到一个 tasks.json 文件,内容如下:
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe 生成活动文件",
"command": "D:\\MinGW\\mingw64\\bin\\g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
}
],
"version": "2.0.0"
}
现在可以只关注如下截图部分:
这一部分是涉及到调试的内容,表示的是一个命令行,可以对单个文件生成带有调试信息的可执行文件。但是对多文件就不可以了。
对于多文件而言,生成带有调试信息的可执行文件的命令行如下:
g++ -g main.cpp swap.cpp -o out.exe
这个时候根据命令行,修改上述内容,得到想要的可执行文件,然后就可以调试了,修改如下:
修改结束之后,需要注意launch.json和tasks.json两个文件的对应,如下:
完成上述对两个文件的修改之后,对源代码修改之后,直接按F5进行调试的时候,修改的内容就会起作用,这是因为"preLaunchTask"生成了新的可执行文件,同时"program"也链接到了新的可执行文件。
其实就是按F5执行调试的时候,会执行launch.json文件内容。
tasks.json做的其实就是调试之前的编译工作。对于cmake的相关操作而言,tasks.json的配置配置如下:
{
"version": "2.0.0",
"options": {
"cwd": "${workspaceFolder}/build" # 进入到 build 文件
},
"tasks": [
{
"type": "shell",
"label": "cmake", # 第一个任务,执行 cmake ..
"command": "cmake",
"args": [
".."
],
},
{
"label": "make", # 第二个任务,执行 make(mingw32-make)
"group": {
"kind": "build",
"isDefault": true
},
"command": "mingw32-make",
"args": [
],
},
{
"label": "Build", # 前两个任务合起来,在launch.json中就可以只执行这一个task
"dependsOn":[
"cmake",
"make"
]
}
],
}
再次基础上,修改launch.json中提及的两处内容,一个是preLaunchTask的名称改为build,一个是链接到生成的可执行文件,这样就可以随意调试了。