Windows配置VSCode+CMake+Ninja+Boost.Test的C++開發環境(教程詳解)
平時習慣了在Linux環境寫C++,有時候切換到Windows想繼續在同一個專案上工作,重新配置環境總是很麻煩。雖然Windows下用Visual Studio寫C++只需要雙擊個圖示,但我還是想折騰一下VS Code的環境配置。原因主要有兩點:一是個人習慣上各種語言都在VS Code裡面寫,利用Git同步程式碼可以很方便地在不同平臺開發同一個專案;二是有些情形下無法使用圖形化介面,比如為Git配置CI(持續性整合)時顯然不能用Visual Studio這個圖形化的IDE來執行Windows環境的測試。
本文涉及的環境和工具版本:
- Windows 10
- VS Code 1.45.0
- C/C++(ms-vscode.cpptools)外掛0.28.0.insider3
- CMake(twxs.cmake)外掛0.0.17
- CMake Tools(ms-vscode.cmake-tools)外掛1.3.1
- Visual Studio IntelliCode(visualstudioexptteam.vscodeintellicode)外掛1.2.7
- Visual Studio Community 2019 (需要呼叫VS提供的MSVC編譯工具,以及相應的標頭檔案和庫檔案)
- CMake 3.17.2
- Ninja 1.10.0
- Boost 1.73.0
主要內容
1 建立C++專案
2 安裝Visual Studio
3 安裝CMake和Ninja
4 下載和編譯Boost
4.1 Command Prompt的使用
4.2 編譯Boost
5 命令列編譯和測試
6 配置VS Code
6.1 settings.json
6.2 c_cpp_properties.json
6.3 tasks.json
6.4 launch.json
6.5 CMakeLists.txt
6.6 編譯、測試和除錯
建立C++專案
VSCode及外掛的安裝過程本文暫不介紹,這裡直接給出專案的檔案結構和程式碼。
專案結構如下。 .vscode
資料夾裡面的3個json檔案用來配置VS Code,第二個資料夾裡面包含對LeetCode某一個問題的解答( solution.hpp
solution.cpp
), solution_test.cpp
用來執行單元測試。最下面的 CMakeLists.txt
檔案用來配置CMake,給出專案的編譯規則。
這裡先給出C++部分的程式碼,其他檔案的內容會在後面給出。
solution.hpp
#ifndef SOLUTION_HEADER #define SOLUTION_HEADER #include <iostream> #include <vector> #include <unordered_set> using namespace std; class Solution { public: vector<int> intersection(vector<int>& nums1,vector<int>& nums2); }; #endif solution.cpp #include "solution.hpp" static auto x = []() { // turn off sync std::ios::sync_with_stdio(false); // untie in/out streams cin.tie(NULL); return 0; }(); vector<int> Solution::intersection(vector<int>& nums1,vector<int>& nums2) { if (nums1.size() > nums2.size()) swap(nums1,nums2); unordered_set<int> A(nums1.begin(),nums1.end()),C; for (auto& i : nums2) { if (A.find(i) != A.end()) C.insert(i); } return vector<int>(C.begin(),C.end()); }
solution.cpp
#include "solution.hpp" static auto x = []() { // turn off sync std::ios::sync_with_stdio(false); // untie in/out streams cin.tie(NULL); return 0; }(); vector<int> Solution::intersection(vector<int>& nums1,C.end()); }
solution_test.cpp
#define BOOST_TEST_MODULE SolutionTest #include "solution.hpp" #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_SUITE(SolutionSuite) BOOST_AUTO_TEST_CASE(PlainTest1) { vector<int> nums1{1,2,1}; vector<int> nums2{2,2}; vector<int> results = Solution().intersection(nums1,nums2); vector<int> expected{2}; sort(results.begin(),results.end()); sort(expected.begin(),expected.end()); BOOST_CHECK_EQUAL_COLLECTIONS(results.begin(),results.end(),expected.begin(),expected.end()); } BOOST_AUTO_TEST_CASE(PlainTest2) { vector<int> nums1{4,9,5}; vector<int> nums2{9,4,8,4}; vector<int> results = Solution().intersection(nums1,nums2); vector<int> expected{9,4}; sort(results.begin(),expected.end()); } BOOST_AUTO_TEST_SUITE_END()
安裝Visual Studio
這裡不詳述VS的安裝過程,只是提示一下需要安裝的元件。
需要注意Visual Studio Community 2019 Preview版本在編譯Boost不能被正確識別,需要安裝正式版。Visual Studio Community 2017/2019 兩個版本我都試驗過,這裡以2019版本為例。
只需要安裝“使用C++的桌面開發”這一套元件就可以了。
安裝CMake和Ninja
CMake可以下載名為cmake-3.17.2-win64-x64.msi 的安裝包來安裝,Ninja 下載之後只有一個可執行檔案,可以隨意放在一個目錄下。
安裝過程暫不詳述,只需要注意安裝完成之後要設定一下環境變數。
設定好環境變數之後,可以重新開啟命令列工具或終端,檢查一下CMake和Ninja的版本,看是否設定成功。
下載和編譯Boost
Boost可以從這個連結下載: https://dl.bintray.com/boostorg/release/1.73.0/source/ ,然後解壓到某個目錄下。
Boost本身是header-only的,即大部分情況下只需要包含其標頭檔案就能直接呼叫。但為了便於把我們自己的程式連結到Boost的單元測試模組(Boost.Test),這裡需要編譯一下Boost,產生靜態庫檔案。
Command Prompt的使用
由於我們之前已經安裝了Visual Studio以及在Windows平臺編譯C++所需的編譯工具和依賴庫,所以我們可以直接利用VS提供的環境來編譯Boost。
在開始選單的“Visual Studio 2019”目錄下可以發現幾個命令列工具,我們可以開啟一個名為“x64 Native Tools Command Prompt for VS 2019”的命令列工具,這個圖示在硬碟上對應到 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
這個指令碼。該指令碼的作用是把MSVC和Windows SDK的包含路徑、庫路徑等新增到環境變數,然後開啟一個cmd命令列。所以在這個cmd執行期間能夠直接檢測到編譯C++所需的所有依賴項。
我們可以試著在這個cmd當中輸入 SET
,檢視已經生效的所有環境變數。
利用這些資訊,我們在常規的cmd或PowerShell裡也能正常編譯C++程式碼。具體的過程會在後面介紹。
預設cmd的字型有點難看,我個人習慣在Windows Terminal 裡面開一個cmd終端,然後執行下面的命令:
> "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
這就可以讓我們的新終端也能夠檢測到MSVC環境,如下圖所示。
編譯Boost
然後, cd
到Boost的根目錄,執行下面的命令:
> bootstrap.bat > b2 --prefix=build install
等待編譯完成之後,在 build\lib
目錄下會出現一大堆 .lib
檔案,我們只會用到 libboost_unit_test_framework-vc142-mt-gd-x64-1_73.lib
這一個檔案。
當然,如果只想編譯單元測試模組,可以用下面的命令:
> b2 address-model=64 architecture=x86 --with-test link=static --prefix=build install
命令列編譯和測試
這裡我們先在命令列裡編譯C++專案,並執行單元測試。 cd
到專案目錄下,然後執行以下命令:
> mkdir build > cd build > cmake -G "Ninja" .. > ninja test_main > test_main.exe
在Windows平臺上,生成工具可以選擇VS提供的NMAKE,也可以用Ninja。微軟的NMAKE類似於Linux平臺的make工具。按照這個 視訊 的介紹,Ninja的編譯速度要比NMAKE快一些。
可以發現,在 vcvars64.bat
所提供的環境下,使用的是VS所安裝的CMake和Ninja,版本號比我們自己安裝都要老一些。下面我們介紹如何在VS Code中配置C++的編譯和測試環境。
配置VS Code
settings.json
開啟VS Code的設定,在 settings.json
中新增下面幾行內容,可以起到類似 vcvars64.bat
的作用:
{ "terminal.integrated.shell.windows": "C:\\Windows\\System32\\cmd.exe","terminal.integrated.env.windows": { "PATH" : "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.18362.0\\x64;E:\\CMake\\bin;E:\\dev-lib\\ninja","INCLUDE": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\include;C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt","LIB": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\ATLMFC\\lib\\x64;C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\lib\\x64;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\ucrt\\x64;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\um\\x64" },"cmake.cmakePath": "E:\\CMake\\bin\\cmake.exe" }
c_cpp_properties.json
這裡給出Linux和Windows兩個平臺的配置。
{ "configurations": [ { "name": "Linux","includePath": [ "${workspaceFolder}/**" ],"defines": [],"compilerPath": "/usr/bin/clang++","cStandard": "c11","cppStandard": "c++17","intelliSenseMode": "clang-x64" },{ "name": "Win32","includePath": [ "${workspaceFolder}/**","C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\include","C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\ATLMFC\\include","C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt","C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared","C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um","C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt","C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\cppwinrt","E:\\dev-lib\\boost_1_73_0" ],"defines": ["_DEBUG","UNICODE","_UNICODE"],"windowsSdkVersion": "10.0.18362.0","compilerPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Hostx64\\x64\\cl.exe","intelliSenseMode": "msvc-x64" } ],"version": 4 }
tasks.json
前兩個 task
是Linux環境的(第一個是清空build目錄,第二個是配置CMake),第三個 task
是Windows下配置CMake的。
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0","tasks": [ { "label": "clean","type": "shell","command": "rm -r build/*" },{ "label": "configure","command": "cmake","args": [ "--no-warn-unused-cli","-DCMAKE_C_COMPILER=/usr/bin/clang","-DCMAKE_CXX_COMPILER=/usr/bin/clang++","-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE","-DCMAKE_BUILD_TYPE=Debug","-H${workspaceFolder}","-B${workspaceFolder}/build","-G'Unix Makefiles'" ] },{ "label": "MSVC configure","args": [ "-H${workspaceFolder}","-GNinja" ] } ] }
launch.json
第一個是在Linux用 gdb
除錯,第二個是在Linux下用 lldb
除錯,第三個是在Windows用MSVC的 cl.exe
除錯。
{ "version": "0.2.0","configurations": [ { "name": "(gdb) Launch","type": "cppdbg","request": "launch","program": "${workspaceFolder}/build/test_main","args": [],"stopAtEntry": false,"cwd": "${workspaceFolder}","environment": [],"externalConsole": true,"MIMode": "gdb","setupCommands": [ { "description": "Enable pretty-printing for gdb","text": "-enable-pretty-printing","ignoreFailures": true } ] },{ "name": "(lldb) Launch","type": "lldb",},{ "name": "(cl) Launch","type": "cppvsdbg","program": "${workspaceFolder}\\build\\test_main.exe","externalConsole": false,} ] }
CMakeLists.txt
這個CMake指令碼也是跨平臺的,自動識別Linux或Windows,然後執行相應的連結。
cmake_minimum_required (VERSION 3.5) project(leetcode) set(PROBLEM_NAME "349-Intersection-of-Two-Arrays-set") set(CMAKE_CXX_STANDARD 14) set(SOLUTION_SOURCES ${PROJECT_SOURCE_DIR}/${PROBLEM_NAME}/solution.cpp) add_library(solution STATIC ${SOLUTION_SOURCES}) enable_testing() set(TEST_SOURCES ${PROJECT_SOURCE_DIR}/${PROBLEM_NAME}/solution_test.cpp) set(TEST_LIBS solution) add_executable(test_main ${TEST_SOURCES}) if(WIN32) message(STATUS "Detected Windows platform") set(BOOST_ROOT E:\\dev-lib\\boost_1_73_0) set(BOOST_LIBRARYDIR E:\\dev-lib\\boost_1_73_0\\build\\lib) set(Boost_USE_STATIC_LIBS ON) find_package(Boost REQUIRED COMPONENTS unit_test_framework) target_link_libraries(test_main PRIVATE ${TEST_LIBS} Boost::boost Boost::unit_test_framework) elseif(UNIX) message(STATUS "Detected UNIX platform") find_package(Boost REQUIRED COMPONENTS unit_test_framework) add_library(boost_unit_test_framework STATIC IMPORTED) set_target_properties(boost_unit_test_framework PROPERTIES IMPORTED_LOCATION /usr/lib/libboost_unit_test_framework.a) target_link_libraries(test_main ${TEST_LIBS} boost_unit_test_framework) else() message(FATAL_ERROR "Unsupported platform") endif() add_test(solution_test test_main COMMAND test_main)
編譯、測試和除錯
按快捷鍵 Ctrl
+ Shift
+ P
,然後就可以輸入我們之前定義的不同命令了:
- “CMake: Configure” – 配置CMake
- “CMake: Build” – 編譯專案
- “CMake: Run tests” – 執行測試
- “Tasks: Run task -> MSVC configure” – 以呼叫Task的方式配置CMake
單元測試的效果如下圖所示:
除錯的效果如下圖所示:
完整的專案程式碼在我的GitHub上: https://github.com/johnhany/leetcode 。關於Linux平臺下C++開發環境的配置可以參考 《Ubuntu計算機視覺開發環境配置(Python/C++)》 。
總結
到此這篇關於Windows配置VSCode+CMake+Ninja+Boost.Test的C++開發環境(教程詳解)的文章就介紹到這了,更多相關VScode配置C/C++環境內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!