🚀 在 VS Code 中

在 VS Code 中使用 C++ 和 WSL

在本教學課程中,您將設定 Visual Studio Code 以在 Windows Subsystem for Linux (WSL) 的 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 文件存放庫中為本教學課程提交問題。

先決條件

若要成功完成本教學課程,您必須執行下列步驟

  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 來編輯您的原始碼,但您將使用 g++ 編譯器在 Linux 上編譯原始碼。您也將使用 GDB 在 Linux 上偵錯。這些工具預設未安裝在 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 專案資料夾,並使用 code . 從 WSL 終端機啟動 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 中執行的工作階段,您可以從下拉式選單中選取關閉遠端連線命令。從您的 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++ 語言檔案,如果您尚未安裝 Microsoft 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++ 編譯器來建置您的程式。請確保您已安裝 C++ 編譯器,然後再嘗試在 VS Code 中執行和偵錯 helloworld.cpp

  1. 開啟 helloworld.cpp,使其成為作用中檔案。

  2. 按下編輯器右上角的播放按鈕。

    Screenshot of helloworld.cpp and play button

  3. 從系統上偵測到的編譯器清單中選擇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

您可以修改您的 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++ 建置並偵錯作用中檔案 (您只會在第一次執行或偵錯 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 陳述式。(請注意,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 play button menu

然後您會看到各種預先定義的偵錯組態的下拉式選單。選擇 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++:編輯組態 (UI) 來檢視 C/C++ 組態 UI。

Command Palette

這會開啟C/C++ 組態頁面。當您在此處進行變更時,VS Code 會將它們寫入名為 c_cpp_properties.json 的檔案中,該檔案位於 .vscode 資料夾中。

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 工作階段。

後續步驟