現已釋出!閱讀關於 11 月新增功能和修復的內容。

在 Visual Studio Code 中使用 Clang

在本教程中,您將在 macOS 上配置 Visual Studio Code 以使用 Clang/LLVM 編譯器和偵錯程式。

配置 VS Code 後,您將在 VS Code 中編譯和除錯 C++ 程式。本教程不講解 Clang 或 C++ 語言。有關這些主題,網路上有很多優秀的資源。

如果您遇到任何問題,請隨時在 VS Code 文件儲存庫中為此教程提交 issue。

先決條件

要成功完成本教程,你必須執行以下步驟

  1. 安裝 macOS 上的 Visual Studio Code

  2. 安裝 VS Code 的 C++ 擴充套件。您可以透過在“擴充套件”檢視中搜索“C++”來安裝 C/C++ 擴充套件(⇧⌘X (Windows、Linux Ctrl+Shift+X))。

    C/C++ extension

確保 Clang 已安裝

您的 Mac 可能已經安裝了 Clang。要驗證這一點,請開啟 macOS 終端視窗並輸入以下命令:

clang --version

如果未安裝 Clang,請鍵入以下命令安裝命令列開發人員工具,其中包括 Clang:

xcode-select --install

建立 Hello World 應用

在 macOS 終端中,建立一個名為 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

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;
}

現在按 ⌘S (Windows、Linux Ctrl+S) 儲存檔案。請注意,您的檔案已列在 VS Code 側邊欄的“檔案資源管理器”檢視(⇧⌘E (Windows、Linux Ctrl+Shift+E))中。

File Explorer

您還可以透過選擇“檔案” > “自動儲存”來啟用“自動儲存”,以自動儲存檔案更改。您可以在 VS Code 的 使用者介面文件中找到有關其他檢視的更多資訊。

注意:當你儲存或開啟 C++ 檔案時,你可能會看到來自 C/C++ 擴充套件的關於 Insiders 版本可用性的通知,該版本可讓你測試新功能和修復。你可以透過選擇 X清除通知)來忽略此通知。

探索 IntelliSense

IntelliSense 是一種工具,透過新增程式碼補全、引數資訊、快速資訊和成員列表等程式碼編輯功能,幫助您更快、更高效地編碼。

要檢視 IntelliSense 的實際效果,請將滑鼠懸停在 vectorstring 上以檢視其型別資訊。如果您在第 10 行鍵入 msg.,您將看到一個推薦成員函式的補全列表,所有這些都由 IntelliSense 生成。

Statement completion IntelliSense

您可以按 Tab 鍵插入選定的成員。然後,當您新增開括號時,將顯示有關函式所需引數的資訊。

如果 IntelliSense 尚未配置,請開啟命令面板(⇧⌘P (Windows、Linux Ctrl+Shift+P)),然後輸入選擇 IntelliSense 配置。從編譯器下拉列表中,選擇 使用 clang++ 進行配置。有關更多資訊,請參閱 IntelliSense 配置文件

執行 helloworld.cpp

請記住,C++ 擴充套件使用您在計算機上安裝的 C++ 編譯器來構建您的程式。在嘗試在 VS Code 中執行和除錯 helloworld.cpp 之前,請確保您已安裝 C++ 編譯器,例如 Clang。

  1. 開啟 helloworld.cpp,使其成為活動檔案。

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

    Screenshot of helloworld.cpp and play button

  3. 從系統中檢測到的編譯器列表中選擇“C/C++: clang++ 構建和除錯活動檔案”。

    Build and debug task

只有在首次執行 helloworld.cpp 時才會要求您選擇編譯器。此編譯器是 tasks.json 檔案中設定的“預設”編譯器。

  1. 構建成功後,程式的輸出將顯示在整合的“除錯控制檯”中。

    screenshot of program output

恭喜!您剛剛在 VS Code 中運行了第一個 C++ 程式!

理解 tasks.json

首次執行程式時,C++ 擴充套件會建立 tasks.json 檔案,該檔案位於專案資料夾的 .vscode 中。tasks.json 儲存構建配置。

以下是 macOS 上的 tasks.json 檔案示例:

