现已发布!阅读 10 月份的新功能和修复。

使用 MinGW 的 GCC

在本教程中,您将配置 Visual Studio Code 以使用来自 mingw-w64 的 GCC C++ 编译器 (g++) 和 GDB 调试器来创建在 Windows 上运行的程序。配置完 VS Code 后,您将编译、运行和调试 Hello World 程序。

本教程不会教您有关 GCC、GDB、minGW-w64 或 C++ 语言的知识。对于这些主题,网上有许多不错的资源。

如果您遇到任何问题,请随时在 VS Code 文档仓库 中为此教程提交问题。

先决条件

要成功完成本教程,您必须执行以下步骤

  1. 安装 Visual Studio Code.

  2. 安装 适用于 VS Code 的 C/C++ 扩展。您可以在扩展视图 (⇧⌘X (Windows、Linux Ctrl+Shift+X)) 中搜索“C++”来安装 C/C++ 扩展。

    C/C++ extension

安装 MinGW-w64 工具链

通过 MSYS2 获取最新版本的 MinGW-w64,它提供了 GCC、MinGW-w64 以及其他有用的 C++ 工具和库的最新原生版本。这将为您提供编译代码、调试代码以及配置代码以与 IntelliSense 协同工作的必要工具。

要安装 MinGW-w64 工具链,请观看此视频或按照以下步骤操作

  1. 您可以从 MSYS2 页面下载最新的安装程序,或使用此 安装程序的直接链接.

  2. 运行安装程序并按照安装向导的步骤操作。请注意,MSYS2 需要 64 位 Windows 8.1 或更高版本。

  3. 在向导中,选择您想要的安装文件夹。记录此目录以备后用。在大多数情况下,推荐的目录是可以接受的。当您进入设置开始菜单快捷方式步骤时,也是如此。完成后,确保选中立即运行 MSYS2 框,然后选择完成。这将为您打开一个 MSYS2 终端窗口。

  4. 在此终端中,通过运行以下命令来安装 MinGW-w64 工具链

    pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
    
  5. 通过按 Enter 键,在 toolchain 组中接受默认的软件包数量。

    MYSS2 Installer

  6. 当系统提示您是否继续安装时,输入 Y

  7. 通过以下步骤将 MinGW-w64 bin 文件夹的路径添加到 Windows PATH 环境变量中

    1. 在 Windows 搜索栏中,输入设置以打开 Windows 设置。
    2. 搜索编辑您的账户的环境变量
    3. 在您的用户变量中,选择 Path 变量,然后选择编辑
    4. 选择新建,并将安装过程中记录的 MinGW-w64 目标文件夹添加到列表中。如果您使用了上述默认设置,则此路径为:C:\msys64\ucrt64\bin
    5. 选择确定,然后在环境变量窗口中再次选择确定以更新 PATH 环境变量。您必须重新打开任何控制台窗口,才能使更新的 PATH 环境变量可用。

检查您的 MinGW 安装

要检查您的 MinGW-w64 工具是否已正确安装并可用,请打开一个新的命令提示符,然后键入

gcc --version
g++ --version
gdb --version

您应该看到说明您安装了哪些版本的 GCC、g++ 和 GDB 的输出。如果不是这种情况

  1. 确保您的 PATH 变量条目与安装工具链的 MinGW-w64 二进制文件位置匹配。如果编译器在该 PATH 条目中不存在,请确保您遵循了前面的说明。
  2. 如果 gcc 的输出正确,但 gdb 不正确,则您需要从 MinGW-w64 工具集中安装缺少的软件包。
    • 如果您在编译时收到“miDebuggerPath 的值无效。”消息,则可能原因是您缺少 mingw-w64-gdb 软件包。

创建 Hello World 应用

首先,让我们设置一个项目。

  1. 启动 Windows 命令提示符(在 Windows 搜索栏中输入Windows 命令提示符)。
  2. 运行以下命令。这些命令将创建一个名为 projects 的空文件夹,您可以将所有 VS Code 项目放在其中。在该文件夹中,接下来的命令将创建一个名为 helloworld 的子文件夹并导航到该文件夹。从那里,您将在 VS Code 中直接打开 helloworld
mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .

“code .”命令将在当前工作文件夹中打开 VS Code,该文件夹将成为您的“工作区”。接受 工作区信任 对话框,方法是选择是,我信任作者,因为这是您创建的文件夹。

当您完成本教程时,您将看到在工作区中的 .vscode 文件夹中创建了三个文件

  • tasks.json(构建说明)
  • launch.json(调试器设置)
  • c_cpp_properties.json(编译器路径和 IntelliSense 设置)

添加 Hello World 源代码文件

在文件资源管理器标题栏中,选择新建文件按钮,并将文件命名为 helloworld.cpp

New File title bar button

添加 hello world 源代码

