在 Linux 上使用 VS Code 進行 C++ 開發

在本教學課程中,您將設定 Visual Studio Code 以在 Linux 上使用 GCC C++ 編譯器 (g++) 與 GDB 偵錯工具。GCC 代表 GNU 編譯器集合 (GNU Compiler Collection);GDB 則是 GNU 偵錯工具。

設定好 VS Code 後,您將在 VS Code 中編譯並偵錯一個簡單的 C++ 程式。本教學課程不會教導您有關 GCC、GDB、Ubuntu 或 C++ 語言本身的知識。針對這些主題,網路上已有許多優質的資源可供參考。

如果您遇到問題,歡迎在 VS Code 文件儲存庫中針對本教學課程提出問題。

先決條件

若要順利完成本教學課程,您必須執行以下操作:

  1. 安裝 Visual Studio Code

  2. 安裝 VS Code 的 C++ 擴充功能。您可以透過在「擴充功能」(Extensions) 檢視中搜尋「c++」來安裝 C/C++ 擴充功能 (⇧⌘X (Windows, Linux Ctrl+Shift+X))。

    C/C++ extension

確保已安裝 GCC

雖然您會使用 VS Code 來編輯原始程式碼,但您將在 Linux 上使用 g++ 編譯器來進行編譯。您也將使用 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,該資料夾將成為您的「工作區」(workspace)。在閱讀本教學課程的過程中,您將在工作區中的 .vscode 資料夾內建立三個檔案

  • tasks.json (編譯器建置設定)
  • launch.json(偵錯工具設定)
  • c_cpp_properties.json(編譯器路徑與 IntelliSense 設定)

新增 Hello World 原始程式碼檔案

在檔案總管標題列中,選擇 **新增檔案** (New File) 並將檔案命名為 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 側邊欄的 **檔案總管** (File Explorer) 檢視 (⇧⌘E (Windows, Linux Ctrl+Shift+E)) 中。

File Explorer

您也可以勾選「檔案」主選單中的「自動儲存」,啟用自動儲存功能來自動儲存檔案變更。

Visual Studio Code 邊緣的活動列可讓您開啟不同的檢視,例如 **搜尋** (Search)、**原始檔控制** (Source Control) 與 **執行** (Run)。您稍後將在本教學課程中查看 **執行** 檢視。您可以在 VS Code 的 使用者介面文件中深入了解其他檢視。

注意:當您儲存或開啟 C++ 檔案時,您可能會看到 C/C++ 擴充功能關於 Insiders 版本可用性的通知,這讓您可以測試新功能與修正。您可以選取 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

您可以修改 tasks.json 以建置多個 C++ 檔案,方式是使用類似 "${workspaceFolder}/*.cpp" 的引數,而非 "${file}"。這會建置目前資料夾中所有的 .cpp 檔案。您也可以透過將 "${fileDirname}/${fileBasenameNoExtension}" 取代為硬編碼的檔名(例如 'helloworld.out')來修改輸出檔名。

偵錯 helloworld.cpp

若要偵錯您的程式碼:

  1. 回到 helloworld.cpp 使其成為作用中檔案。
  2. 透過點擊編輯器邊界或在目前行上使用 F9 來設定中斷點。 helloworld.cpp 中斷點截圖
  3. 從播放按鈕旁的下拉式選單中,選取 Debug C/C++ File播放按鈕下拉式選單截圖
  4. 從系統偵測到的編譯器清單中選擇 **C/C++: g++ build and debug active file**(您只需在第一次執行或偵錯 helloworld.cpp 時選擇編譯器)。C++ 偵錯設定下拉式選單

執行按鈕有兩種模式:**執行 C/C++ 檔案** (Run C/C++ File) 與 **偵錯 C/C++ 檔案** (Debug C/C++ File)。預設會使用上次使用的模式。如果您在執行按鈕中看到偵錯圖示,只需選取執行按鈕即可進行偵錯,無需選取下拉式選單項目。