{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "C/C++: clang++ build active file",
      "command": "/usr/bin/clang++",
      "args": [
        "-fcolor-diagnostics",
        "-fansi-escape-codes",
        "-g",
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": ["$gcc"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ],
  "version": "2.0.0"
}

注意:你可以在變數參考中瞭解有關 tasks.json 變數的更多資訊。

command 設定指定要執行的程式。在這種情況下,它是 clang++

args 陣列指定傳遞給 clang++ 的命令列引數。這些引數必須按照編譯器期望的順序指定。

此任務指示 C++ 編譯器接受活動檔案 (${file}),對其進行編譯,並在當前目錄 (${fileDirname}) 中建立輸出檔案(使用 -o 開關),該檔名與活動檔名相同,但不帶副檔名(${fileBasenameNoExtension})。此過程將建立 helloworld

label 值是您在任務列表中看到的內容,它基於您的個人偏好。

detail 值是任務列表中任務的描述。更新此字串以將其與類似任務區分開。

problemMatcher 值選擇用於在編譯器輸出中查詢錯誤和警告的輸出解析器。對於 clang++,$gcc problemMatcher 可產生最佳結果。

從現在開始,播放按鈕始終從 tasks.json 讀取以確定如何構建和執行您的程式。您可以在 tasks.json 中定義多個構建任務,其中標記為預設的任務是播放按鈕使用的任務。如果您需要更改預設編譯器,可以在命令面板中執行“任務: 配置預設構建任務”。或者,您可以修改 tasks.json 檔案並透過替換此段來刪除預設值:

    "group": {
        "kind": "build",
        "isDefault": true
    },

替換為

    "group": "build",

修改 tasks.json

您可以透過使用類似 "${workspaceFolder}/*.cpp" 的引數而不是 "${file}" 來修改 tasks.json 以構建多個 C++ 檔案。這會構建當前資料夾中的所有 .cpp 檔案。您還可以透過將 "${fileDirname}/${fileBasenameNoExtension}" 替換為硬編碼檔名(例如 "${workspaceFolder}/myProgram.out")來修改輸出檔名。

除錯 helloworld.cpp

要除錯你的程式碼,

  1. 回到 helloworld.cpp,使其成為活動檔案。

  2. 透過單擊編輯器邊距或使用 F9 在當前行設定斷點。

    screenshot of breakpoint in helloworld.cpp

  3. 從播放按鈕旁邊的下拉列表中,選擇“除錯 C/C++ 檔案”。

    Screenshot of play button drop-down

  4. 從系統中檢測到的編譯器列表中選擇“C/C++: clang++ 構建和除錯活動檔案”(只有在首次執行或除錯 helloworld.cpp 時才會要求您選擇編譯器)。

    Build and debug task

  5. 您將看到任務執行並在“終端”視窗中列印輸出。

    Hello World Terminal Output

播放按鈕有兩種模式:“執行 C/C++ 檔案”和“除錯 C/C++ 檔案”。預設是最後使用的模式。如果您在播放按鈕上看到除錯圖示,則可以選擇播放按鈕進行除錯,而不是選擇下拉選單項。

探索偵錯程式

在開始單步除錯程式碼之前,我們花點時間注意使用者介面中的幾處變化

  • 整合終端出現在原始碼編輯器的底部。在“除錯控制檯”選項卡中,您將看到指示偵錯程式已啟動並正在執行的輸出。

  • 編輯器會高亮顯示你在啟動偵錯程式之前設定斷點的行

    Initial breakpoint

  • 活動欄中的“執行和除錯”檢視顯示除錯資訊。

  • 程式碼編輯器頂部會出現一個除錯控制面板。你可以透過抓取左側的點來在螢幕上移動它。

    Debugging controls

單步除錯程式碼

現在你已準備好開始單步除錯程式碼。

  1. 選擇除錯控制面板中的“跳過”圖示,以便突出顯示 for (const string& word : msg) 語句。

    Step over button

    跳過命令會跳過建立和初始化 msg 變數時呼叫的 vectorstring 類中的所有內部函式呼叫。請注意“變數”視窗中的變化。msg 的內容可見,因為該語句已完成。

  2. 再次按“跳過”前進到下一條語句(跳過初始化迴圈要執行的所有內部程式碼)。現在,“變數”視窗顯示有關迴圈變數的資訊。

  3. 再次按“跳過”以執行 cout 語句。

  4. 如果你願意,可以繼續按單步跳過,直到向量中的所有單詞都列印到控制檯。但如果你好奇,可以嘗試按單步進入按鈕來單步執行 C++ 標準庫中的原始碼!

設定監視

您可能希望在程式執行過程中跟蹤變數的值。您可以透過為變數設定“監視”來實現此目的。

  1. 在“監視”視窗中,選擇加號,然後在文字框中鍵入 word。這是迴圈變數的名稱。現在,在逐行執行迴圈時,檢視“監視”視窗。

    Watch window

    注意:監視變數的值僅在程式執行位於該變數的作用域內時才可用。例如,對於迴圈變數,該值僅在程式執行迴圈時才可用。

  2. 透過在迴圈前新增此語句來新增另一個監視:int i = 0;。然後,在迴圈內部新增此語句:++i;。現在,像上一步一樣為 i 新增監視。

  3. 當程式執行暫停時,您可以透過將滑鼠指標懸停在任何變數上來快速檢視其值。

    Mouse hover

使用 launch.json 自定義除錯

當你使用播放按鈕或 F5 進行除錯時,C++ 擴充套件會即時建立一個動態除錯配置。

在某些情況下,你可能希望自定義除錯配置,例如指定在執行時傳遞給程式的引數。你可以在 launch.json 檔案中定義自定義除錯配置。

要建立 launch.json,請從播放按鈕下拉選單中選擇新增除錯配置

Add debug configuration play button menu

然後,您將看到一個下拉列表,其中包含各種預定義的除錯配置。選擇“C/C++: clang++ 構建和除錯活動檔案”。 C++ 除錯配置下拉列表

VS Code 建立一個 launch.json 檔案,它看起來像這樣

{
  "configurations": [
    {
      "name": "C/C++: clang++ build and debug active file",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}/${fileBasenameNoExtension}",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${fileDirname}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "lldb",
      "preLaunchTask": "C/C++: clang++ build active file"
    }
  ],
  "version": "2.0.0"
}

