使用 MinGW 的 GCC
在本教學課程中,您將設定 Visual Studio Code 以使用來自 mingw-w64 的 GCC C++ 編譯器 (g++) 和 GDB 偵錯工具,來建立可在 Windows 上執行的程式。設定 VS Code 後,您將編譯、執行及偵錯 Hello World 程式。
本教學課程不會教導您關於 GCC、GDB、minGW-w64 或 C++ 語言的知識。關於這些主題,網路上有許多優良資源可供參考。
如果您有任何問題,歡迎在 VS Code 文件存放庫中針對本教學課程提出問題。
先決條件
若要成功完成本教學課程,您必須執行下列步驟
-
安裝 VS Code 的 C/C++ 擴充功能。您可以藉由在 [擴充功能] 檢視中搜尋 'C++' 來安裝 C/C++ 擴充功能 (⇧⌘X (Windows、Linux Ctrl+Shift+X))。
安裝 MinGW-w64 工具鏈
透過 MSYS2 取得最新版本的 MinGW-w64,其提供 GCC、MinGW-w64 和其他實用 C++ 工具和程式庫的最新原生組建。這將為您提供必要的工具來編譯程式碼、偵錯程式碼,並設定其與 IntelliSense 搭配運作。
若要安裝 MinGW-w64 工具鏈,請觀看此影片或遵循下列步驟
-
執行安裝程式並遵循安裝精靈的步驟。請注意,MSYS2 需要 64 位元 Windows 8.1 或更新版本。
-
在精靈中,選擇您想要的 [安裝資料夾]。記錄此目錄以供稍後使用。在大多數情況下,建議的目錄是可以接受的。當您設定 [開始] 功能表捷徑步驟時,情況亦同。完成後,請務必選取 [立即執行 MSYS2] 方塊,然後選取 [完成]。這會為您開啟 MSYS2 終端機視窗。
-
在此終端機中,執行下列命令以安裝 MinGW-w64 工具鏈
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
-
按下 Enter 鍵接受
toolchain
群組中的預設套件數。 -
當系統提示是否繼續安裝時,輸入
Y
。 -
使用下列步驟將 MinGW-w64
bin
資料夾的路徑新增至 WindowsPATH
環境變數- 在 Windows 搜尋列中,輸入 [設定] 以開啟 Windows 設定。
- 搜尋 [編輯您帳戶的環境變數]。
- 在 [使用者變數] 中,選取 [Path] 變數,然後選取 [編輯]。
- 選取 [新增],然後將您在安裝過程中記錄的 MinGW-w64 目的地資料夾新增至清單。如果您使用上述預設設定,則路徑會是:
C:\msys64\ucrt64\bin
。 - 選取 [確定],然後在 [環境變數] 視窗中再次選取 [確定] 以更新
PATH
環境變數。您必須重新開啟任何主控台視窗,更新後的PATH
環境變數才會生效。
檢查您的 MinGW 安裝
若要檢查您的 MinGW-w64 工具是否已正確安裝且可供使用,請開啟新的命令提示字元並輸入
gcc --version
g++ --version
gdb --version
您應該會看到指出您已安裝哪個版本的 GCC、g++ 和 GDB 的輸出。如果不是這種情況
- 請確定您的 PATH 變數項目符合安裝工具鏈的 MinGW-w64 二進位檔位置。如果編譯器不存在於該 PATH 項目中,請確定您已遵循先前的指示。
- 如果
gcc
有正確的輸出,但gdb
沒有,則您需要從 MinGW-w64 工具組安裝您遺失的套件。- 如果在編譯時收到「miDebuggerPath 的值無效」訊息,原因之一可能是您遺失了
mingw-w64-gdb
套件。
- 如果在編譯時收到「miDebuggerPath 的值無效」訊息,原因之一可能是您遺失了
建立 Hello World 應用程式
首先,讓我們設定專案。
- 啟動 Windows 命令提示字元 (在 Windows 搜尋列中輸入 [Windows 命令提示字元])。
- 執行下列命令。這些命令會建立名為
projects
的空資料夾,您可以在其中放置所有 VS Code 專案。接下來的命令會在其中建立名為helloworld
的子資料夾並導覽至該資料夾。從那裡,您將直接在 VS Code 中開啟helloworld
。
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
。
新增 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))
您也可以選取 [檔案] > [自動儲存] 來啟用 自動儲存,以自動儲存您的檔案變更。您可以在 VS Code 使用者介面文件中找到關於其他檢視的詳細資訊。
注意:當您儲存或開啟 C++ 檔案時,您可能會看到來自 C/C++ 擴充功能的通知,指出有 Insiders 版本可用,讓您可以測試新功能和修正程式。您可以選取
X
([清除通知]) 來忽略此通知。
探索 IntelliSense
IntelliSense 是一種工具,可藉由新增程式碼編輯功能 (例如程式碼完成、參數資訊、快速資訊和成員清單) 來協助您更快速且更有效率地撰寫程式碼。
若要查看 IntelliSense 的實際運作情況,請將滑鼠游標停留在 vector
或 string
上,以查看其類型資訊。如果您在第 10 行中輸入 msg.
,您可以看到建議呼叫的成員函式完成清單,全部由 IntelliSense 產生
您可以按下 Tab 鍵來插入選取的成員。如果您接著新增左括弧,IntelliSense 會顯示關於所需引數的資訊。
如果尚未設定 IntelliSense,請開啟 [命令選擇區] (⇧⌘P (Windows、Linux Ctrl+Shift+P)) 並輸入 [選取 IntelliSense 設定]。從編譯器下拉式清單中,選取 Use gcc.exe
以進行設定。如需詳細資訊,請參閱 IntelliSense 設定文件。
執行 helloworld.cpp
請記住,C++ 擴充功能會使用您在電腦上安裝的 C++ 編譯器來建置您的程式。在嘗試在 VS Code 中執行和偵錯 helloworld.cpp
之前,請確定您已完成「安裝 MinGW-w64 工具鏈」步驟。
-
開啟
helloworld.cpp
,使其成為作用中檔案。 -
按下編輯器右上角的 [播放] 按鈕。
-
從系統上偵測到的編譯器清單中,選擇 [C/C++: g++.exe 建置並偵錯作用中檔案]。
您只會在第一次執行 helloworld.cpp
時被要求選擇編譯器。此編譯器將在 tasks.json 檔案中設定為「預設」編譯器。
-
建置成功後,程式的輸出會出現在整合式 [終端機] 中。
恭喜!您剛剛已在 VS Code 中執行您的第一個 C++ 程式!
了解 tasks.json
第一次執行程式時,C++ 擴充功能會建立 tasks.json
檔案,您可以在專案的 .vscode
資料夾中找到該檔案。tasks.json
儲存您的建置組態。
您的新 tasks.json
檔案看起來應該與下方的 JSON 類似
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
注意:您可以在變數參考中深入了解
tasks.json
變數。
command
設定指定要執行的程式;在此案例中為 g++
。
args
陣列指定傳遞至 g++ 的命令列引數。這些引數會以編譯器預期的特定順序在此檔案中列出。
此工作會告知 g++ 採用作用中檔案 (${file}
)、編譯檔案,並在目前目錄 (${fileDirname}
) 中建立輸出檔案 (-o
參數),其名稱與作用中檔案相同,但副檔名為 .exe
(${fileBasenameNoExtension}.exe
)。對我們而言,這會產生 helloworld.exe
。
label
值是您會在工作清單中看到的內容;您可以將其命名為您喜歡的任何名稱。
detail
值是您會在工作清單中看到的任務描述。強烈建議您重新命名此值,以將其與類似的工作區分開來。
problemMatcher
值會選取輸出剖析器,以用於在編譯器輸出中尋找錯誤和警告。對於 GCC,如果您使用 $gcc
問題比對器,將會獲得最佳結果。
從現在起,[播放] 按鈕將從 tasks.json
讀取,以判斷如何建置和執行您的程式。您可以在 tasks.json
中定義多個建置工作,而標示為預設的工作將由 [播放] 按鈕使用。如果您需要變更預設編譯器,您可以執行 [工作: 設定預設建置工作] (在 [命令選擇區] 中)。或者,您可以修改 tasks.json
檔案,並藉由取代此區段來移除預設值
"group": {
"kind": "build",
"isDefault": true
},
以此取代
"group": "build",
修改 tasks.json
自 2024 年 11 月 3 日起,MSYS2 預設已停用 mingw-w64 的萬用字元支援。此變更會影響建置命令中如何處理 "*.cpp"
等萬用字元。若要在 tasks.json
中建置多個 C++ 檔案,您必須明確列出檔案、使用 make
或 cmake
等建置系統,或實作下列因應措施:https://www.msys2.org/docs/c/#expanding-wildcard-arguments。
如果您先前使用 "${workspaceFolder}/*.cpp"
來編譯目前資料夾中的所有 .cpp
檔案,這將不再直接運作。相反地,您可以手動列出檔案或定義建置指令碼。
偵錯 helloworld.cpp
若要偵錯您的程式碼,
- 返回
helloworld.cpp
,使其成為作用中檔案。 - 藉由按一下編輯器邊界或在目前行上使用 F9 來設定中斷點。
- 從 [播放] 按鈕旁的下拉式清單中,選取 [偵錯 C/C++ 檔案]。
- 從系統上偵測到的編譯器清單中,選擇 [C/C++: g++ 建置並偵錯作用中檔案] (您只會在第一次執行或偵錯
helloworld.cpp
時被要求選擇編譯器)。
[播放] 按鈕有兩種模式:[執行 C/C++ 檔案] 和 [偵錯 C/C++ 檔案]。它會預設為上次使用的模式。如果您在 [播放] 按鈕中看到偵錯圖示,您可以直接選取 [播放] 按鈕進行偵錯,而無需使用下拉式清單。
探索偵錯工具
在您開始逐步執行程式碼之前,讓我們先花點時間注意使用者介面中的幾項變更
-
整合式 [終端機] 會出現在原始碼編輯器的底部。在 [偵錯主控台] 索引標籤中,您會看到指出偵錯工具已啟動並執行的輸出。
-
編輯器會醒目提示您在啟動偵錯工具之前設定中斷點的行
-
左側的 [執行與偵錯] 檢視會顯示偵錯資訊。您稍後會在教學課程中看到範例。
-
在程式碼編輯器的頂端,會出現偵錯控制面板。您可以抓住左側的點,在螢幕上移動此面板。
逐步執行程式碼
現在您已準備好開始逐步執行程式碼。
-
在偵錯控制面板中,選取 [逐步跳過] 圖示。
這會將程式執行推進到 for 迴圈的第一行,並跳過在建立和初始化
msg
變數時叫用的 vector 和 string 類別內的所有內部函式呼叫。請注意左側 [變數] 視窗中的變更。在此案例中,這些錯誤是預期的,因為雖然迴圈的變數名稱現在對偵錯工具可見,但陳述式尚未執行,因此此時沒有任何內容可讀取。不過,
msg
的內容是可見的,因為該陳述式已完成。 -
再次按下 [逐步跳過] 以推進到此程式中的下一個陳述式 (跳過為初始化迴圈而執行的所有內部程式碼)。現在,[變數] 視窗會顯示關於迴圈變數的資訊。
-
再次按下 [逐步跳過] 以執行
cout
陳述式。(請注意,C++ 擴充功能在迴圈結束之前不會將任何輸出列印到 [偵錯主控台]。) -
如果您願意,您可以持續按下 [逐步跳過],直到向量中的所有文字都已列印到主控台為止。但如果您很好奇,請嘗試按下 [逐步執行] 按鈕,以逐步執行 C++ 標準程式庫中的原始碼!
若要返回您自己的程式碼,一種方法是持續按下 [逐步跳過]。另一種方法是在您的程式碼中設定中斷點,方法是切換到程式碼編輯器中的
helloworld.cpp
索引標籤,將插入點放在迴圈內cout
陳述式的某個位置,然後按下 F9。左側的邊界中會出現一個紅點,表示已在此行上設定中斷點。然後按下 F5 以從標準程式庫標頭中的目前行開始執行。執行會在
cout
上中斷。如果您願意,您可以再次按下 F9 以切換關閉中斷點。當迴圈完成時,您可以在整合式 [終端機] 中看到輸出,以及 GDB 輸出的其他診斷資訊。
設定監看式
有時您可能想要在程式執行時追蹤變數的值。您可以藉由在變數上設定監看式來執行此動作。
-
將插入點放在迴圈內。在 [監看式] 視窗中,選取加號,然後在文字方塊中輸入
word
,這是迴圈變數的名稱。現在在逐步執行迴圈時檢視 [監看式] 視窗。 -
藉由在迴圈之前新增此陳述式來新增另一個監看式:
int i = 0;
。然後,在迴圈內,新增此陳述式:++i;
。現在如同上一個步驟一樣,為i
新增監看式。 -
若要在執行暫停在中斷點時快速檢視任何變數的值,您可以將滑鼠游標停留在其上方。
使用 launch.json 自訂偵錯
當您使用 [播放] 按鈕或 F5 進行偵錯時,C++ 擴充功能會即時建立動態偵錯組態。
在某些情況下,您會想要自訂偵錯組態,例如指定要在執行階段傳遞至程式的引數。您可以在 launch.json
檔案中定義自訂偵錯組態。
若要建立 launch.json
,請從 [播放] 按鈕下拉式功能表中選擇 [新增偵錯組態]。
接著您會看到各種預先定義的偵錯組態下拉式清單。選擇 [C/C++: g++.exe 建置並偵錯作用中檔案]。
VS Code 會在 .vscode
資料夾中建立 launch.json
檔案`,其看起來類似如下
{
"configurations": [
{
"name": "C/C++: g++.exe build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "C:\\msys64\\ucrt64\\bin\\gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++.exe build active file"
}
],
"version": "2.0.0"
}
在上述 JSON 中,program
指定您想要偵錯的程式。此處會將其設定為作用中檔案資料夾 (${fileDirname}
) 和作用中檔案名稱,副檔名為 .exe
(${fileBasenameNoExtension}.exe
),如果 helloworld.cpp
是作用中檔案,則會是 helloworld.exe
。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 會將其寫入名為 c_cpp_properties.json
的檔案 (位於 .vscode
資料夾中)。
在此,我們已將 [組態名稱] 變更為 [GCC]、將 [編譯器路徑] 下拉式清單設定為 g++ 編譯器,並將 [IntelliSense 模式] 設定為符合編譯器 (gcc-x64)。
Visual Studio Code 會將這些設定放在 .vscode\c_cpp_properties.json
中。如果您直接開啟該檔案,其看起來應該類似如下
{
"configurations": [
{
"name": "GCC",
"includePath": ["${workspaceFolder}/**"],
"defines": ["_DEBUG", "UNICODE", "_UNICODE"],
"windowsSdkVersion": "10.0.22000.0",
"compilerPath": "C:/msys64/mingw64/bin/g++.exe",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}
只有當您的程式包含不在您的工作區或標準程式庫路徑中的標頭檔時,您才需要新增至 [包含路徑] 陣列設定。強烈建議不要針對我們支援的編譯器將系統包含路徑新增至 includePath
設定。
編譯器路徑
擴充功能會使用 compilerPath
設定來推斷 C++ 標準程式庫標頭檔的路徑。當擴充功能知道在何處尋找這些檔案時,它可以提供智慧型完成和 [跳到定義] 導覽等功能。
C/C++ 擴充功能會嘗試根據其在您的系統上找到的內容,使用預設編譯器來填入 compilerPath
。擴充功能會在數個常見的編譯器位置中尋找,但只會自動選取其中一個位於「Program Files」資料夾之一,或其路徑列在 PATH 環境變數中的編譯器。如果可以找到 Microsoft Visual C++ 編譯器,則會選取該編譯器,否則會選取 gcc、g++ 或 clang 的版本。
如果您安裝多個編譯器,您可能需要變更 compilerPath
以符合您專案的慣用編譯器。您也可以使用 [命令選擇區] 中的 [C/C++: 選取 IntelliSense 設定...] 命令,以選取擴充功能偵測到的編譯器之一。
疑難排解
已安裝 MSYS2,但仍找不到 g++ 和 gdb
您必須遵循 MSYS2 網站上的步驟,使用 MSYS CLI 安裝完整的 MinGW-w64 工具鏈 (pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
),以及所有必要的先決條件。工具鏈包含 g++ 和 gdb。
身為 Windows 使用者,執行 pacman 命令時發生錯誤
Windows 電腦上的 UCRT 僅包含在 Windows 10 或更新版本中。如果您使用的是其他版本的 Windows,請執行下列未使用 UCRT 的命令
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
當您將 MinGW-w64 目的地資料夾新增至您的環境變數清單時,預設路徑接著會是:C:\msys64\mingw64\bin
。
MinGW 32 位元
如果您需要 32 位元版本的 MinGW 工具組,請參閱 MSYS2 wiki 上的下載區段。其中包含 32 位元和 64 位元安裝選項的連結。
後續步驟
- 探索 VS Code 使用者指南。
- 檢閱 C++ 擴充功能概觀。
- 建立新的工作區、將您的
.vscode
JSON 檔案複製到其中、調整新工作區路徑、程式名稱等的必要設定,然後開始撰寫程式碼!