在 VS Code 中於 Linux 上使用 C++
在本教學課程中,您將設定 Visual Studio Code 以在 Linux 上使用 GCC C++ 編譯器 (g++) 和 GDB 偵錯工具。GCC 代表 GNU Compiler Collection (GNU 編譯器套件);GDB 是 GNU 偵錯工具。
設定 VS Code 後,您將在 VS Code 中編譯和偵錯簡單的 C++ 程式。本教學課程不會教您 GCC、GDB、Ubuntu 或 C++ 語言。關於這些主題,網路上有許多優良資源。
如果您有問題,歡迎在 VS Code 文件存放庫中針對本教學課程提出問題。
先決條件
若要成功完成本教學課程,您必須執行下列操作
-
安裝 VS Code 的 C++ 擴充功能。您可以在 [擴充功能] 檢視中搜尋 'c++' 來安裝 C/C++ 擴充功能 (⇧⌘X (Windows、Linux Ctrl+Shift+X))。
確認已安裝 GCC
雖然您將使用 VS Code 來編輯原始碼,但您將使用 g++ 編譯器在 Linux 上編譯原始碼。您也會使用 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,此資料夾會變成您的「工作區」。當您逐步執行教學課程時,您將在工作區中的 .vscode
資料夾中建立三個檔案
tasks.json
(編譯器建置設定)launch.json
(偵錯工具設定)c_cpp_properties.json
(編譯器路徑和 IntelliSense 設定)
新增 Hello World 原始碼檔案
在 [檔案總管] 標題列中,選取 [新增檔案] 並將檔案命名為 helloworld.cpp
。
貼上下列原始碼
#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 側邊欄的 [檔案總管] 檢視中 (⇧⌘E (Windows、Linux Ctrl+Shift+E))
您也可以啟用自動儲存以自動儲存檔案變更,方法是在主要 [檔案] 功能表中勾選 [自動儲存]。
Visual Studio Code 邊緣的活動列可讓您開啟不同的檢視,例如 [搜尋]、[原始檔控制] 和 [執行]。您稍後會在教學課程中查看 [執行] 檢視。您可以在 VS Code 使用者介面文件中找到有關其他檢視的詳細資訊。
注意:當您儲存或開啟 C++ 檔案時,您可能會看到來自 C/C++ 擴充功能的通知,告知 Insiders 版本可用,讓您可以測試新功能和修正程式。您可以選取
X
([清除通知]) 來忽略此通知。
探索 IntelliSense
在 helloworld.cpp
檔案中,將滑鼠停留在 vector
或 string
上以查看類型資訊。在宣告 msg
變數之後,開始輸入 msg.
,就像您呼叫成員函式一樣。您應該立即看到完成清單,其中顯示所有成員函式,以及顯示 msg
物件類型資訊的視窗
您可以按下 Tab 鍵來插入選取的成員。然後,當您新增左括號時,您會看到函式所需引數的相關資訊。
執行 helloworld.cpp
請記住,C++ 擴充功能會使用您機器上安裝的 C++ 編譯器來建置您的程式。在嘗試在 VS Code 中執行和偵錯 helloworld.cpp
之前,請確定您已安裝 C++ 編譯器。
-
開啟
helloworld.cpp
,使其成為作用中檔案。 -
按下編輯器右上角的播放按鈕。
-
從系統上偵測到的編譯器清單中選擇 [g++ 建置並偵錯作用中檔案]。
您只會在第一次執行 helloworld.cpp
時被要求選擇編譯器。此編譯器將在 tasks.json
檔案中設定為「預設」編譯器。
-
建置成功後,程式的輸出將會出現在整合式 [終端機] 中。
第一次執行程式時,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
若要偵錯您的程式碼,
- 返回
helloworld.cpp
,使其成為作用中檔案。 - 藉由按一下編輯器邊界或在目前行上使用 F9 來設定中斷點。
- 從播放按鈕旁邊的下拉式選單中,選取 [偵錯 C/C++ 檔案]。
- 從系統上偵測到的編譯器清單中選擇 [C/C++: g++ 建置並偵錯作用中檔案] (您只會在第一次執行或偵錯
helloworld.cpp
時被要求選擇編譯器)。
播放按鈕有兩種模式:[執行 C/C++ 檔案] 和 [偵錯 C/C++ 檔案]。它會預設為上次使用的模式。如果您在播放按鈕中看到偵錯圖示,您可以直接選取播放按鈕進行偵錯,而無需選取下拉式選單項目。
探索偵錯工具
在您開始逐步執行程式碼之前,讓我們先花一點時間注意使用者介面中的幾項變更
-
整合式 [終端機] 出現在原始碼編輯器的底部。在 [偵錯輸出] 索引標籤中,您會看到指出偵錯工具已啟動並執行的輸出。
-
編輯器會醒目提示第 12 行,這是您在啟動偵錯工具之前設定的中斷點
-
左側的 [執行和偵錯] 檢視會顯示偵錯資訊。您稍後會在教學課程中看到範例。
-
在程式碼編輯器的頂端,會出現偵錯控制面板。您可以抓住左側的點,在螢幕上移動它。
如果您在工作區中已有 launch.json 檔案,播放按鈕會在判斷如何執行和偵錯您的 C++ 檔案時從中讀取。如果您沒有 launch.json,播放按鈕將動態建立暫時的「快速偵錯」組態,完全無需 launch.json!
逐步執行程式碼
現在您已準備好開始逐步執行程式碼。
-
按一下或按下偵錯控制面板中的 [逐步跳過] 圖示。
這會將程式執行推進到 for 迴圈的第一行,並跳過在建立和初始化
msg
變數時所呼叫的vector
和string
類別中的所有內部函式呼叫。請注意側邊 [變數] 視窗中的變更。 -
再次按下 [逐步跳過] 以推進到此程式中的下一個陳述式 (跳過執行以初始化迴圈的所有內部程式碼)。現在,[變數] 視窗會顯示迴圈變數的相關資訊。
-
再次按下 [逐步跳過] 以執行
cout
陳述式。(請注意,C++ 擴充功能在最後一個 cout 執行之前,不會將任何輸出列印到 [偵錯主控台]。) -
如果您願意,您可以繼續按下 [逐步跳過],直到向量中的所有單字都已列印到主控台為止。但如果您好奇,請嘗試按下 [逐步進入] 按鈕,逐步執行 C++ 標準程式庫中的原始碼!
若要返回您自己的程式碼,一種方法是繼續按下 [逐步跳過]。另一種方法是在程式碼中設定中斷點,方法是切換到程式碼編輯器中的
helloworld.cpp
索引標籤,將插入點放在迴圈內cout
陳述式的某處,然後按下 F9。左側邊界中會出現一個紅色點,表示已在此行上設定中斷點。然後按下 F5,從標準程式庫標頭中的目前行開始執行。執行將在
cout
上中斷。如果您願意,您可以再次按下 F9 以切換關閉中斷點。迴圈完成後,您可以在整合式終端機的 [偵錯主控台] 索引標籤中看到輸出,以及 GDB 輸出的其他一些診斷資訊。
設定監看式
若要在程式執行時追蹤變數的值,請在變數上設定監看式。
-
將插入點放在迴圈內。在 [監看式] 視窗中,按一下加號,並在文字方塊中輸入
word
,這是迴圈變數的名稱。現在,當您逐步執行迴圈時,請檢視 [監看式] 視窗。 -
若要在執行在斷點暫停時快速檢視任何變數的值,您可以將滑鼠指標停留在其上方。
接下來,您將建立 tasks.json
檔案,以告知 VS Code 如何建置 (編譯) 程式。此工作將叫用 g++ 編譯器,從原始碼建立可執行檔。
在編輯器中開啟 helloworld.cpp
很重要,因為下一個步驟會使用編輯器中的作用中檔案作為內容,以在下一個步驟中建立建置工作。
使用 launch.json 自訂偵錯
當您使用播放按鈕或 F5 進行偵錯時,C++ 擴充功能會動態建立偵錯組態。
在某些情況下,您會想要自訂偵錯組態,例如指定在執行階段傳遞至程式的引數。您可以在 launch.json
檔案中定義自訂偵錯組態。
若要建立 launch.json
,請從播放按鈕下拉式選單中選擇 [新增偵錯組態]。
然後,您會看到各種預先定義的偵錯組態的下拉式選單。選擇 [g++ 建置並偵錯作用中檔案]。
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
是作用中檔案,則會是 helloworld
。args
屬性是要在執行階段傳遞至程式的引數陣列。
預設情況下,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。
這會開啟 [C/C++ 組態] 頁面。當您在此處進行變更時,VS Code 會將它們寫入 .vscode
資料夾中名為 c_cpp_properties.json
的檔案。
只有當您的程式包含不在工作區或標準程式庫路徑中的標頭檔時,您才需要修改 [包含路徑] 設定。
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.json
、tasks.json
或 c_cpp_properties.json
檔案。
後續步驟
- 探索VS Code 使用者指南。
- 檢閱C++ 擴充功能總覽。
- 建立新的工作區,將您的 .json 檔案複製到其中,調整新工作區路徑、程式名稱等的必要設定,然後開始撰寫程式碼!