现在粘贴此源代码

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<string> msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};

    for (const string& word : msg)
    {
        cout << word << " ";
    }
    cout << endl;
}

现在按 ⌘S (Windows、Linux Ctrl+S) 保存文件。注意,您刚刚添加的文件是如何出现在 VS Code 侧边栏中的文件资源管理器视图 (⇧⌘E (Windows、Linux Ctrl+Shift+E)) 中的

File Explorer

您还可以通过选择文件 > 自动保存来启用 自动保存 以自动保存您的文件更改。您可以在 VS Code 的 用户界面文档 中了解有关其他视图的更多信息。

注意:当您保存或打开 C++ 文件时,您可能会看到来自 C/C++ 扩展的关于 Insiders 版本可用的通知,该版本可以让您测试新功能和修复。您可以通过选择 X清除通知)来忽略此通知。

探索 IntelliSense

IntelliSense 是一种工具,它可以通过添加代码编辑功能(如代码补全、参数信息、快速信息和成员列表)来帮助您更快、更有效地编写代码。

要查看 IntelliSense 的实际效果,请将鼠标悬停在 vectorstring 上以查看其类型信息。如果您在第 10 行键入 msg.,则可以看到建议的成员函数的补全列表,所有这些都由 IntelliSense 生成

Statement completion IntelliSense

您可以按 Tab 键插入选定的成员。如果您随后添加左括号,IntelliSense 将显示有关哪些参数是必需的信息。

如果 IntelliSense 尚未配置,请打开命令面板 (⇧⌘P (Windows、Linux Ctrl+Shift+P)) 并输入 选择 IntelliSense 配置。从编译器下拉列表中选择 Use gcc.exe 进行配置。有关更多信息,请参阅 IntelliSense 配置文档

运行 helloworld.cpp

请记住,C++ 扩展使用您机器上安装的 C++ 编译器来构建您的程序。在尝试在 VS Code 中运行和调试 helloworld.cpp 之前,请确保您已完成“安装 MinGW-w64 工具链”步骤。

  1. 打开 helloworld.cpp,使其成为活动文件。

  2. 按下编辑器右上角的播放按钮。

    Screenshot of helloworld.cpp and play button

  3. 从系统上检测到的编译器列表中选择 C/C++: g++.exe 构建并调试活动文件

    C++ debug configuration dropdown

您只需在第一次运行 helloworld.cpp 时选择编译器。该编译器将被设置为 tasks.json 文件中的“默认”编译器。

  1. 构建成功后,程序的输出将显示在集成的 终端 中。

    screenshot of program output

恭喜!您已在 VS Code 中运行了第一个 C++ 程序!

了解 tasks.json

首次运行程序时,C++ 扩展会创建一个 tasks.json 文件,您将在项目的 .vscode 文件夹中找到它。tasks.json 存储您的构建配置。

新的 tasks.json 文件应类似于下面的 JSON。

