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

在 VS Code 中使用 C++ 和 WSL

在本教程中,你將在 Windows Subsystem for Linux (WSL) 中配置 Visual Studio Code 以在 Ubuntu 上使用 GCC C++ 編譯器 (g++) 和 GDB 偵錯程式。GCC 代表 GNU Compiler Collection;GDB 是 GNU 偵錯程式。WSL 是 Windows 內的一個 Linux 環境,它直接在機器硬體上執行,而不是在虛擬機器中。

注意:本教程的大部分內容也適用於直接在 Linux 機器上使用 C++ 和 VS Code。

Visual Studio Code 透過 WSL 擴充套件支援直接在 WSL 中工作。我們推薦這種 WSL 開發模式,即你的所有原始碼檔案以及編譯器都託管在 Linux 發行版上。有關更多背景資訊,請參閱 VS Code 遠端開發

完成本教程後,你將能夠建立和配置自己的 C++ 專案,並可以瀏覽 VS Code 文件以獲取有關其眾多功能的更多資訊。本教程不教授 GCC、Linux 或 C++ 語言。對於這些主題,網上有許多很好的資源。

如果你遇到任何問題,請隨時在 VS Code 文件倉庫中為本教程提交 issue。

先決條件

要成功完成本教程,你必須執行以下步驟

  1. 安裝 Visual Studio Code

  2. 安裝 WSL 擴充套件

  3. 安裝 Windows Subsystem for Linux,然後使用該頁面上的連結安裝你選擇的 Linux 發行版。本教程使用 Ubuntu。在安裝過程中,請記住你的 Linux 使用者密碼,因為安裝其他軟體時需要它。

設定你的 Linux 環境

  1. 開啟 WSL 的 Bash shell。如果你安裝了 Ubuntu 發行版,請在 Windows 搜尋框中鍵入“Ubuntu”,然後在結果列表中單擊它。對於 Debian,鍵入“Debian”,依此類推。

    Ubuntu in Start Menu

    shell 會出現一個命令提示符,預設情況下由你的使用者名稱和計算機名組成,並將你置於主目錄中。對於 Ubuntu,它看起來像這樣

    Bash Shell

  2. 建立一個名為 projects 的目錄,然後在該目錄下建立一個名為 helloworld 的子目錄

    mkdir projects
    cd projects
    mkdir helloworld
    
  3. 雖然你將使用 VS Code 編輯原始碼,但你將在 Linux 上使用 g++ 編譯器編譯原始碼。你還將在 Linux 上使用 GDB 進行除錯。這些工具預設沒有安裝在 Ubuntu 上,所以你必須安裝它們。幸運的是,這項任務相當簡單!

  4. 在 WSL 命令提示符中,首先執行 apt-get update 來更新 Ubuntu 軟體包列表。過時的發行版有時會干擾安裝新軟體包的嘗試。

    sudo apt-get update
    

    如果你願意,可以執行 sudo apt-get update && sudo apt-get dist-upgrade 來下載最新版本的系統軟體包,但這可能需要更長的時間,具體取決於你的網路連線速度。

  5. 在命令提示符下,透過鍵入以下命令安裝 GNU 編譯器工具和 GDB 偵錯程式

    sudo apt-get install build-essential gdb
    
  6. 透過定位 g++ 和 gdb 來驗證安裝是否成功。如果 whereis 命令沒有返回檔名,請嘗試再次執行更新命令。

    whereis g++
    whereis gdb
    

注意:如果你直接在 Linux 機器上而不是在 WSL 中工作,安裝 g++ 編譯器和 GDB 偵錯程式的設定步驟同樣適用。在你的 helloworld 專案中執行 VS Code,以及編輯、構建和除錯的步驟都是相同的。

在 WSL 中執行 VS Code

導航到你的 helloworld 專案資料夾,並從 WSL 終端用 code . 啟動 VS Code

cd $HOME/projects/helloworld
code .

你會看到一條關於“正在安裝 VS Code Server”的訊息。VS Code 正在 Linux 端下載並安裝一個小伺服器,桌面的 VS Code 將與該伺服器通訊。然後 VS Code 將啟動並開啟 helloWorld 資料夾。檔案資源管理器顯示 VS Code 現在正在 WSL 的上下文中執行,標題欄為 WSL: Ubuntu

File Explorer in WSL

你也可以從狀態列中分辨出遠端上下文。

Remote context in the Status bar

如果單擊遠端狀態列項,你將看到一個適用於當前會話的遠端命令下拉列表。例如,如果你想結束在 WSL 中執行的會話,可以從下拉列表中選擇 Close Remote Connection 命令。在 WSL 命令提示符下執行 code . 將重新啟動在 WSL 中執行的 VS Code。