program 設定指定您要除錯的程式。這裡設定為活動檔案資料夾 ${fileDirname} 和活動檔名 ${fileBasenameNoExtension},如果 helloworld.cpp 是活動檔案,則為 helloworldargs 屬性是要在執行時傳遞給程式的引數陣列。

預設情況下,C++ 擴充套件不會向原始碼新增任何斷點,並且 stopAtEntry 值設定為 false

stopAtEntry 值更改為 true,以便在開始除錯時讓偵錯程式在 main 方法處停止。

確保 preLaunchTask 值與 tasks.json 檔案中的構建任務的 label 匹配。

從現在開始,播放按鈕和 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++ 配置”頁面。

C++ configuration

Visual Studio Code 將這些設定放在 .vscode/c_cpp_properties.json 中。如果你直接開啟該檔案,它應該看起來像這樣

{
  "configurations": [
    {
      "name": "Mac",
      "includePath": ["${workspaceFolder}/**"],
      "defines": [],
      "macFrameworkPath": [
        "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
      ],
      "compilerPath": "/usr/bin/clang",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "intelliSenseMode": "macos-clang-arm64"
    }
  ],
  "version": 4
}

只有當您的程式包含工作區或標準庫路徑中不存在的標頭檔案時,才需要修改“包含路徑”設定。

編譯器路徑

該擴充套件使用 compilerPath 設定來推斷 C++ 標準庫標頭檔案的路徑。當擴充套件知道在哪裡可以找到這些檔案時,它就可以提供智慧補全和“轉到定義”導航等功能。

C/C++ 擴充套件會嘗試根據它在系統上找到的內容,將 compilerPath 填充為預設編譯器位置。compilerPath 的搜尋順序是:

  • 您的 PATH 中已知編譯器的名稱。編譯器在列表中的出現順序取決於您的 PATH。
  • 然後會搜尋硬編碼的 Xcode 路徑,例如 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/

有關更多資訊,請參閱 IntelliSense 配置文件

Mac 框架路徑

在“C/C++ 配置”螢幕上,向下滾動並展開“高階設定”,並確保“Mac 框架路徑”指向系統標頭檔案。例如:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks

故障排除

編譯器和連結錯誤

錯誤的最常見原因(例如 undefined _mainattempting to link with file built for unknown-unsupported file format 等)發生在您啟動構建或除錯時 helloworld.cpp 不是活動檔案。這是因為編譯器試圖編譯非原始碼的內容,例如您的 launch.jsontasks.jsonc_cpp_properties.json 檔案。

如果您看到有關“C++11 擴充套件”的構建錯誤,您可能尚未更新 tasks.json 構建任務以使用 clang++ 引數 --std=c++17。預設情況下,clang++ 使用 C++98 標準,該標準不支援 helloworld.cpp 中使用的初始化。請確保用 執行 helloworld.cpp 部分中提供的程式碼塊替換 tasks.json 檔案的全部內容。

終端無法啟動用於輸入

在 macOS Catalina 及更高版本上,您可能會遇到即使設定了 "externalConsole": true 也無法輸入的問題。會開啟一個終端視窗,但實際上不允許您鍵入任何輸入。

該問題目前正在 #5079 中跟蹤。

解決方法是讓 VS Code 啟動一次終端。您可以透過在 tasks.json 中新增並執行以下任務來實現:

{
  "label": "Open Terminal",
  "type": "shell",
  "command": "osascript -e 'tell application \"Terminal\"\ndo script \"echo hello\"\nend tell'",
  "problemMatcher": []
}

您可以使用“終端”>“執行任務...”並選擇“開啟終端”來執行此特定任務。

接受許可權請求後,外部控制檯應在除錯時出現。

後續步驟

© . This site is unofficial and not affiliated with Microsoft.