🚀 在 VS Code 中

在 VS Code 中使用 C++ 和 WSL

在本教學課程中,您將設定 Visual Studio Code 以在 適用於 Linux 的 Windows 子系統 (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. 安裝 適用於 Linux 的 Windows 子系統,然後使用該頁面上的連結來安裝您選擇的 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 中執行的工作階段,您可以從下拉式選單中選取 關閉遠端連線 命令。從您的 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++ 編譯器來建置您的程式。在嘗試在 VS Code 中執行和偵錯 helloworld.cpp 之前,請確保您已安裝 C++ 編譯器。

  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,以透過使用類似 "${workspaceFolder}/*.cpp" 而非 "${file}" 的引數來建置多個 C++ 檔案。這將建置您目前資料夾中的所有 .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 工作階段。

後續步驟