程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Linux中運用VS Code編譯調試C++項目詳解

Linux中運用VS Code編譯調試C++項目詳解

編輯:關於C++

Linux中運用VS Code編譯調試C++項目詳解。本站提示廣大學習愛好者:(Linux中運用VS Code編譯調試C++項目詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是Linux中運用VS Code編譯調試C++項目詳解正文


前言

關於VS Code在Linux下的裝置這裡就不提了,不論是CentOS還是Ubuntu,假如不懂且搜問題足夠的狀況下,你會處理的。

一、前置知識——gcc/g++的編譯鏈接進程

在Windows下,假如你用Visual Studio停止開發,C/C++的編譯器普通采用微軟提供的MSBuild;在Linux下C/C++的編譯器大多采用gcc/g++。既然要在Linux下停止C++開發,很有必要理解一下g++編譯器的一些根本知識。

假定我如今有一個最復雜的C++文件:

 #include <iostream>
 using namespace std;
 int main() {
 cout << "Hello, world!!!!" << endl;
 return 0;
 }

接上去如何編譯呢?復雜來說分紅兩步:先編譯,再鏈接

1. 裝置g++編譯器

啟動終端,進入root形式,裝置gcc和g++

Ubuntu:

CentOS:

[xxx@xxx ~]$ su
[xxx@xxx ~]# yum install gcc
[xxx@xxx ~]# gcc --version
[xxx@xxx ~]# yum install gcc-g++
[xxx@xxx ~]# g++ --version

2. 編譯hello.cpp

[xxx@xxx ~]$ g++ -c hello.cpp

輸入後果是一個hello.o文件,這是編譯進程的生成的兩頭文件。-c 表示只編譯,不鏈接。

3. 鏈接hello.o生成hello.out

[xxx@xxx ~]$ g++ -o hello.out hello.o

輸入後果是一個hello.out文件,這是最終的可執行文件。-o 表示輸入文件,hello.o是上一步生成的.o文件。

當然,假如第2、3步是可以兼並執行,直接執行命令

[xxx@xxx ~]$ g++ -o hello.out hello.cpp

但是第2、3步分開執行是有意義的,前面會講到。

4. 運轉hello.out

最後執行以下hello.out驗證一下輸入後果呗

[xxx@xxx ~]$ ./hello.out

二、構建項目

實踐開發進程中當然不能夠只要一個cpp這麼復雜,有時分會有十分多的.h和.cpp文件互相配合,那麼下面直接經過g++編譯可執行文件就沒那麼復雜了。我們需求借助Make這個弱小的項目構建工具,協助我們構建和組織項目代碼。

假定如今有如下3個文件:hw2.cpp、solution.h和solution.cpp

 /* solution.h */
 class Solution {
 public:
 void Say();
 };
/* solution.cpp */
 #include <iostream>
 #include "solution.h"
 void Solution::Say(){
 std::cout << "HI!" << std::endl;
 }
 /* hw2.cpp */
 #include "solution.h"
 int main () {
 Solution sln;
 sln.Say();
 return 0;
 }

可以看到這個復雜例子包括頭文件援用、定義和完成別離等狀況,假如直接g++ -o hw2.out hw2.cpp將會報未定義援用的錯誤:

[xxx@xxx ~]$ g++ -o hw2.out hw2.cpp

/tmp/ccIMYTxf.o:在函數‘main'中:

hw2.cpp:(.text+0x10):對‘Solution::Say()'未定義的援用

collect2: 錯誤:ld 前往 1

這時Make就該大顯神通了。

首先我們還需求理解一下makefile。

在項目的根目錄下創立一個makefile文件,以通知Make如何編譯和鏈接順序。

build : hw2.o solution.o
 g++ -o build hw2.o solution.o #留意後面必需是tab,不能是空格
 hw2.o : hw2.cpp solution.h
 g++ -g -c hw2.cpp
 solution.o : solution.h solution.cpp
 g++ -g -c solution.cpp
 clean :
 rm hw2.o solution.o build

先來解釋一下makefile的根本語法規則:

target ... : prerequisites ...
  command #留意後面是tab

target是一個目的文件,可以是Object File,也可以是執行文件,還可以是一個標簽;

prerequisites是要生成那個target所需求的文件或是目的;

command是make需求執行的命令(恣意的Shell命令)。

說白了就是target這一個或多個目的,依賴於prerequisites列表中的文件,其執行規則定義在command裡。假如prerequisites列表中文件比target要新,就會執行command,否則就跳過。這就是整個make進程的根本原理。

那麼,我們回頭看看下面定義的makefile文件,我們解釋一下每兩行的作用

 build : hw2.o solution.o
 g++ -o build hw2.o solution.o

target是build,依賴於hw2.o 和 solution.o,執行的命令是 g++ -o build hw2.o solution.o

意思是經過g++鏈接hw2.o和solution.o,生成可執行文件build,prerequisites有兩個.o文件,是由於代碼裡hw2援用了solution.h。

hw2.o : hw2.cpp solution.h
 g++ -g -c hw2.cpp

target是hw2.o,依賴於hw2.cpp和solution.h,執行命令是g++ -g -c hw2.cpp

意思是經過g++編譯hw2.cpp文件,生成hw2.o文件,g++命令中 -g 表示生成的文件是可調試的,假如沒有-g,調試時無法命中綴點。

 solution.o : solution.h solution.cpp
 g++ -g -c solution.cpp

同上,編譯solution.cpp文件,生成solution.o文件。

clean :
 rm hw2.o solution.o build

這裡clean不是一個可執行文件,也不是一個.o文件,它只不過是一個舉措名字,相似於label的作用,make不會去找冒號後的依賴關系,也不會自動執行命令。假如要執行該命令,必需在make後顯示指出整個舉措的名字,如make clean。

好了,接上去說一下make的任務原理。在默許的方式下,我們只需輸出make,則發作了以下行為:

     a. make在以後目錄下找名為makefile或Makefile的文件;

     b. 假如找到,它會找文件中的第一個target,如上述文件中的build,並作為終極目的文件;

     c. 假如第一個target的文件不存在,或其依賴的.o 文件修正時間要比target這個文件新,則會執行緊接著的command來生成這個target文件;

     d. 假如第一個target所依賴的.o文件不存在,則會在makefile文件中找target為.o的依賴,假如找到則執行command,.o的依賴必是.h或.cpp,於是make可以生成 .o 文件了

     e. 回溯到b步執行最終目的

看一下執行後果

[xxx@xxx ~]$ make
g++ -g -c hw2.cpp
g++ -g -c solution.cpp
g++ -o build hw2.o solution.o #留意後面必需是tab,不能是空格
[xxx@xxx ~]$ ./build 
HI!
[xxx@xxx ~]$

由於makefile文件中加了-g這一選項,於是可以經過gdb停止調試,並且會命中綴點,這裡感興味可以再理解一下gdb的運用。

接上去我們要說到如何經過VS Code停止調試。

三、在VS Code中編譯調試

首先裝置完VS Code之後,還需求裝置一下擴展cpptools,請自行完成。

點擊菜單 檢查-> 調試,或直接快捷鍵ctrl + shift + D

點擊設置圖標,在彈出的選擇環境中選擇C++(GDB/LLDB),會自動創立一個launch.json文件

望文生義,laucn.json的作用是通知VS Code如何執行啟動義務,也就是我們要把什麼文件啟動起來,在上述例子中顯然是build這個可執行文件了。修正一下json文件中波浪線的program節點,改成${workspaceRoot}/build,其他的暫時不變

1 {
 2  "version": "0.2.0",
 3  "configurations": [
 4   {
 5    "name": "C++ Launch",
 6    "type": "cppdbg",
 7    "request": "launch",
 8    "program": "${workspaceRoot}/build",
 9    "args": [],
10    "stopAtEntry": false,
11    "cwd": "${workspaceRoot}",
12    "environment": [],
13    "externalConsole": true,
14    "linux": {
15     "MIMode": "gdb"
16    },
17    "osx": {
18     "MIMode": "lldb"
19    },
20    "windows": {
21     "MIMode": "gdb"
22    }
23   },
24   {
25    "name": "C++ Attach",
26    "type": "cppdbg",
27    "request": "attach",
28    "program": "${workspaceRoot}/build",
29    "processId": "${command.pickProcess}",
30    "linux": {
31     "MIMode": "gdb"
32    },
33    "osx": {
34     "MIMode": "lldb"
35    },
36    "windows": {
37     "MIMode": "gdb"
38    }
39   }
40  ]
41 }

接著我們嘗試一下F5,開端調試,後果可以看到報了一個短少build文件的錯誤。緣由是我們還沒執行make編譯出可執行文件呢。我們在launch.json文件中,添加一個preLaunchTask的節點,並設置值為“build”。留意這裡的build不是指可執行文件build,而是一個名為build的義務!

 1 {
 2  "version": "0.2.0",
 3  "configurations": [
 4   {
 5    "name": "C++ Launch",
 6    "type": "cppdbg",
 7    "request": "launch",
 8    "program": "${workspaceRoot}/build",
 9    "args": [],
10    "stopAtEntry": false,
11    "cwd": "${workspaceRoot}",
12    "environment": [],
13    "externalConsole": true,
14    "preLaunchTask": "build",
15    "linux": {
16     "MIMode": "gdb"
17    },
18    "osx": {
19     "MIMode": "lldb"
20    },
21    "windows": {
22     "MIMode": "gdb"
23    }
24   },
25   {
26    "name": "C++ Attach",
27    "type": "cppdbg",
28    "request": "attach",
29    "program": "${workspaceRoot}/build",
30    "processId": "${command.pickProcess}",
31    "linux": {
32     "MIMode": "gdb"
33    },
34    "osx": {
35     "MIMode": "lldb"
36    },
37    "windows": {
38     "MIMode": "gdb"
39    }
40   }
41  ]
42 }

再嘗試F5,會提示一個信息:

點擊配置義務運轉順序,並選擇Others, 會自動生成一個tasks.json文件,這個文件的作用就是通知launch或許編譯器需求執行什麼操作。顯然我們這裡要執行make命令,修正tasks.json為如下:

1 {
 2  "version": "0.1.0",
 3  "command": "make",
 4  "showOutput": "always",
 5  "tasks": [
 6   {
 7    "taskName": "clean"
 8   },
 9   {
10    "taskName": "build",
11    "problemMatcher": {
12     "owner": "cpp",
13     "fileLocation": ["relative", "${workspaceRoot}"],
14     "pattern": {
15      "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
16      "file": 1,
17      "line": 2,
18      "column": 3,
19      "severity": 4,
20      "message": 5
21     }
22    }
23   }
24  ]
25 }

其中tasks節點是一組義務,留意到其中一個名為build的義務,這就是launch.json文件中指定的preLaunchTask,標明在啟動可執行順序之前,會先執行一下preLaunchTask即這裡的build義務,重新make一下代碼,更新可執行順序之後再啟動。

當然也可以指運轉tasks這些義務而不啟動可執行順序,直接ctrl + shift + B,在VSC的console裡可以看到和終端執行一樣的輸入:

執行完後,項目中會多出.o和build文件

關於VS Code的launch.json和tasks.json中更多節點的含義,參考

https://code.visualstudio.com/docs/editor/debugging

https://code.visualstudio.com/docs/editor/tasks

接著設置好斷點之後F5,就可以進入斷點調試了

總結

本文次要總結了gcc/g++和make/makefile的根底知識,以及在Linux下運用VS Code停止調試開發的辦法,希望對正在挖坑的同窗有所協助,假如有疑問大家可以留言交流,謝謝大家對的支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved