VSCode笔记01-VSCode+CMake+MinGW配置: VSCode下进行C/C++的编译、运行和调试

VSCode笔记01-VSCode+CMake+MinGW配置: VSCode下进行C/C++的编译、运行和调试

1 安装MinGW-w64

1.1 下载并安装

地址:mingw-64 GCC下载,我下载的版本为 8.10 x86_64-posix-seh,因为后面要编译Opencv的话需要使用posix版。

20220829163205

下载后放到C盘并修改文件名,目录结构如下:

20220830161106

安装完后通过下面的命令验证是否安装成功,如果安装成功会返回版本号。

g++ --version
gdb --version

1.2 配置环境变量

打开环境变量,在用户变量->Path中添加安装路径,如:C:\MinGW\bin ,确定。

2 安装CMake VSCode及扩展

2.1 安装CMake

下载CMake,下载最新版即可,我下载的 cmake-3.24.1-windows-x86_64.msi

2.2 安装VSCode

下载地址https://code.visualstudio.com/Download

2.3 安装扩展 Cmake 和 Cmake Tools

安装两个扩展。

20220827152318

另外如果还没有安装过**C/C++**扩展的话,也需要安装一下。

20220827152336

3 CMake工程验证

用一个实例来验证VSCode下对CMake工程进行编译和调试。

创建一个空目录,在此目录基础上创建空目录和空文件,如下。

│CMakeLists.txt
│main.cpp
├─bin
├─build
├─include
│   my_print.h
└─src
    my_print.cpp

创建完后,VSCode显示。

20220827152417

在 VSCode 中双击打开 my_print.h,复制粘贴。

#include <iostream>

class Hello
{
public:
    void PrintHelloWorld();
};

双击打开 my_print.c,复制粘贴。

#include <iostream>
#include "my_print.h"

using namespace std;
void Hello::PrintHelloWorld()
{
    std::cout << "HelloWorld" << std::endl;
    system("pause");
}

双击打开 main.cpp,复制粘贴。

#include <iostream>
#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
)

3.1 终端下编译 运行

为了确保工程和环境配置没有问题,我们先使用 终端 来进行 CMake 编译。在 VSCode 菜单终端下点击新建终端。
在终端中输入命令,生成makefile。

cd build
cmake -G "MinGW Makefiles" ../

../ 上一层目录,CMakeLists.txt 所在目录。
-G 指定生成器,在终端输入cmake --help可以看到列出的可用生成器,我们选择MinGW Makefiles,也就是上面刚安装的。

20220827152442

上图中也提到了 “Generates a make file for use with mingw32-make.”,所以接下来我们使用mingw32-make来进行编译,生成可执行文件。

mingw32-make

编译成功后会显示[100%] Built target main,说明bin目录下的可执行文件已经生成,终端输入如下命令执行。

cd ../
./bin/main.exe

成功打印了HelloWorld,按任意键退出。

20220827152719

顺利到这里的话说明编译环境没有问题了。

3.2 VSCode下编译

核心其实就是把终端的这些命令和环境移到 VSCode 来进行编译。
首先,按键Ctrl+Shift+P,输入 task ,选择配置任务。

20220827152742

然后随便选一个模板,反正还要自己配。

20220827152854

之后,会自动创建 .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 ,运行生成任务任务。

20220827152935

可以通过后面的小齿轮来修改 运行生成任务 的快捷键,我改成了F4,这样可以用F4编译,用F5运行调试。

F4运行后

20220827152954

说明可执行文件已经生成了。

3.3 tasks.json属性配置说明

属性说明
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控制是否将集成终端面板置于前面。有效值为:
  • always- 面板总是放在前面。这是默认设置。
  • never- 用户必须使用“视图” > “终端”命令 将终端面板显式置于前面。
  • silent- 仅当未扫描输出以查找错误和警告时,才将终端面板置于前面。
revealProblems控制在运行此任务时是否显示问题面板。优先级高于reveal。默认为never
  • always- 执行此任务时始终显示问题面板。
  • onProblem- 仅在发现问题时才显示问题面板。
  • never- 执行此任务时从不显示问题面板。
focus控制终端是否获取输入焦点。默认为false。
echo控制执行的命令是否在终端中回显。默认为true。
showReuseMessage控制是否显示“终端将被任务重用,按任意键关闭它”消息。默认true。
panel控制终端实例是否在任务运行之间共享。可能的值为:
  • shared- 终端是共享的,其他任务运行的输出被添加到同一个终端。
  • dedicated- 终端专用于特定任务。如果再次执行该任务,则重新使用终端。但是,不同任务的输出显示在不同的终端中。
  • new- 该任务的每次执行都使用一个新的干净终端。
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

3.4 VSCode下运行

现在我想让 运行 也在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来配置:

20220827153021

这样的话再运行任务,就直接运行exe了,也可以把run任务加入到build任务中,自动编译并运行,但是需要把默认任务去掉。按F4运行任务,运行成功。

20220827153127

操作完后把 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界面)

20220827153149

选择 C++(GDB/LLDB)

20220827153210

可以看到 .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运行,弹出终端窗口,并输出结果。

20220827153253

OK,到这里的话,其实就很容易理解tasks.json和launch.json的作用了,tasks.json就是制定了一些任务,比如按一定规则编译;launch.json则指定了运行时要做的事情,通常是用来调试。

4 VSCode下调试

4.1 配置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"
        }
    ]
}

4.2 launch的属性配置说明

强制配置属性(面向所有)说明
type用于此启动配置的调试器类型。每个安装的调试扩展都引入了一种类型:例如,node用于内置的 Node 调试器,php用于PHP扩展 和 go用于 Go 扩展。
对于C/C++扩展,如果使用 GDB/LLDB 调试器,type为cppdbg;如果使用 Visual Studio Windows 调试器,type为cppvsdbg。只能是这两个,这是C/C++扩展指定的。
request此启动配置的请求类型。可选项launchattach
这是我对官方的理解:
launchattach区别在于是否程序已经再运行,如果已经运行的情况下使用attach,如浏览器工具开发;通常基于服务器和桌面开发的都是launch
name出现在调试启动配置下拉列表中的易于阅读的名称。
可选配置属性(面向所有)说明
presentationpresentation对象中包含ordergrouphidden属性,可以在调试配置下拉列表和调试快速选择中对配置和复合工具栏进行排序、分组和隐藏。例如
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指定使用哪种控制台,可选internalConsoleintegratedTerminalexternalTerminal
GDB/LLDB的属性说明
MIMode告诉VSCode 调用哪个调试器,可选gdblldb
miDebuggerPath指定调试器的路径,该路径要保证能在系统环境变量中搜索到。
miDebuggerArgs要传递给调试器的附加参数(例如 gdb)。
stopAtConnect如果设置为true,调试器应在连接到目标后停止。如果设置为false,调试器将在连接后继续。默认值为false
setupCommands为了设置GDBLLDB而执行的 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"
symbolLoadInfoloadAll:如果为true,将加载所有库的符号,否则将不加载任何solib symbols。通过ExceptionList修改。默认值为true
exceptionList:用;分隔的文件名列表(允许使用通配符)。修改LoadAll的行为。如果LoadAll为真,则不要为与列表中任何名称匹配的库加载符号。否则只为匹配的库加载符号。例子:"foo.so;bar.so"

4.3 VSCode调试

现在我们把launch.json准备好了,现在在my_print.cpp上随便打个断点。

20220827153320

通过按键F5,或者下面的按钮来进行调试。

20220827153341

可以通过左侧的调试工具栏和下面的调试控制台来观测调试结果。

20220827153408

----------end----------

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值