试试在 VS Code 中使用

在 VS Code 中使用 Linux 上的 C++

在本教程中,你将配置 Visual Studio Code,以便在 Linux 上使用 GCC C++ 编译器 (g++) 和 GDB 调试器。GCC 代表 GNU 编译器集合;GDB 是 GNU 调试器。

配置 VS Code 后,你将在 VS Code 中编译和调试一个简单的 C++ 程序。本教程不教授 GCC、GDB、Ubuntu 或 C++ 语言本身。对于这些主题,Web 上有许多优秀的资源可供参考。

如果遇到问题,请随时在 VS Code 文档仓库 中提交有关本教程的问题。

先决条件

要成功完成本教程,你必须执行以下操作

  1. 安装 Visual Studio Code

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

    C/C++ extension

确保已安装 GCC

虽然你将使用 VS Code 编辑源代码,但你将使用 g++ 编译器在 Linux 上编译源代码。你还将使用 GDB 进行调试。这些工具默认不会安装在 Ubuntu 上,因此你必须安装它们。幸运的是,这很简单。

首先,检查 GCC 是否已经安装。要验证是否安装,请打开终端窗口并输入以下命令

gcc -v

如果 GCC 未安装,请在终端窗口中运行以下命令来更新 Ubuntu 包列表。过时的 Linux 发行版有时可能会干扰安装新软件包的操作。

sudo apt-get update

接下来,使用此命令安装 GNU 编译器工具和 GDB 调试器

sudo apt-get install build-essential gdb

创建 Hello World 程序

在终端窗口中,创建一个名为 projects 的空文件夹来存储 VS Code 项目。然后创建一个名为 helloworld 的子文件夹,导航到其中,并通过输入以下命令在该文件夹中打开 VS Code

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

粘贴以下源代码

#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;

    return 0;
}

现在按 ⌘S (Windows, Linux Ctrl+S) 保存文件。请注意,你的文件列在 VS Code 侧边栏的 文件资源管理器 视图 (⇧⌘E (Windows, Linux Ctrl+Shift+E)) 中

File Explorer

你还可以通过在主 文件 菜单中勾选 自动保存 来启用 自动保存,以便自动保存你的文件更改。

Visual Studio Code 边缘的活动栏允许你打开不同的视图,例如 搜索源代码管理运行。你将在本教程稍后查看 运行 视图。你可以在 VS Code 用户界面文档 中了解更多关于其他视图的信息。

注意:当你保存或打开 C++ 文件时,你可能会看到 C/C++ 扩展发出的关于 Insider 版本可用性的通知,该版本允许你测试新功能和修复程序。你可以通过选择 X (清除通知) 来忽略此通知。

探索 IntelliSense

helloworld.cpp 文件中,将鼠标悬停在 vectorstring 上方以查看类型信息。在声明 msg 变量后,开始输入 msg.,就像调用成员函数一样。你会立即看到一个显示所有成员函数的补全列表,以及一个显示 msg 对象类型信息的窗口

Statement completion IntelliSense

你可以按 Tab 键插入选定的成员。然后,当你添加开括号时,你会看到关于函数所需参数的信息。

运行 helloworld.cpp

请记住,C++ 扩展使用你机器上安装的 C++ 编译器来构建程序。在尝试在 VS Code 中运行和调试 helloworld.cpp 之前,请确保已安装 C++ 编译器。

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

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

    Screenshot of helloworld.cpp and play button

  3. 从系统检测到的编译器列表中选择 g++ build and debug active file (g++ 构建并调试活动文件)

    C++ debug configuration dropdown

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

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

    screenshot of program output

第一次运行程序时,C++ 扩展会创建 tasks.json 文件,该文件位于项目中的 .vscode 文件夹中。tasks.json 存储构建配置。

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

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "C/C++: g++ build active file",
      "command": "/usr/bin/g++",
      "args": ["-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}"],
      "options": {
        "cwd": "/usr/bin"
      },
      "problemMatcher": ["$gcc"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ]
}

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

command 设置指定要运行的程序;在本例中是 g++。args 数组指定将传递给 g++ 的命令行参数。这些参数必须按照编译器期望的顺序指定。

此任务告诉 g++ 获取活动文件 (${file}),编译它,并在当前目录 (${fileDirname}) 中创建一个与活动文件同名但没有扩展名 (${fileBasenameNoExtension}) 的可执行文件,对于我们的示例,结果是 helloworld

label 值是你在任务列表中看到的内容;你可以随意命名。

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

从现在开始,播放按钮将读取 tasks.json 文件来确定如何构建和运行你的程序。你可以在 tasks.json 中定义多个构建任务,任何标记为默认的任务都将由播放按钮使用。如果你需要更改默认编译器,可以运行 任务: 配置默认构建任务。或者,你可以修改 tasks.json 文件并通过替换以下部分来移除默认设置

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

使用此设置

    "group": "build",

修改 tasks.json

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

调试 helloworld.cpp

