vs code基本使用以及總結
launch.json作用
這個文件配置了調試器的設置,允許你定義如何啟動和調試你的程序。這包括配置執行路徑、傳遞給程序的參數、環境變量以及特定語言或框架的調試器選項。
常用配置
"version": "0.2.0"
: 這是配置文件格式的版本號,通知 VS Code 使用特定的解析方式。"configurations": [...]
: 這個數組包含了一系列的調試配置,每個配置項允許您以不同的方式啟動和調試程序。
對于數組中的單個配置對象:
"name": "(gdb) 啟動"
: 這是調試配置的名稱,您會在啟動調試會話時在 VS Code 的調試菜單中看到它。"type": "cppdbg"
: 指定調試器類型,cppdbg
是 C/C++ 的調試器。"request": "launch"
: 表示這是一個啟動(而不是附加)調試會話的請求。"program": "${workspaceFolder}/a.exe"
: 指定了要調試的程序的路徑。${workspaceFolder}
是一個變量,指的是您的工作區目錄。"args": []
: 為程序指定命令行參數的數組,這里為空,意味著不傳遞任何參數。"stopAtEntry": false
: 指定調試器是否在程序入口點停止,這里設置為false
,表示不在入口點停止。"cwd": "${workspaceFolder}"
: 設置程序的當前工作目錄,這里也使用了**${workspaceFolder}
**變量。"environment": []
: 允許您指定環境變量的數組,這里為空,意味著使用默認環境。"externalConsole": false
: 指定是否為調試的程序使用外部控制臺窗口。設置為**false
**表示不使用外部控制臺。"MIMode": "gdb"
: 指定使用的調試器接口,這里是 GDB(GNU調試器)。"miDebuggerPath": "D:\\Program Files (x86)\\msys64\\mingw64\\bin\\gdb.exe"
: 提供 GDB 調試器可執行文件的路徑。"setupCommands": [...]
: 包含一組在調試會話開始時自動執行的 GDB 命令。"description"
: 提供命令的描述。"text"
: 實際要執行的 GDB 命令文本。"ignoreFailures": true
: 指定如果這個命令失敗是否應該忽略錯誤。
關于 “request”
在 launch.json
配置中的 "request"
字段定義了調試會話的類型。它有兩個主要的值:
"launch"
:告訴調試器啟動一個程序實例,適用于當你想從頭開始調試程序時。"attach"
:告訴調試器附加到一個已經運行的程序實例,適用于調試已經啟動的進程。
某些調試器和語言擴展可能支持更多的 "request"
類型,例如 "test"
或者其他自定義請求,但 "launch"
和 "attach"
是最常見的。
- attach類型
-
介紹
attach類型,可以讓GDB鏈接到一個已經在運行的程序中進行調試,調試的手段與launch模式下一樣,包括設定斷點,查看變量等。但是“attach”模式進行調試的主要好處就是能夠在程序已經運行的情況下開始調試,而無需重新啟動程序。這在下列情況中特別有用:
- 程序已經運行:當您想要調試的程序已經在運行,并且不能或不方便重新啟動時。這可能是因為程序需要長時間運行才能到達需要調試的狀態,或者它正在處理實時數據。
- 生產環境的問題:特別是在生產環境中,有時候您可能無法重現問題,需要直接在生產服務器上進行調試。此時,“attach”模式允許您連接到生產服務器上的進程,直接進行調試。
- 服務和守護進程:對于服務和守護進程,這些程序通常由系統啟動,不容易從外部啟動調試會話。附加調試允許您連接到這些已經運行的服務進行調試。
- 遠程進程:對于在遠程服務器上運行的進程,您可以通過遠程調試工具附加到這些進程,而不需要在服務器上直接操作。
在“attach”模式下,調試器提供的功能(如設置斷點、查看變量值、單步執行等)與在“launch”模式下啟動調試會話時相同。所以,從調試功能上看,“attach”模式與“launch”模式提供了相同的調試能力,只是在操作上有所不同。
-
步驟
讓我們以一個簡單的C++程序為例,來說明如何使用**
attach
**模式進行調試。假設你有一個長時間運行的C++應用程序,該程序偶爾會出現一個難以復現的錯誤,你希望在錯誤發生時附加調試器來觀察發生了什么首先,這是你的C++程序(假設文件名為
main.cpp
):#include <iostream>#include <thread>#include <chrono>void longRunningFunction() {for (int i = 0; i < 100; ++i) {std::this_thread::sleep_for(std::chrono::seconds(1));std::cout << "Running iteration " << i << std::endl;} }int main() {std::cout << "Process ID: " << getpid() << std::endl;longRunningFunction();return 0; }
這個程序會運行一個循環,每秒打印一次輸出。我們在輸出中包含了進程ID,這樣你就可以知道應該附加到哪個進程。
你可以編譯這個程序,然后運行它:
g++ main.cpp -o myapp -std=c++11 -pthread ./myapp
程序會開始運行并打印它的進程ID。
現在,打開VS Code,創建一個
launch.json
文件,并添加一個attach
配置:{"version": "0.2.0","configurations": [{"name": "C++ Attach","type": "cppdbg","request": "attach","program": "${workspaceFolder}/myapp","processId": "${command:pickProcess}","MIMode": "gdb","miDebuggerPath": "/usr/bin/gdb"}] }
注意
processId
設置為${command:pickProcess}
,這意味著VS Code會在你啟動調試會話時彈出一個窗口,讓你選擇一個進程ID來附加。當你準備好附加調試器時:
- 在VS Code中選擇“Run” > “Start Debugging”或按F5。
- 選擇“C++ Attach”配置。
- VS Code會彈出一個窗口讓你選擇一個進程。輸入或選擇你的應用程序的進程ID。
- 現在調試器附加到了你的應用程序,你可以設置斷點、檢查變量、查看調用堆棧等。
通過這種方式,你可以在程序運行到特定狀態時開始調試,而不需要從頭開始運行程序。這對于調試生產環境中的服務或長時間運行的進程特別有用。
-
關于變量 ${workspaceFolder}
${workspaceFolder}
是 VS Code 中的一個內置變量,代表當前打開的工作區(workspace)的根文件夾路徑。這個變量的值是自動設置的,基于你用 VS Code 打開的文件夾。
- 如果你通過 “File > Open Folder” 打開了一個文件夾,那么這個文件夾就是
${workspaceFolder}
的值。 - 如果你是在一個多根工作區環境中(即打開了多個文件夾),
${workspaceFolder}
表示當前活動文件所在的根文件夾。
你不能直接在 launch.json
文件中更改 ${workspaceFolder}
變量的值,因為它是由 VS Code 根據你打開的工作區動態確定的。
如果需要特定的工作目錄,你可以直接在 "cwd"
字段中指定路徑,而不是使用 ${workspaceFolder}
變量,例如:
"cwd": "D:\\MyProjects\\MyApp"
請記住,當你使用特定路徑而不是 ${workspaceFolder}
變量時,你的配置將不再是可移植的,這意味著在不同的機器或環境中可能需要手動調整路徑。
還有哪些調試器
調試器是用來提供運行時程序調試功能的軟件工具。不同的編程語言和開發環境支持不同的調試器。以下是一些常見的調試器:
- GDB (GNU Debugger):用于調試C和C++語言編寫的程序。
- LLDB:LLVM項目的調試器,也主要用于C和C++語言。
- Visual Studio 調試器:集成在Visual Studio IDE中,支持多種語言,包括C#、C++、VB.NET等。
- Xcode 調試器:集成在Xcode中,主要用于Objective-C和Swift語言。
- PDB (Python Debugger):用于調試Python程序。
- Node.js Inspector:用于調試Node.js應用程序。
關于多根工作區
將兩個獨立的項目(目錄是完全獨立的,配置也可以獨立),統一到一個工作區中,這種工作區就叫做多根工作區。
在這種多根工作區中,每個根目錄可以代表一個獨立的項目,它們在 VS Code 的界面中是并列顯示的,但都在同一個編輯器窗口中進行管理。
-
步驟
如果你想將兩個子項目配置為多根工作區的兩個獨立根目錄,你需要:
- 在VS Code中打開任意一個子文件夾作為工作區。
- 點擊“File”菜單,選擇“Add Folder to Workspace…”然后選擇另一個子文件夾。
- 通過“File”菜單選擇“Save Workspace As…”保存你的多根工作區配置。
這樣,你就有了一個包含兩個獨立項目的多根工作區,每個項目都可以有自己的配置,并且它們在VS Code的界面中是并列的。
-
優勢
- 集中管理:能夠在單個 VS Code 窗口中管理多個項目,而不需要為每個項目打開一個新的窗口。
- 共享配置:可以有一個共享的設置和擴展推薦,這對于涉及多個相關項目或服務的大型應用程序特別有用。
- 獨立配置:盡管有共享的設置,每個項目依然可以有自己的專屬配置,如特定的調試設置、任務和插件。
- 便捷的源碼操作:可以輕松地在項目之間拖放文件,或在不同項目的文件之間進行比較和引用。
- 提高工作效率:在多個項目之間切換非常方便,不需要重新打開或重新布局窗口。
- 搜索和導航:能夠跨所有打開的項目進行搜索和導航,這在處理多個庫或服務時特別有用。
- 版本控制:如果每個根目錄都是一個獨立的版本控制倉庫,VS Code可以同時顯示每個倉庫的源代碼管理狀態。
- 插件作用域:某些插件可以配置為只在特定的根目錄中運行,從而允許對插件的行為進行更精細的控制。
tasks.json
這個文件定義了任務(比如編譯,構建、測試或部署你的代碼),這些任務可以通過VS Code的命令面板執行。你可以配置任務來運行構建系統、調用外部腳本、運行測試套件等。
常用配置
"type": "cppbuild"
: 指定任務的類型。這里是**cppbuild
**,表示這是一個C++編譯任務。"label": "C/C++: g++.exe 生成活動文件"
: 這是任務的名稱,顯示在VS Code的任務運行菜單中。這個名字可以是任意的,描述了任務的作用。"command": "D:\\Program Files (x86)\\msys64\\mingw64\\bin\\g++.exe"
: 指定執行的命令,這里是g++編譯器的完整路徑。這條命令用于編譯C++源代碼文件。"args"
: 這是傳遞給命令的參數列表。"-fdiagnostics-color=always"
: 強制編譯器總是在診斷輸出(比如錯誤和警告)中使用顏色,這可以幫助識別問題。"-g"
: 在生成的可執行文件中包含調試信息,這對于后續的調試非常重要。"${file}"
: 這是一個變量,代表當前在VS Code中打開的文件。這意味著這個任務將編譯當前文件。"-o"
: 指定輸出文件的選項。"${fileDirname}\\${fileBasenameNoExtension}.exe"
: 這是輸出文件的路徑和名稱。它使用了幾個變量來構建路徑:**${fileDirname}
是當前文件的目錄,${fileBasenameNoExtension}
是不帶擴展名的文件名。最后,加上.exe
**擴展名來生成Windows可執行文件。
"options"
: 包含了額外的配置選項。"cwd": "${fileDirname}"
: 指定任務運行時的當前工作目錄。**${fileDirname}
**變量使得g++在源文件所在的目錄下執行。
"problemMatcher"
: 用于將編譯器輸出中的錯誤和警告與VS Code的問題面板關聯起來。**"$gcc"
**是一個預定義的問題匹配器,適用于GCC/G++編譯器的輸出。"group"
: 定義了任務的分組信息。"kind": "build"
: 表示這個任務是一個構建任務。"isDefault": true
: 表示這是默認的構建任務,當你按下**Ctrl+Shift+B
(或者Cmd+Shift+B
**在macOS上)時會執行這個任務。
"detail": "調試器生成的任務。"
: 提供了任務的詳細描述。"version": "2.0.0"
: 指定了任務配置的版本號。
c_cpp_properties.json
這個文件用于配置C/C++插件的屬性,比如包括哪些頭文件路徑(includePath)、定義哪些預處理器宏(defines)、使用哪種C/C++標準(cStandard/cppStandard)、選擇哪個編譯器路徑(compilerPath)等。它幫助VS Code正確地為代碼提供智能提示、代碼導航和語法高亮。
settings.json
這個文件包含了編輯器的工作區設置,比如字體大小、縮進大小、是否啟用自動保存等。這些設置可以覆蓋全局用戶設置,只對當前工作區有效。
常見問題
當點擊“調試”/“運行”時發生了什么?
- 調試:當你點擊“調試”,VS Code會啟動配置在**
launch.json
**文件中的調試器(比如GDB或LLDB,取決于你的配置和使用的平臺)。調試器會啟動編譯出的程序,并在指定的斷點處暫停執行,讓你可以查看變量的值、執行堆棧、內存狀態等。對于C++程序,確實常用GDB或LLDB作為調試器。 - 運行:點擊“運行”通常意味著直接啟動編譯出的程序,而不通過調試器。在VS Code中,這可能通過配置在**
tasks.json
**中的任務來實現,比如一個編譯任務后跟一個執行編譯結果的任務。
task.json中只指定了編譯器gcc,沒有指定鏈接器,那系統怎么知道使用哪個鏈接器呢?g++有鏈接的功能么?
是的,g++
實際上不僅僅是一個編譯器,它同時也具備鏈接器的功能。當你使用 g++
來編譯C++程序時,g++
會在編譯源代碼文件(.cpp
文件)生成目標文件(.o
或 .obj
文件)之后,自動調用鏈接器將這些目標文件鏈接成最終的可執行文件。
在 tasks.json
中,當你指定了 g++.exe
作為 command
并提供了一系列的 args
(參數)時,如果參數中包括了多個源文件或至少一個目標文件,g++
會在編譯完成后自動執行鏈接步驟。這個過程是自動的,基于你提供的命令行參數,g++
能夠理解你的意圖是僅編譯、僅鏈接,還是編譯后鏈接。
鏈接器的選擇
g++
調用的鏈接器通常是 GNU 的 ld
,這是 GNU 項目的標準鏈接器。在大多數Linux系統和使用GCC的環境中,ld
被用作默認的鏈接器。g++
會傳遞適當的參數給 ld
,以確保C++標準庫和其他庫被正確鏈接。
在Windows上,當使用MinGW(一個Windows平臺上的GCC移植)時,g++
同樣會調用 ld
,但配置為支持Windows平臺和PE(可執行文件)格式。
如何知道使用了哪個鏈接器
雖然在 tasks.json
中沒有直接指定鏈接器,但通過查看 g++
的文檔和命令行參數(使用 g++ -v
來查看詳細的編譯和鏈接過程),你可以得知 g++
在背后使用了哪個鏈接器以及如何調用它。
總結
g++
在編譯C++程序時同時承擔了編譯器和鏈接器的角色。- 通過在
tasks.json
中配置g++
命令和參數,g++
會自動處理編譯和鏈接步驟。 - 鏈接過程通常是隱式進行的,
g++
會根據提供的源文件和目標文件參數自動執行鏈接。 g++
默認使用的鏈接器是 GNU 的ld
,它被配置為支持特定平臺的鏈接需求。
為什么不需要像java去指定庫的環境變量?
C++編譯器(如g++或clang++)通常已經配置好了標準庫的路徑,所以你不需要像設置JDK那樣設置環境變量。當你編譯一個程序時,編譯器知道如何找到它需要的庫。
不同的編譯器通常會配有它們自己的標準 C++ 庫實現,或者選擇使用現有的某個版本。這些庫實現了 C++ 標準中定義的功能,包括數據結構、算法、輸入/輸出操作等。這些庫之間在性能、擴展功能和兼容性方面可能會有所不同。
幾個常見的 C++ 標準庫實現包括:
- libstdc++: GNU 編譯器集合(GCC)所使用的 C++ 標準庫。它廣泛用于 Linux 系統和其他 Unix-like 系統,以及使用 MinGW 或 Cygwin 在 Windows 上的 GCC 版本。
- libc++: LLVM 項目的 C++ 標準庫實現,與 Clang 編譯器一起使用。它旨在高度遵循 C++ 標準,并且在性能和內存占用方面進行了優化。
- Microsoft STL (MS STL): Microsoft Visual C++(MSVC)編譯器使用的 C++ 標準庫。它是 Visual Studio 開發環境的一部分,并且專門為 Windows 平臺優化。
- STLPort: 一個獨立的、跨平臺的 C++ 標準庫實現,可以用于不同的編譯器和平臺。
這些庫之間的主要不同可能包括:
- 性能: 某些實現可能在特定類型的操作上進行了優化,比如字符串處理或容器操作。
- 擴展: 雖然所有標準庫都實現了 C++ 標準中定義的接口,但某些庫可能提供額外的非標準擴展。
- 兼容性: 特定的庫版本可能支持特定版本的 C++ 標準(如 C++11、C++14、C++17、C++20)。
- 平臺支持: 一些庫可能針對特定操作系統或硬件架構進行了特別的調整和優化。
- 錯誤處理: 不同的庫可能在出現異常或錯誤時有不同的行為。
- 調試支持: 在調試模式下,一些庫提供額外的檢查或調試信息。
選擇哪個標準庫實現,通常取決于所使用的編譯器和目標平臺。大多數情況下,開發者會使用默認配套的標準庫,因為它通常是為特定編譯器或平臺優化過的。然而,在某些跨平臺項目中,可能會選擇特定的標準庫實現來確保一致的行為。
如果你使用的是第三方庫,那么你可能需要指定這些庫的路徑(使用-I
來指定頭文件路徑,使用-L
和-l
來指定庫文件的路徑和名稱)。
task中設置頭文件引用
"tasks": [{"type": "cppbuild","label": "C/C++: g++.exe 生成活動文件","command": "D:\\Program Files (x86)\\msys64\\mingw64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g","${workspaceFolder}\\main.cpp","${workspaceFolder}\\testNUllPointer.cpp","-I","${workspaceFolder}/include","-o","${fileDirname}\\${fileBasenameNoExtension}.exe"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true},"detail": "調試器生成的任務。"}],
如果要編譯多個源文件話,怎么設置呢?
要編譯多個源文件到一個目標文件,您需要在 tasks.json
的 args
部分列出所有的源文件,然后指定輸出的目標文件名。由于 ${file}
變量僅代表當前活動文件,它不能直接用來指定多個源文件。相反,您需要手動指定源文件的路徑,或者使用通配符(取決于您的構建系統是否支持它)。
假設您的項目有兩個源文件 main.cpp
和 helper.cpp
,并且您想將它們編譯到一個名為 app.exe
的目標文件中。下面是如何設置 tasks.json
文件的示例:
{"tasks": [{"type": "cppbuild","label": "Build app.exe","command": "D:\\Program Files (x86)\\msys64\\mingw64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g",**"${workspaceFolder}\\main.cpp"**,**"${workspaceFolder}\\helper.cpp",**"-o",**"${workspaceFolder}\\app.exe"**],"options": {"cwd": "${workspaceFolder}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true},"detail": "編譯 main.cpp 和 helper.cpp 到 app.exe。"}],"version": "2.0.0"
}
請注意幾個關鍵點:
"args"
: 這里您列出了所有要編譯的源文件的路徑。${workspaceFolder}
變量代表當前工作區的根目錄,確保無論當前活動文件是什么,都會編譯指定的源文件。- 最后的
o
參數后面指定了輸出的目標文件名和路徑。
這種方法適用于小到中型的項目,其中只有少數幾個源文件需要編譯。對于更大的項目,手動列出所有源文件可能變得不實用。在這種情況下,您可能需要使用一個更高級的構建系統(如 Make、CMake、MSBuild 等),它可以自動處理源文件的發現和管理編譯依賴關系。
如果您的構建系統或命令行工具支持通配符,您也可以使用類似 "${workspaceFolder}\\*.cpp"
的方式來指定源文件,但請注意,并非所有工具和環境都支持這種語法。
參考
https://code.visualstudio.com/docs/cpp/config-mingw