探索偵錯器

在開始逐步執行程式碼之前,讓我們花點時間留意使用者介面的幾項變更

  • 整合式終端機會出現在原始碼編輯器的底部。在「偵錯輸出」索引標籤中,您會看到指出偵錯工具正在執行中的輸出。

  • 編輯器會反白顯示第 12 行,這是您在啟動偵錯工具之前設定的中斷點。

    Initial breakpoint

  • 左側的「執行與偵錯」檢視會顯示偵錯資訊。您稍後會在教學課程中看到範例。

  • 在程式碼編輯器的頂部,會出現一個偵錯控制面板。您可以透過抓取左側的點將其移至畫面其他位置。

    Debugging controls

如果您的工作區中已經有 launch.json 檔案,執行按鈕在判斷如何執行與偵錯您的 C++ 檔案時,將會讀取該檔案。如果您沒有 launch.json,執行按鈕會即時建立一個暫時性的「快速偵錯」設定,完全不需要 launch.json

逐步執行程式碼

現在您已準備好開始逐步執行程式碼。

  1. 點擊或按下偵錯控制面板中的「跳過 (Step over)」圖示。

    Step over button

    這會將程式執行進度推進到 for 迴圈的第一行,並跳過 vectorstring 類別內部的所有函式呼叫(這些呼叫是在建立並初始化 msg 變數時執行的)。請注意旁邊 **變數** (Variables) 視窗的變化。

    Debugging windows

  2. 再次按下「跳過」以推進到程式中的下一個陳述式(跳過初始化迴圈所執行的所有內部程式碼)。現在,「變數」視窗會顯示迴圈變數的相關資訊。

  3. 再次按下 **跳過** (Step over) 以執行 cout 陳述式。(請注意,在最後一個 cout 執行之前,C++ 擴充功能不會將任何輸出印至 **偵錯主控台** (Debug Console)。)

  4. 如果您願意,可以持續按下逐步跳過,直到向量中的所有單字都列印到主控台為止。但如果您感到好奇,請嘗試按下逐步執行 (Step Into) 按鈕,以逐步追蹤 C++ 標準函式庫中的原始程式碼!

    Breakpoint in gcc standard library header

    若要回到您自己的程式碼,一種方法是持續按下「跳過」。另一種方法是在您的程式碼中設定中斷點:切換至程式碼編輯器中的 helloworld.cpp 索引標籤,將插入點放在迴圈內 cout 陳述式的某處,然後按下 F9。左側裝訂邊會出現一個紅點,表示已在此行設定中斷點。

    Breakpoint in main

    然後按下 F5 從標準程式庫標頭中的目前行開始執行。程式執行將會在 cout 處中斷。如果您願意,可以再次按下 F9 來取消中斷點。

    當迴圈完成後,您可以在整合式終端機的 **偵錯主控台** (Debug Console) 索引標籤中看到輸出,以及 GDB 輸出的一些其他診斷資訊。

    Debug console display

設定監看式 (Watch)

若要在程式執行時追蹤變數的值,請對該變數設定 **監看式** (watch)。

  1. 將插入點置於迴圈內部。在 **監看式** (Watch) 視窗中,按一下加號,並在文字方塊中輸入 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++: Edit Configurations (UI) 命令來查看 C/C++ 設定 UI。

Command Palette

這會開啟 C/C++ 設定頁面。當您在此處進行變更時,VS Code 會將其寫入 .vscode 資料夾中名為 c_cpp_properties.json 的檔案。

IntelliSense configuration window

只有當您的程式包含不在工作區或標準程式庫路徑中的標頭檔時,才需要修改 **Include 路徑** (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 檔案複製到其中,為新的工作區路徑、程式名稱等調整必要的設定,然後開始編寫程式碼吧!
© . This site is unofficial and not affiliated with Microsoft.