要调试代码,

  1. 返回到 helloworld.cpp 使其成为活动文件。
  2. 通过单击编辑器边距或在当前行使用 F9 设置断点。screenshot of breakpoint in helloworld.cpp
  3. 从播放按钮旁边的下拉列表中,选择 Debug C/C++ File (调试 C/C++ 文件)Screenshot of play button drop-down
  4. 从系统检测到的编译器列表中选择 C/C++: g++ build and debug active file (C/C++: g++ 构建并调试活动文件)(只有在第一次运行或调试 helloworld.cpp 时才会要求你选择编译器)。C++ debug configuration dropdown

播放按钮有两种模式:Run C/C++ File (运行 C/C++ 文件)Debug C/C++ File (调试 C/C++ 文件)。它将默认为上次使用的模式。如果你在播放按钮中看到调试图标,则可以直接选择播放按钮进行调试,而无需选择下拉菜单项。

探索调试器

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

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

  • 编辑器高亮显示第 12 行,这是你在启动调试器之前设置的断点

    Initial breakpoint

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

  • 在代码编辑器的顶部,会出现一个调试控制面板。你可以通过抓住左侧的点来在屏幕上移动它。

    Debugging controls

如果你的工作区中已有 launch.json 文件,则播放按钮将在确定如何运行和调试 C++ 文件时读取该文件。如果你没有 launch.json 文件,播放按钮将即时创建临时“快速调试”配置,从而完全无需 launch.json 文件!

逐步执行代码

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

  1. 单击或按下调试控制面板中的 逐过程 图标。

    Step over button

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

    Debugging windows

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

  3. 再次按 逐过程 执行 cout 语句。(注意,C++ 扩展在最后一个 cout 执行之前不会向 调试控制台 输出任何内容。)

  4. 如果愿意,可以继续按 逐过程,直到向量中的所有单词都打印到控制台。但如果你感到好奇,请尝试按下 逐语句 按钮来逐步执行 C++ 标准库中的源代码!

    Breakpoint in gcc standard library header

    要返回自己的代码,一种方法是继续按 逐过程。另一种方法是通过切换到代码编辑器中的 helloworld.cpp 选项卡,将插入点放在循环内 cout 语句的某个位置,然后按下 F9,在代码中设置断点。左侧的边栏中会出现一个红点,表示在此行设置了断点。

    Breakpoint in main

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

    循环完成后,你可以在集成终端的 调试控制台 选项卡中看到输出,以及 GDB 输出的其他一些诊断信息。

    Debug console display

设置监视

要在程序执行时跟踪变量的值,请在该变量上设置监视

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

    Watch window

  2. 要在执行暂停在断点处时快速查看任何变量的值,可以将鼠标指针悬停在其上方。

    Mouse hover

接下来,你将创建一个 tasks.json 文件来告诉 VS Code 如何构建(编译)程序。此任务将调用 g++ 编译器从源代码创建可执行文件。

在编辑器中打开 helloworld.cpp 很重要,因为下一步会使用编辑器中的活动文件作为上下文,在下一步中创建构建任务。

使用 launch.json 自定义调试

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

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

要创建 launch.json 文件,请从播放按钮下拉菜单中选择 Add Debug Configuration (添加调试配置)

Add debug configuration play button menu

然后,你会看到一个包含各种预定义调试配置的下拉列表。选择 g++ build and debug active file (g++ 构建并调试活动文件)

C++ debug configuration dropdown

VS Code 创建一个 launch.json 文件,看起来像这样

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C/C++: g++ build and debug active file",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}/${fileBasenameNoExtension}",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "/usr/bin/gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C/C++: g++ build active file"
    }
  ]
}

在上面的 JSON 中,program 指定了要调试的程序。在这里,它被设置为活动文件所在的文件夹 ${fileDirname} 和不带扩展名的活动文件名 ${fileBasenameNoExtension},如果 helloworld.cpp 是活动文件,则结果将是 helloworldargs 属性是一个数组,包含在运行时传递给程序的参数。

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

stopAtEntry 的值更改为 true,以便在开始调试时让调试器在 main 方法处停止。

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

C/C++ 配置

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

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

Command Palette

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

IntelliSense configuration window

只有当你的程序包含不在你的工作区或标准库路径中的头文件时,才需要修改 Include path (包含路径) 设置。

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

{
  "configurations": [
    {
      "name": "Linux",
      "includePath": ["${workspaceFolder}/**"],
      "defines": [],
      "compilerPath": "/usr/bin/gcc",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "intelliSenseMode": "clang-x64"
    }
  ],
  "version": 4
}

复用 C++ 配置

VS Code 现在已配置为在 Linux 上使用 gcc。此配置适用于当前工作区。要复用此配置,只需将 JSON 文件复制到新项目文件夹(工作区)中的 .vscode 文件夹中,并根据需要更改源代码文件和可执行文件的名称即可。

故障排除

编译器和链接错误

最常见的错误原因(例如 undefined _main,或 attempting to link with file built for unknown-unsupported file format 等)发生在你开始构建或开始调试时 helloworld.cpp 不是活动文件。这是因为编译器正尝试编译非源代码文件,例如你的 launch.jsontasks.jsonc_cpp_properties.json 文件。

下一步

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