參加你附近的 ,瞭解 VS Code 中的 AI 輔助開發。

透過 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 配置”。從編譯器下拉列表中,選擇 使用 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 build and debug active file”。

    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

從 2024 年 11 月 3 日起,MSYS2 預設停用了 mingw-w64 的萬用字元支援。此更改會影響像 "*.cpp" 這樣的萬用字元在構建命令中的處理方式。要在你的 tasks.json 中構建多個 C++ 檔案,你必須顯式列出檔案,使用像 makecmake 這樣的構建系統,或實施以下解決方法:https://www.msys2.org/docs/c/#expanding-wildcard-arguments。

如果你以前使用 "${workspaceFolder}/*.cpp" 來編譯當前資料夾中的所有 .cpp 檔案,這將不再直接有效。相反,你可以手動列出檔案或定義一個構建指令碼。

除錯 helloworld.cpp

要除錯你的程式碼,

  1. 回到 helloworld.cpp,使其成為活動檔案。
  2. 透過單擊編輯器邊距或在當前行使用 F9 設定斷點。helloworld.cpp 中斷點的螢幕截圖
  3. 從播放按鈕旁邊的下拉選單中,選擇除錯 C/C++ 檔案播放按鈕下拉選單的螢幕截圖
  4. 從你係統上檢測到的編譯器列表中選擇“C/C++: g++ build and debug active file”(你只有在第一次執行或除錯 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 build and debug active file”。

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)等設定。

你可以透過從命令面板 (⇧⌘P (Windows、Linux 為 Ctrl+Shift+P)) 執行 C/C++: 編輯配置 (UI) 命令來檢視 C/C++ 配置 UI。

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
}

只有當你的程式包含不在你的工作區或標準庫路徑中的標頭檔案時,你才需要新增到“包含路徑”陣列設定中。強烈建議不要將系統包含路徑新增到我們支援的編譯器的 includePath 設定中。

編譯器路徑

擴充套件使用 compilerPath 設定來推斷 C++ 標準庫標頭檔案的路徑。當擴充套件知道在哪裡找到這些檔案時,它就可以提供像智慧補全和“轉到定義”導航等功能。

C/C++ 擴充套件會嘗試根據它在你係統上找到的內容,為 compilerPath 填充一個預設編譯器。擴充套件會在幾個常見的編譯器位置查詢,但只會自動選擇位於“Program Files”資料夾之一或其路徑列在 PATH 環境變數中的編譯器。如果能找到 Microsoft Visual C++ 編譯器,它將被選中,否則它將選擇一個版本的 gcc、g++ 或 clang。

如果你安裝了多個編譯器,你可能需要更改 compilerPath 以匹配你專案的首選編譯器。你也可以在命令面板中使用“C/C++: 選擇 IntelliSense 配置...”命令來選擇擴充套件檢測到的編譯器之一。

故障排除

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 檔案複製到其中,為新的工作區路徑、程式名稱等調整必要的設定,然後開始編碼吧!