安裝套件 
注意: GDB 12.09 版本在VSCode除錯的時候會有錯誤,可以參考下面方式將GDB升級到12.10以上版本升級GDB GDB issue  {: .prompt-warning  }
 
安裝CMake 直接用sudo apt install cmake,安裝的版本會比較舊,因此如果想用CMake最新的功能可以按照官方網站的安裝方式 ,安裝後我們可以測試一下CMake安裝成功,在這裡我們CMake的版本至少要大於3.15 
 
編譯C++檔 用以下指令建立一個專案資料夾,最後一行code .會直接打開一個新的VScode並且以這個資料夾作為工作目錄
1 2 3 4 5 mkdir projects cd projects mkdir helloworld cd helloworld code . 
 
在helloworld資料夾建立helloworld.cpp檔案並且寫入以下程式碼,然後按下編譯按鈕,並且選擇g++作為編譯器(如下圖所示)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #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 ; } 
 
 {: w=”700” h=”400” } {: w=”700” h=”400” }
成功編譯後,你會在Terminal看到程式成功輸出文字 {: w=”700” h=”400” }
第一次按下執行compiler後,VScode會幫你建立一個.vscode資料夾和一個,tasks.json。或是你可以自己建立一個.vscode資料夾並且放入tasks.json。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 {     "tasks" :  [          {              "type" :  "cppbuild" ,              "label" :  "C/C++: gcc-9 build active file" ,              "command" :  "/usr/bin/gcc-9" ,              "args" :  [                  "-fdiagnostics-color=always" ,                  "-g" ,                  "${file}" ,                  "-o" ,                  "${fileDirname}/${fileBasenameNoExtension}"              ] ,              "options" :  {                  "cwd" :  "${fileDirname}"              } ,              "problemMatcher" :  [                  "$gcc"              ] ,              "group" :  {                  "kind" :  "build" ,                  "isDefault" :  true              } ,              "detail" :  "Task generated by Debugger."          }      ] ,      "version" :  "2.0.0"  } 
 
{: file=’tasks.json’}
在這個資料夾下可以有三種檔案,每個檔案各有自己的用處,關於tasks.json詳細設定可以參考這裡 
tasks.json (compiler build settings) 
launch.json (debugger settings) 
c_cpp_properties.json (compiler path and IntelliSense settings) 
 
在tasks.json裡面有幾個的比較重要的點
args是給GCC的參數,要符合GCC參數的順序 
在這裡我們用${file}這個變數告訴GCC目前打開的檔案讓他編譯 
${fileDirname}這個變數告訴GCC目前的資料夾位置,讓他在這個位置產生我們的執行檔 
${fileBasenameNoExtension}變數取出目前開啟的檔名但是不包含副檔名,我們用這個名字作為我們的執行檔名,也就是helloworld 
label會顯示在task清單 detail 會顯示在task清單的詳細描述。先按下Ctrl+P並且輸入task (task後面有空白),就會顯示task清單,包含我們建立的task(如下圖所示) 
如果有多個task,可以利用group裡面isDefault屬性設定預設task 
 
 {: w=”700” h=”400” }
除錯、設中斷點 
在程式碼下一個中斷點,並且點及旁邊的執行按鈕並且選擇Debug就可以開始除錯了 {: w=”700” h=”400” } {: w=”700” h=”400” } {: w=”350” h=”200” } 
 
設定在啟動程式時傳入參數給程式 如果像在啟動程式時傳入一些參數,可以利用launch.json,要建立launch.json只需要案價旁邊的齒輪並選擇G++,VSCode就會自動幫你建立一份 {: w=”350” h=”200” } {: w=”700” h=”400” }  
在launch.json裡面有幾個的比較重要的點
program是要執行的執行檔名稱,也就是我們編譯後產生的helloworld檔 
args是執行時要傳給執行檔  的參數 
 
C/C++的其他設定 通常編寫C/C++的時候也會用到很多函式庫,我們可以指定這些函式庫的路徑讓VSCode的Intelligence Scope懂這些函式庫。 首先按下Ctrl+Shift+P並且輸入C/C++,按下C/C++: Edit Configurations (UI),後VSCode會幫我們產生一個c_cpp_properties.json。 在Include path的地方加入我們要包含的路徑。或者我們也可以在c_cpp_properties.jsonconfigurations下的includePath直接做修改
 {: w=”700” h=”400” }  