{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "C/C++: g++.exe build active file",
      "command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
      "args": [
        "-fdiagnostics-color=always",
        "-g",
        "${file}",
        "-o",
        "${fileDirname}\\${fileBasenameNoExtension}.exe"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": ["$gcc"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ],
  "version": "2.0.0"
}

注意:您可以在 变量参考 中了解有关 tasks.json 变量的更多信息。

command 设置指定要运行的程序;在本例中为 g++

args 数组指定传递给 g++ 的命令行参数。这些参数按编译器预期的特定顺序列在此文件中。

此任务指示 g++ 获取活动文件 (${file}),对其进行编译,并在当前目录 (${fileDirname}) 中创建一个与活动文件同名但扩展名为 .exe 的输出文件 (-o 开关)。(${fileBasenameNoExtension}.exe)。对于我们来说,这将导致 helloworld.exe

label 值是您将在任务列表中看到的内容;您可以将其命名为任何您喜欢的名称。

detail 值是您将在任务列表中看到的任务描述。强烈建议您重命名此值,以将其与类似任务区分开来。

problemMatcher 值选择用于在编译器输出中查找错误和警告的输出解析器。对于 GCC,如果您使用 $gcc 问题匹配器,则会获得最佳结果。

从现在开始,播放按钮将从 tasks.json 中读取以了解如何构建和运行您的程序。您可以在 tasks.json 中定义多个构建任务,并且播放按钮将使用标记为默认的任何任务。如果您需要更改默认编译器,可以在命令面板中运行 任务:配置默认构建任务。或者,您可以修改 tasks.json 文件并删除默认值,方法是将以下段落替换为

    "group": {
        "kind": "build",
        "isDefault": true
    },

改为以下内容

    "group": "build",

修改 tasks.json

您可以修改 tasks.json,通过使用类似 "${workspaceFolder}/*.cpp" 而不是 "${file}" 的参数来构建多个 C++ 文件。这将构建当前文件夹中的所有 .cpp 文件。您还可以通过将 "${fileDirname}\\${fileBasenameNoExtension}.exe" 替换为硬编码文件名(例如 "${workspaceFolder}\\myProgram.exe")来修改输出文件名。

调试 helloworld.cpp

要调试代码,

  1. 返回 helloworld.cpp,使其成为活动文件。
  2. 通过单击编辑器边距或在当前行上使用 F9 来设置断点。 helloworld.cpp 中断点的屏幕截图
  3. 从播放按钮旁边的下拉列表中选择 调试 C/C++ 文件播放按钮下拉菜单的屏幕截图
  4. 从系统上检测到的编译器列表中选择 C/C++: g++ 构建并调试活动文件(您只需在第一次运行或调试 helloworld.cpp 时选择编译器)。 C++ 调试配置下拉菜单

播放按钮有两种模式:运行 C/C++ 文件调试 C/C++ 文件。它将默认使用上次使用的模式。如果在播放按钮中看到调试图标,则可以选择播放按钮进行调试,而不是使用下拉菜单。

探索调试器

在您开始逐步执行代码之前,让我们花点时间注意用户界面中的几个变化

  • 集成终端出现在源代码编辑器的底部。在 调试控制台 选项卡中,您将看到指示调试器正在运行的输出。

  • 编辑器突出显示您在启动调试器之前设置断点的行

    Initial breakpoint

  • 左侧的 运行和调试 视图显示调试信息。您将在本教程后面的部分中看到一个示例。

  • 在代码编辑器的顶部,会显示一个调试控制面板。您可以通过抓住左侧的点来将它移动到屏幕上的其他位置。

    Debugging controls

逐步执行代码

现在您已准备好开始逐步执行代码。

  1. 在调试控制面板中选择 单步执行 图标。

    Step over button

    这将使程序执行前进到 for 循环的第一行,并跳过在创建和初始化 msg 变量时调用的 vectorstring 类中的所有内部函数调用。请注意左侧 变量 窗口的变化。

    Debugging windows

    在本例中,这些错误是预期的,因为尽管循环的变量名称现在对调试器可见,但该语句尚未执行,因此此时没有内容可读。但是,msg 的内容是可见的,因为该语句已完成执行。

  2. 再次按下 单步执行 以前进到该程序中的下一条语句(跳过执行以初始化循环的所有内部代码)。现在,变量 窗口显示有关循环变量的信息。

  3. 再次按下 单步执行 以执行 cout 语句。(请注意,C++ 扩展不会将任何输出打印到 调试控制台,直到循环退出为止。)

  4. 如果您愿意,可以一直按下 单步执行,直到矢量中的所有单词都打印到控制台。但是,如果您好奇,请尝试按下 单步进入 按钮来逐步执行 C++ 标准库中的源代码!

    要返回您自己的代码,一种方法是不断按下 单步执行。另一种方法是在代码中设置断点,方法是切换到代码编辑器中的 helloworld.cpp 选项卡,将插入点放在循环内的 cout 语句中的任何位置,然后按下 F9。左侧边距中会出现一个红色点,表示在此行上已设置断点。

    Breakpoint in main

    然后按下 F5 以从标准库头文件中的当前行开始执行。执行将在 cout 上中断。如果您愿意,可以再次按下 F9 以关闭断点。

    循环完成后,您可以在集成终端中看到输出,以及 GDB 输出的一些其他诊断信息。

    Debug output in terminal

设置监视

有时,您可能希望在程序执行时跟踪变量的值。您可以通过对该变量设置 监视 来实现这一点。

  1. 将插入点放在循环内。在 监视 窗口中,选择加号,然后在文本框中键入 word,它是循环变量的名称。现在,在逐步执行循环时查看 监视 窗口。

    Watch window

  2. 通过在循环之前添加以下语句来添加另一个监视:int i = 0;。然后,在循环内添加以下语句:++i;。现在,在您在上一步骤中执行的操作中添加对 i 的监视。

  3. 要快速查看执行暂停在断点上的任何变量的值,可以使用鼠标指针悬停在该变量上。

    Mouse hover

使用 launch.json 自定义调试

使用播放按钮或 F5 进行调试时,C++ 扩展会动态地创建调试配置。

在某些情况下,您可能需要自定义调试配置,例如指定要在运行时传递给程序的参数。您可以在 launch.json 文件中定义自定义调试配置。

要创建 launch.json,请从播放按钮下拉菜单中选择 添加调试配置

Add debug configuration play button menu

然后,您将看到一个包含各种预定义调试配置的下拉菜单。选择 C/C++: g++.exe 构建并调试活动文件

C++ debug configuration dropdown

VS Code 会在 .vscode 文件夹中创建一个 launch.json 文件,该文件看起来像这样

{
  "configurations": [
    {
      "name": "C/C++: g++.exe build and debug active file",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${fileDirname}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "C:\\msys64\\ucrt64\\bin\\gdb.exe",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        },
        {
          "description": "Set Disassembly Flavor to Intel",
          "text": "-gdb-set disassembly-flavor intel",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C/C++: g++.exe build active file"
    }
  ],
  "version": "2.0.0"
}

在上面的 JSON 中,program 指定您要调试的程序。此处将其设置为活动文件文件夹 (${fileDirname}) 和活动文件名,扩展名为 .exe (${fileBasenameNoExtension}.exe),如果 helloworld.cpp 是活动文件,则将为 helloworld.exeargs 属性是传递给程序在运行时使用的参数的数组。

默认情况下,C++ 扩展不会将任何断点添加到源代码中,并且 stopAtEntry 值设置为 false

stopAtEntry 值更改为 true,以在您开始调试时使调试器在 main 方法上停止。

从现在开始,播放按钮和 F5 将在启动程序进行调试时从您的 launch.json 文件中读取。

添加其他 C/C++ 设置

如果您想要对 C/C++ 扩展进行更多控制,可以创建一个 c_cpp_properties.json 文件,该文件将允许您更改设置,例如编译器路径、包含路径、C++ 标准(默认值为 C++17)等等。

您可以通过从命令面板运行命令 C/C++: 编辑配置 (UI) 来查看 C/C++ 配置 UI (⇧⌘P (Windows、Linux Ctrl+Shift+P))。

Command Palette

这将打开 C/C++ 配置 页面。当您在此处进行更改时,VS Code 会将这些更改写入 .vscode 文件夹中的名为 c_cpp_properties.json 的文件中。

在这里,我们已将 配置名称 更改为 GCC,将 编译器路径 下拉列表设置为 g++ 编译器,并将 IntelliSense 模式 设置为与编译器匹配 (gcc-x64)。

Command Palette

Visual Studio Code 将这些设置放在 .vscode\c_cpp_properties.json 中。如果您直接打开该文件,它应该看起来像这样

{
  "configurations": [
    {
      "name": "GCC",
      "includePath": ["${workspaceFolder}/**"],
      "defines": ["_DEBUG", "UNICODE", "_UNICODE"],
      "windowsSdkVersion": "10.0.22000.0",
      "compilerPath": "C:/msys64/mingw64/bin/g++.exe",
      "cStandard": "c17",
      "cppStandard": "c++17",
      "intelliSenseMode": "windows-gcc-x64"
    }
  ],
  "version": 4
}

只有在程序包含不在工作区或标准库路径中的头文件时,才需要添加到 包含路径 数组设置中。

编译器路径

扩展使用 compilerPath 设置来推断 C++ 标准库头文件路径。当扩展知道在何处可以找到这些文件时,它可以提供智能完成和 转到定义 导航等功能。

C/C++ 扩展尝试根据它在您的系统上找到的内容,使用默认编译器位置填充 compilerPath。扩展将在几个常见的编译器位置中查找。

compilerPath 搜索顺序是

  • 首先检查 Microsoft Visual C++ 编译器
  • 然后查找 Windows Subsystem for Linux (WSL) 上的 g++
  • 然后是 MinGW-w64 的 g++。

如果您已安装 Visual Studio 或 WSL,您可能需要更改 `compilerPath` 以匹配您的项目首选编译器。例如,如果您使用 i686 架构、Win32 线程和 sjlj 异常处理安装选项安装了 MinGW-w64 版本 8.1.0,则路径将如下所示:`C:\Program Files (x86)\mingw-w64\i686-8.1.0-win32-sjlj-rt_v6-rev0\mingw64\bin\g++.exe`。

故障排除

已安装 MSYS2,但仍未找到 g++ 和 gdb

您必须按照MSYS2 网站上的步骤,使用 MSYS CLI 安装完整的 MinGW-w64 工具链(`pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain`)以及所有必需的先决条件。该工具链包括 g++ 和 gdb。

作为 Windows 用户,运行 pacman 命令会出错

Windows 机器上的 UCRT 仅包含在 Windows 10 或更高版本中。如果您使用的是其他版本的 Windows,请运行以下不使用 UCRT 的命令

pacman -S --needed base-devel mingw-w64-x86_64-toolchain

将 MinGW-w64 目标文件夹添加到环境变量列表后,默认路径将变为:`C:\msys64\mingw64\bin`。

MinGW 32 位

如果您需要 32 位版本的 MinGW 工具集,请参阅 MSYS2 wiki 上的下载部分。它包含 32 位和 64 位安装选项的链接。

下一步

  • 探索VS Code 用户指南
  • 查看C++ 扩展概述
  • 创建一个新的工作区,将您的 `.vscode` JSON 文件复制到其中,调整新工作区路径、程序名称等必要设置,然后开始编码!