code . 命令在當前工作資料夾中打開了 VS Code,該資料夾成為你的“工作區”。在本教程的學習過程中,你會看到在工作區的 .vscode 資料夾中建立了三個檔案

  • c_cpp_properties.json(編譯器路徑和 IntelliSense 設定)
  • tasks.json(生成說明)
  • launch.json(偵錯程式設定)

新增原始碼檔案

在“檔案資源管理器”標題欄中,選擇新建檔案按鈕並將檔案命名為 helloworld.cpp

New File title bar button

安裝 C/C++ 擴充套件

一旦你建立了檔案並且 VS Code 檢測到它是一個 C++ 語言檔案,如果你尚未安裝微軟 C/C++ 擴充套件,系統可能會提示你安裝。

C++ extension notification

選擇安裝,然後在擴充套件檢視中顯示按鈕時選擇需要過載以完成 C/C++ 擴充套件的安裝。

如果你已經在 VS Code 本地安裝了 C/C++ 語言擴充套件,你需要轉到擴充套件檢視 (⇧⌘X (Windows、Linux 為 Ctrl+Shift+X)) 並將這些擴充套件安裝到 WSL 中。本地安裝的擴充套件可以透過選擇在 WSL 中安裝按鈕然後選擇需要過載來安裝到 WSL 中。

Install in WSL 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 使用者介面文件中找到有關其他檢視的更多資訊。

探索 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

    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

你可以修改你的 tasks.json 以構建多個 C++ 檔案,方法是使用像 "${workspaceFolder}/*.cpp" 這樣的引數來代替 "${file}"。這將構建你當前資料夾中所有的 .cpp 檔案。你還可以透過將 "${fileDirname}/${fileBasenameNoExtension}" 替換為硬編碼的檔名(例如 'helloworld.out')來修改輸出檔名。

除錯 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++ 檔案。它將預設為上次使用的模式。如果你在播放按鈕中看到除錯圖示,你可以直接點選播放按鈕進行除錯,而無需選擇下拉選單項。

探索偵錯程式

在開始單步除錯程式碼之前,我們花點時間注意使用者介面中的幾處變化

  • 整合終端出現在原始碼編輯器的底部。在除錯輸出選項卡中,你將看到指示偵錯程式已啟動並正在執行的輸出。

  • 編輯器高亮顯示第 12 行,這是你在啟動偵錯程式之前設定的斷點

    Initial breakpoint

  • 左側的執行和除錯檢視顯示除錯資訊。你將在本教程的後面看到一個示例。

  • 程式碼編輯器頂部會出現一個除錯控制面板。你可以透過抓取左側的點來在螢幕上移動它。

    Debugging controls

如果你的工作區中已經有一個 launch.json 檔案,播放按鈕在確定如何執行和除錯你的 C++ 檔案時會讀取它。如果你沒有 launch.json,播放按鈕會即時建立一個臨時的“快速除錯”配置,從而完全不需要 launch.json!

單步除錯程式碼

現在你已準備好開始單步除錯程式碼。

  1. 單擊或按下除錯控制面板中的跳過圖示。

    Step over button

    這將使程式執行前進到 for 迴圈的第一行,並跳過在建立和初始化 msg 變數時呼叫的 vectorstring 類中的所有內部函式呼叫。注意側邊變數視窗的變化。

    Debugging windows

  2. 再次按跳過以推進到此程式中的下一個語句(跳過用於初始化迴圈的所有內部程式碼)。現在,變數視窗顯示有關迴圈變數的資訊。

  3. 再次按單步跳過來執行 cout 語句。(請注意,在最後一個 cout 執行之前,C++ 擴充套件不會向除錯控制檯列印任何輸出。)

  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 play button menu

然後你會看到一個包含各種預定義除錯配置的下拉列表。選擇 g++ build and debug active file

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++: 編輯配置 (UI) 命令來檢視 C/C++ 配置 UI。

Command Palette

這將開啟C/C++ 配置頁面。當你在此處進行更改時,VS Code 會將它們寫入 .vscode 資料夾中名為 c_cpp_properties.json 的檔案。

Command Palette

只有當你的程式包含了不在你的工作區或標準庫路徑中的標頭檔案時,你才需要修改包含路徑設定。

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
}

關閉 WSL 會話

當你在 WSL 中的工作完成後,你可以使用主檔案選單和命令面板 (⇧⌘P (Windows、Linux 為 Ctrl+Shift+P)) 中可用的關閉遠端連線命令來關閉你的遠端會話。這將重新啟動在本地執行的 VS Code。你可以透過選擇帶有 [WSL] 字尾的資料夾,從檔案 > 開啟最近的檔案列表中輕鬆地重新開啟你的 WSL 會話。

後續步驟