g++ include OpenCV函式庫 首先我們先按照Linux安裝prebuild函式庫以OpenCV為例 這篇文章安裝prebuild的OpenCV library。 接下來建立一個ShowImage.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include  <opencv2/core.hpp>  #include  <opencv2/imgcodecs.hpp>  #include  <opencv2/highgui.hpp>  #include  <iostream>  using namespace cv; int  main () {     std ::string  image_path = samples::findFile("starry_night.jpg" );     Mat img = imread(image_path, IMREAD_COLOR);     if (img.empty())     {         std ::cout  << "Could not read the image: "  << image_path << std ::endl ;         return  1 ;     }     imshow("Display window" , img);     int  k = waitKey(0 );      if (k == 's' )     {         imwrite("starry_night.png" , img);     }     return  0 ; } 
 
{: file=’ShowImage.cpp’}
我們可以發現VSCode的Intelligence scope找不到OpenCV標頭檔而顯示紅色虛線。 {: w=”700” h=”400” }  
這時候我們需要修改前面步驟提到的c_cpp_properties.jsoninclude OpenCV的路徑就可以了,而因為我們是安裝prebuild的OpenCV,所以我們的標頭檔已經被安裝在/usr/include/opencv4/裡面,因此修改後的c_cpp_properties.json如下。我們在includePath的清單中加入了/usr/include/opencv4/**,之後你就可以看到Intelligence scope成功認出OpenCV,而且OpenCV的函示可以順利顯示說明文字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 {     "configurations" :  [          {              "name" :  "Linux" ,              "includePath" :  [                  "${workspaceFolder}/**" ,                  "/usr/include/opencv4/**"               ] ,              "defines" :  [ ] ,              "compilerPath" :  "/usr/bin/gcc" ,              "cStandard" :  "gnu17" ,              "cppStandard" :  "gnu++17" ,              "intelliSenseMode" :  "linux-gcc-x64"          }      ] ,      "version" :  4  } 
 
{: file=’c_cpp_properties.json’} {: w=”700” h=”400” }  
不過這時候g++依然不知道OpenCV的標頭檔在哪裡,所以如果直接編譯還是會出錯。
pkg-config幫我們列出全部的標頭檔位置和opencv的名稱 標頭檔路徑只需要加上g++選項-I/usr/include/opencv4就可以了,不過如果要把所有用到的library都手動寫出來實在很麻煩,這時候pkg-config可以幫我們把全部的opencv library全部列出來,我們可以試看看在終端機輸入下面指令pkg-config --libs --cflags opencv4(如果安裝的是opencv 2.x或3.x要輸入pkg-config --libs --cflags opencv),終端機的回應應該會長的像下面這樣。
1 2 $ pkg-config --libs --cflags opencv4 -I/usr/include/opencv4 -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_hfs -lopencv_img_hash -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_shape -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_highgui -lopencv_datasets -lopencv_text -lopencv_plot -lopencv_ml -lopencv_videostab -lopencv_videoio -lopencv_viz -lopencv_wechat_qrcode -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core 
 
我們可以發現回傳的文字可以直接當成g++的選項來用,因此我們修改tasks.json,在給g++的參數args的list加入
1 "`pkg-config --libs --cflags opencv4`" 
 
改好後tasks.json如下,注意pkg-config --libs --cflags opencv4被兩個引號包圍,因為原本g++的指令是長這樣
1 /usr/bin/g++ -g main.cpp -o main `pkg-config --libs --cflags opencv4` 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 {     "tasks" :  [          {              "type" :  "cppbuild" ,              "label" :  "C/C++: g++ build active file" ,              "command" :  "/usr/bin/g++" ,              "args" :  [                  "-fdiagnostics-color=always" ,                  "-g" ,                  "${file}" ,                  "-o" ,                  "${fileDirname}/${fileBasenameNoExtension}" ,                  "`pkg-config --libs --cflags opencv4`"              ] ,              "options" :  {                  "cwd" :  "${fileDirname}"              } ,              "problemMatcher" :  [                  "$gcc"              ] ,              "group" :  {                  "kind" :  "build" ,                  "isDefault" :  true              } ,              "detail" :  "Task generated by Debugger."          }      ] ,      "version" :  "2.0.0"  } 
 
{: file=’tasks.json’}
接下來VSCode就可以順利編譯程式並產生執行檔了。
用CMake管理跨Windows和Linux的C++專案以Darknet為例 如果開發團隊中有人用Windows OS開發,有人用Linux OS開發,而Windows的人只熟悉Visual Studio。這時候要一起合作完成專案在編譯的時候就會遇到困難。CMake跨平台的專案產生器就是專門解決這個問題。只要寫好一次CMake檔,他就可以在Windows幫你產生Visual Studio專案檔.sln,或是在Linux產生Makefile。很多時候我們會想要直接編譯別人的開源程式,這裡我們將以Darknet作為範例。開始這個範例之前你必須先在電腦上安裝好OPenCV 
下載Darknet 1 2 git clone  git@github.com:AlexeyAB/darknet.git cd  darknet
 
建立CMake的task.json 按下ctrl + shift + p並且輸入task,選擇Tasks: Configure task,然後再選擇CMake: build,就task設定就會產生在${workspaceFolder}/.vscode/tasks.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { 	"version" :  "2.0.0" ,  	"tasks" :  [  		{  			"type" :  "cmake" ,  			"label" :  "CMake: build" ,  			"command" :  "build" ,  			"targets" :  [  				"all"  			] ,  			"group" :  "build" ,  			"problemMatcher" :  [ ] ,  			"detail" :  "CMake template build task"  		}  	]  } 
 
{: file=’task.json’} 這個檔案會編譯所有的CMake Targets ,你也可以指定你想編譯的targets。
設定build參數 首先我們先查看Darknet有哪些CMake項可以設定,輸入cmake -S . -B build -LH就可以看到選項。在這個範例不想要使用CUDA,所以要把ENABLE_CUDA:BOOL=ON設為OFF。我們可以建立一個設定檔在${workspaceFolder}/.vscode/settings.json,並且輸入以下內容。更多其他的CMake設定可以在這裡 查到。另外因為Darknet已經存在build資料夾,所以我們指定其他資料夾作為build資料夾cmake.buildDirectory": "${workspaceFolder}/local-build,不過通常我們可以直接用預設值,並不需要另外設定cmake.buildDirectory
1 2 3 4 5 6 7 {     "cmake.configureArgs" :  [          "-DENABLE_CUDA=OFF" ,          "-DVCPKG_BUILD_OPENCV_WITH_CUDA=OFF"      ] ,      "cmake.buildDirectory" :  "${workspaceFolder}/local-build"  } 
 
CMake Config 首先我們要先跑一次CMake Config,按下ctrl + shift + p輸入cmake選擇CMake:Configure,在Output的地方會看到有沒有錯誤,如果出現錯誤歡迎在下面留言板留言。
建立launch.json 接下來要設定啟動,先建立一個launch.json位於${workspaceFolder}/.vscode/launch.json,並且複製以下內容。在這裡用到許多CMake extension提供的變數,可以在這裡 查詢更多的變數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 {     "version" :  "0.2.0" ,      "configurations" :  [          {              "name" :  "(gdb) Launch" ,              "type" :  "cppdbg" ,              "request" :  "launch" ,                           "program" :  "${command:cmake.launchTargetPath}" ,              "args" :  [ ] ,              "stopAtEntry" :  false ,              "cwd" :  "${workspaceFolder}" ,              "environment" :  [                  {                                                                "name" :  "PATH" ,                      "value" :  "${env:PATH}:${command:cmake.getLaunchTargetDirectory}"                  } ,                  {                      "name" :  "OTHER_VALUE" ,                      "value" :  "Something something"                  }              ] ,              "console" :  "externalTerminal" ,              "MIMode" :  "gdb" ,              "setupCommands" :  [                  {                      "description" :  "Enable pretty-printing for gdb" ,                      "text" :  "-enable-pretty-printing" ,                      "ignoreFailures" :  true                  }              ]          }      ]  } 
 
{= file:’launch.json’}
設定啟動時參數 首先要先下載yolov1.cfg和yolov1.weights並且放到cfg資料夾 Darknet執行檔啟動時需要參數,我們可以在launch.json的args設定。
1 "args" :  [ "detect" ,  "cfg/yolov1.cfg" ,  "cfg/yolov1.weights" ,  "data/dog.jpg" ] , 
 
執行 參考:  
Build with CMake Toolshttps://github.com/microsoft/vscode-cmake-tools/blob/f4804bcd2d376b4ad850c537d6ebdae46cfdcf3c/docs/build.md   
https://code.visualstudio.com/docs/cpp/config-linux   
Display an image in an OpenCV windowhttps://docs.opencv.org/4.x/db/deb/tutorial_display_image.html 
pkg-config尋找opencv函式庫https://answers.opencv.org/question/227890/using-l-in-g-command-line/ 
Get started with CMake Tools on Linuxhttps://code.visualstudio.com/docs/cpp/cmake-linux 
CMake Tools for Visual Studio Code documentationhttps://github.com/microsoft/vscode-cmake-tools/blob/main/docs/README.md 
Guide: “A modern, open source C++ dev environment with Visual Studio Code, vcpkg, and CMake”https://www.reddit.com/r/cpp/comments/j1dh9w/guide_a_modern_open_source_c_dev_environment_with/