地址:mingw-64 GCC下载,我下载的版本为 8.10 x86_64-posix-seh
,因为后面要编译Opencv的话需要使用posix版。
下载后放到C盘并修改文件名,目录结构如下:
安装完后通过下面的命令验证是否安装成功,如果安装成功会返回版本号。
g++ --version
gdb --version
打开环境变量,在用户变量->Path中添加安装路径,如:C:\MinGW\bin ,确定。
下载CMake,下载最新版即可,我下载的 cmake-3.24.1-windows-x86_64.msi
下载地址https://code.visualstudio.com/Download
安装两个扩展。
另外如果还没有安装过**C/C++**扩展的话,也需要安装一下。
用一个实例来验证VSCode下对CMake工程进行编译和调试。
创建一个空目录,在此目录基础上创建空目录和空文件,如下。
│CMakeLists.txt
│main.cpp
├─bin
├─build
├─include
│ my_print.h
└─src
my_print.cpp
创建完后,VSCode显示。
在 VSCode 中双击打开 my_print.h,复制粘贴。
#include
class Hello
{
public:
void PrintHelloWorld();
};
双击打开 my_print.c,复制粘贴。
#include
#include "my_print.h"
using namespace std;
void Hello::PrintHelloWorld()
{
std::cout << "HelloWorld" << std::endl;
system("pause");
}
双击打开 main.cpp,复制粘贴。
#include
#include "my_print.h"
using namespace std;
int main()
{
Hello hello;
hello.PrintHelloWorld();
}
双击打开 CMakeList.txt,复制粘贴。
# 指定最小CMake版本
cmake_minimum_required(VERSION 3.0)
# 定义项目的名字
project(HelloWorld)
# 设置编译类型(Debug Release MinSizeRel RelWithDebInfo)
set(CMAKE_BUILD_TYPE debug)
# 设置生成的可执行文件路径
# ${PROJECT_SOURCE_DIR}和${CMAKE_SOURCE_DIR}都指工程的顶级目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# include,指定头文件搜索路径
# ${CMAKE_CURRENT_SOURCE_DIR}为CMakeList.txt所在目录
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
# 将 main.cpp 编译生成可执行文件 main
add_executable(
main
main.cpp
src/my_print.cpp
)
为了确保工程和环境配置没有问题,我们先使用 终端 来进行 CMake 编译。在 VSCode 菜单终端下点击新建终端。
在终端中输入命令,生成makefile。
cd build
cmake -G "MinGW Makefiles" ../
../
上一层目录,CMakeLists.txt 所在目录。
-G
指定生成器,在终端输入cmake --help
可以看到列出的可用生成器,我们选择MinGW Makefiles
,也就是上面刚安装的。
上图中也提到了 “Generates a make file for use with mingw32-make.”,所以接下来我们使用mingw32-make来进行编译,生成可执行文件。
mingw32-make
编译成功后会显示[100%] Built target main
,说明bin目录下的可执行文件已经生成,终端输入如下命令执行。
cd ../
./bin/main.exe
成功打印了HelloWorld,按任意键退出。
顺利到这里的话说明编译环境没有问题了。
核心其实就是把终端的这些命令和环境移到 VSCode 来进行编译。
首先,按键Ctrl+Shift+P
,输入 task ,选择配置任务。
然后随便选一个模板,反正还要自己配。
之后,会自动创建 .vscode 目录和 task.json 文件,打开tasks.json文件,清空并粘贴如下内容。
task.json文件主要是配置编译生成任务。
{
"version": "2.0.0",
"options": {"cwd": "${workspaceFolder}/build"},
"tasks": [
// 第一步 生成makefile
{
"type": "shell",
"label": "cmake",
"command": "cmake",
"args": [
"-G \"MinGW Makefiles\"",
".."
]
},
// 第二步 生成exe
{
"label": "make",
"command": "mingw32-make.exe",
},
// 第三步 dependsOn指定执行顺序,这里的label标签 build 后面会在launch.json中使用
{
"label": "build",
"dependsOrder": "sequence", // 按列出的顺序执行任务依赖项
"dependsOn":[
"cmake",
"make"
],
}
]
}
到这里,编译任务就配置好了,现在我们可以像在终端那样,来生成可执行文件。
按键Ctrl+Shift+P
,输入task ,运行生成任务任务。
可以通过后面的小齿轮来修改 运行生成任务 的快捷键,我改成了F4
,这样可以用F4
编译,用F5
运行调试。
F4
运行后
说明可执行文件已经生成了。
属性 | 说明 |
---|---|
label |
用户界面中使用的任务标签。 |
type |
任务的类型。对于自定义任务,可以是shell或process。如果shell指定,则命令被解释为 shell 命令(例如:bash、cmd 或 PowerShell);如果process指定,则命令被解释为要执行的进程。 |
command |
要执行的实际命令。 |
args |
执行命令带的参数。 |
group |
指定任务所属的组,Run Test Task时用到。 |
options |
覆盖cwd(当前工作目录)、env(环境变量)或shell(默认 shell)的默认值。 |
runOptions |
定义任务何时以及如何运行。 |
dependsOn |
定义组合任务,并列出任务依赖项(可以看作是子任务),如本例。 |
dependsOrder |
定义组合任务的执行顺序,默认是并行执行,如果指定了sequence ,那么任务依赖项将按照在dependsOn 中列出的顺序执行。 |
如果要配置task的输出行为,可以通过presentation
来指定。
presentation属性 | 说明 |
---|---|
reveal |
控制是否将集成终端面板置于前面。有效值为:
|
revealProblems |
控制在运行此任务时是否显示问题面板。优先级高于reveal 。默认为never
|
focus |
控制终端是否获取输入焦点。默认为false。 |
echo |
控制执行的命令是否在终端中回显。默认为true。 |
showReuseMessage |
控制是否显示“终端将被任务重用,按任意键关闭它”消息。默认true。 |
panel |
控制终端实例是否在任务运行之间共享。可能的值为:
|
clear |
控制在运行此任务之前是否清除终端。默认为false。 |
close |
控制任务退出时是否关闭任务运行所在的终端。 |
group |
控制是否使用拆分窗格在特定终端组中执行任务。同一组中的任务(由字符串值指定)将使用拆分终端而不是新的终端面板来呈现。 |
这里我们尝试一下showReuseMessage
属性,不显示 终端将被任务重用,按任意键关闭它,tasks.json脚本,清空并粘贴如下。
{
"version": "2.0.0",
"options": {"cwd": "${workspaceFolder}/build"},
"tasks": [
// 第一步 生成makefile
{
"type": "shell",
"label": "cmake",
"command": "cmake",
"presentation":{
"showReuseMessage":false // 不显示 终端将被任务重用,按任意键关闭它
},
"args": [
"-G \"MinGW Makefiles\"",
".."
],
},
// 第二步 生成exe
{
"label": "make",
"command": "mingw32-make.exe",
},
// 第三步 dependsOn指定执行顺序,这里的label标签 build 后面会在launch.json中使用
{
"label": "build",
"dependsOrder": "sequence", // 按列出的顺序执行任务依赖项
"dependsOn":[
"cmake",
"make"
],
}
]
}
再次执行一下编译任务,我定义了快捷键F4
,然后可以看到第一步cmake任务执行完后不再显示 终端将被任务重用,按任意键关闭它。
可以在终端中输入命令来执行exe。
./bin/main.exe
现在我想让 运行 也在VSCode下操作,VSCode下运行的话就需要另外一个launch.json文件,该文件是运行时指定的操作,主要用于调试,现在我还不想调试,只想编译运行。
两种方式,一种利用tasks.json,一种利用launch.json
利用 tasks.json 运行 exe:
在tasks.json文件中加入run任务,如下,粘贴到"tasks"项内build任务的前面面即可。
{
"version": "2.0.0",
"options": {"cwd": "${workspaceFolder}/build"},
"tasks": [
// 第一步 生成makefile
{
"type": "shell",
"label": "cmake",
"command": "cmake",
"presentation": {
"showReuseMessage": false
},
"args": [
"-G \"MinGW Makefiles\"",
".."
]
},
// 第二步 生成exe
{
"label": "make",
"command": "mingw32-make.exe"
},
// 运行exe
{
"label": "run",
"type": "shell",
"command": "${workspaceFolder}//bin//main.exe",
"presentation": {
"showReuseMessage": false
},
// 将任务 run 配置为默认任务
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
},
// 第三步 dependsOn指定执行顺序,这里的label标签 build 后面会在launch.json中使用
{
"label": "build",
"dependsOrder": "sequence",// 按列出的顺序执行任务依赖项
"dependsOn": [
"cmake",
"make"
]
}
]
}
这里通过命令将run配置为默认任务,也可以通过按键Ctrl+Shift+P
来配置:
这样的话再运行任务,就直接运行exe了,也可以把run任务加入到build任务中,自动编译并运行,但是需要把默认任务去掉。按F4
运行任务,运行成功。
操作完后把 run 的默认任务设置注释掉,以免影响后面操作。
{
"version": "2.0.0",
"options": {"cwd": "${workspaceFolder}/build"},
"tasks": [
// 第一步 生成makefile
{
"type": "shell",
"label": "cmake",
"command": "cmake",
"presentation": {
"showReuseMessage": false
},
"args": [
"-G \"MinGW Makefiles\"",
".."
]
},
// 第二步 生成exe
{
"label": "make",
"command": "mingw32-make.exe"
},
// 运行exe
{
"label": "run",
"type": "shell",
"command": "${workspaceFolder}//bin//main.exe",
"presentation": {
"showReuseMessage": false
},
// 将任务 run 配置为默认任务
// "problemMatcher": [],
// "group": {
// "kind": "build",
// "isDefault": true
// }
},
// 第三步 dependsOn指定执行顺序,这里的label标签 build 后面会在launch.json中使用
{
"label": "build",
"dependsOrder": "sequence",// 按列出的顺序执行任务依赖项
"dependsOn": [
"cmake",
"make"
]
}
]
}
利用 launch.json 运行 exe:
现在在.vscode目录下创建launch.json文件,或通过下图来创建该文件(先切到main.cpp界面)
选择 C++(GDB/LLDB)
可以看到 .vscode 目录下已经自动创建了launch.json文件。清空并粘贴。
{
"version": "0.2.0",
"configurations": [
{
"name": "Run",
"type": "cppdbg",
"request": "launch",
"args": [],
"program": "${workspaceFolder}//bin//main.exe",//指定生成的可执行文件的路径
"cwd": "${workspaceFolder}",
}
]
}
这里就是指定了要运行的程序program
,来运行main.exe。
按F5
运行,弹出终端窗口,并输出结果。
OK,到这里的话,其实就很容易理解tasks.json和launch.json的作用了,tasks.json就是制定了一些任务,比如按一定规则编译;launch.json则指定了运行时要做的事情,通常是用来调试。
如果按上面的 3.3 操作了后,现在.vscode目录下是有launch.json文件的,清空,粘贴如下。
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Cmake",
"type": "cppdbg",
"request": "launch",
"args": [],
"program": "${workspaceFolder}//bin//main.exe",//指定生成的可执行文件的路径
"miDebuggerPath": "C://MinGW//bin//gdb.exe",//gdb.exe的路径
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
//执行Task任务,每次调试时都执行一遍 build 任务
//"preLaunchTask": "build"
}
]
}
强制配置属性(面向所有) | 说明 |
---|---|
type |
用于此启动配置的调试器类型。每个安装的调试扩展都引入了一种类型:例如,node用于内置的 Node 调试器,php用于PHP扩展 和 go用于 Go 扩展。 对于C/C++扩展,如果使用 GDB/LLDB 调试器,type为cppdbg;如果使用 Visual Studio Windows 调试器,type为cppvsdbg。只能是这两个,这是C/C++扩展指定的。 |
request |
此启动配置的请求类型。可选项launch 和attach 。这是我对官方的理解: launch 和attach 区别在于是否程序已经再运行,如果已经运行的情况下使用attach ,如浏览器工具开发;通常基于服务器和桌面开发的都是launch 。 |
name |
出现在调试启动配置下拉列表中的易于阅读的名称。 |
可选配置属性(面向所有) | 说明 |
presentation |
presentation 对象中包含order 、group 和hidden 属性,可以在调试配置下拉列表和调试快速选择中对配置和复合工具栏进行排序、分组和隐藏。例如hidden 配置为true ,就会隐藏左侧的调试工具栏。 |
preLaunchTask |
配置在调试会话开始之前启动的任务,需要设置为tasks.json中指定的任务的label (在工作区的.vscode文件夹中)。或者,可以将其设置${defaultBuildTask} 来使用默认构建任务。 |
postDebugTask |
配置在调试会话结束时启动的任务,需要设置为tasks.json中指定的任务的name (在工作区的.vscode文件夹中)。 |
internalConsoleOptions |
调试会话期间调试控制台面板的可见性。 |
debugServer |
调试扩展的作者使用:此属性允许您连接到指定端口,而不是启动调试适配器。 所以我们普通使用者就不管这个了。 |
serverReadyAction |
应该是通过这个配置输出到浏览器中。 |
其它属性(面向大多数调试器) | 说明 |
program |
启动调试器时运行的可执行文件或文件。 |
args |
传递给程序进行调试的参数。 |
env |
环境变量(该值null可用于“取消定义”变量) 定义环境变量时,使用方式 "environment": [{ "name": "config", "value": "Debug" }], ;引用环境变量时,使用方式 ${env:Name} 。 |
envFile |
带有环境变量的 .env 文件的路径。 |
cwd |
设置当前工作路径,用于搜索依赖项和其他文件。 |
port |
连接到运行的进程的端口。 |
stopOnEntry |
程序入口处停止。 |
console |
指定使用哪种控制台,可选internalConsole ,integratedTerminal 和externalTerminal 。 |
GDB/LLDB的属性 | 说明 |
MIMode |
告诉VSCode 调用哪个调试器,可选gdb 和lldb 。 |
miDebuggerPath |
指定调试器的路径,该路径要保证能在系统环境变量中搜索到。 |
miDebuggerArgs |
要传递给调试器的附加参数(例如 gdb)。 |
stopAtConnect |
如果设置为true ,调试器应在连接到目标后停止。如果设置为false ,调试器将在连接后继续。默认值为false 。 |
setupCommands |
为了设置GDB 或LLDB 而执行的 JSON 命令数组。示例:"setupCommands": [ { "text": "target-run", "description": "run target", "ignoreFailures": false }] 。 |
customLaunchSetupCommands |
如果提供,它将用一些其他命令替换用于启动目标的默认命令。例如,这可以是“-target-attach”,以便附加到目标进程。空命令列表将启动命令替换为空,如果调试器被提供启动选项作为命令行选项,这可能很有用。示例:"customLaunchSetupCommands": [ { "text": "target-run", "description": "run target", "ignoreFailures": false }] 。 |
launchCompleteCommand |
在调试器完全设置后执行的命令,以使目标进程运行。允许的值为"exec-run" 、"exec-continue" 、"None" 。默认值为"exec-run" 。 |
symbolLoadInfo |
loadAll :如果为true ,将加载所有库的符号,否则将不加载任何solib symbols。通过ExceptionList修改。默认值为true 。exceptionList :用; 分隔的文件名列表(允许使用通配符)。修改LoadAll 的行为。如果LoadAll 为真,则不要为与列表中任何名称匹配的库加载符号。否则只为匹配的库加载符号。例子:"foo.so;bar.so" 。 |
现在我们把launch.json准备好了,现在在my_print.cpp上随便打个断点。
通过按键F5
,或者下面的按钮来进行调试。
可以通过左侧的调试工具栏和下面的调试控制台来观测调试结果。
----------end----------