欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux中使用VS Code編譯調(diào)試C++項(xiàng)目詳解

 更新時(shí)間:2016年12月13日 10:58:42   作者:DoubleLi  
最近因?yàn)轫?xiàng)目的需求,需要在Linux下開(kāi)發(fā)C++相關(guān)項(xiàng)目,經(jīng)過(guò)一番摸索最終實(shí)現(xiàn)了,下面這篇文章就給大家簡(jiǎn)單總結(jié)了一下如何通過(guò)VS Code進(jìn)行編譯調(diào)試的一些注意事項(xiàng)。有需要的朋友們可以參考借鑒,下面來(lái)跟著小編一起看看吧。

前言

關(guān)于VS Code在Linux下的安裝這里就不提了,不管是CentOS還是Ubuntu,如果不懂且搜問(wèn)題足夠的情況下,你會(huì)解決的。

一、前置知識(shí)——gcc/g++的編譯鏈接過(guò)程

在Windows下,如果你用Visual Studio進(jìn)行開(kāi)發(fā),C/C++的編譯器一般采用微軟提供的MSBuild;在Linux下C/C++的編譯器大多采用gcc/g++。既然要在Linux下進(jìn)行C++開(kāi)發(fā),很有必要了解一下g++編譯器的一些基本知識(shí)。

假設(shè)我現(xiàn)在有一個(gè)最簡(jiǎn)單的C++文件:

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

接下來(lái)如何編譯呢?簡(jiǎn)單來(lái)說(shuō)分成兩步:先編譯,再鏈接

1. 安裝g++編譯器

啟動(dòng)終端,進(jìn)入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

輸出結(jié)果是一個(gè)hello.o文件,這是編譯過(guò)程的生成的中間文件。-c 表示只編譯,不鏈接。

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

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

輸出結(jié)果是一個(gè)hello.out文件,這是最終的可執(zhí)行文件。-o 表示輸出文件,hello.o是上一步生成的.o文件。

當(dāng)然,如果第2、3步是可以合并執(zhí)行,直接執(zhí)行命令

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

然而第2、3步分開(kāi)執(zhí)行是有意義的,后面會(huì)講到。

4. 運(yùn)行hello.out

最后執(zhí)行以下hello.out驗(yàn)證一下輸出結(jié)果唄

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

二、構(gòu)建項(xiàng)目

實(shí)際開(kāi)發(fā)過(guò)程中當(dāng)然不可能只有一個(gè)cpp這么簡(jiǎn)單,有時(shí)候會(huì)有非常多的.h和.cpp文件相互配合,那么上面直接通過(guò)g++編譯可執(zhí)行文件就沒(méi)那么簡(jiǎn)單了。我們需要借助Make這個(gè)強(qiáng)大的項(xiàng)目構(gòu)建工具,幫助我們構(gòu)建和組織項(xiàng)目代碼。

假設(shè)現(xiàn)在有如下3個(gè)文件: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è)簡(jiǎn)單例子包括頭文件引用、定義和實(shí)現(xiàn)分離等情況,如果直接g++ -o hw2.out hw2.cpp將會(huì)報(bào)未定義引用的錯(cuò)誤:

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

/tmp/ccIMYTxf.o:在函數(shù)‘main'中:

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

collect2: 錯(cuò)誤:ld 返回 1

這時(shí)Make就該大顯身手了。

首先我們還需要了解一下makefile。

在項(xiàng)目的根目錄下創(chuàng)建一個(gè)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

先來(lái)解釋一下makefile的基本語(yǔ)法規(guī)則:

target ... : prerequisites ...
  command #注意前面是tab

target是一個(gè)目標(biāo)文件,可以是Object File,也可以是執(zhí)行文件,還可以是一個(gè)標(biāo)簽;

prerequisites是要生成那個(gè)target所需要的文件或是目標(biāo);

command是make需要執(zhí)行的命令(任意的Shell命令)。

說(shuō)白了就是target這一個(gè)或多個(gè)目標(biāo),依賴于prerequisites列表中的文件,其執(zhí)行規(guī)則定義在command里。如果prerequisites列表中文件比target要新,就會(huì)執(zhí)行command,否則就跳過(guò)。這就是整個(gè)make過(guò)程的基本原理。

那么,我們回頭看看上面定義的makefile文件,我們解釋一下每?jī)尚械淖饔?/p>

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

target是build,依賴于hw2.o 和 solution.o,執(zhí)行的命令是 g++ -o build hw2.o solution.o

意思是通過(guò)g++鏈接hw2.o和solution.o,生成可執(zhí)行文件build,prerequisites有兩個(gè).o文件,是因?yàn)榇a里hw2引用了solution.h。

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

target是hw2.o,依賴于hw2.cpp和solution.h,執(zhí)行命令是g++ -g -c hw2.cpp

意思是通過(guò)g++編譯hw2.cpp文件,生成hw2.o文件,g++命令中 -g 表示生成的文件是可調(diào)試的,如果沒(méi)有-g,調(diào)試時(shí)無(wú)法命中斷點(diǎn)。

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

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

clean :
 rm hw2.o solution.o build

這里clean不是一個(gè)可執(zhí)行文件,也不是一個(gè).o文件,它只不過(guò)是一個(gè)動(dòng)作名字,類似于label的作用,make不會(huì)去找冒號(hào)后的依賴關(guān)系,也不會(huì)自動(dòng)執(zhí)行命令。如果要執(zhí)行該命令,必須在make后顯示指出整個(gè)動(dòng)作的名字,如make clean。

好了,接下來(lái)說(shuō)一下make的工作原理。在默認(rèn)的方式下,我們只需輸入make,則發(fā)生了以下行為:

     a. make在當(dāng)前目錄下找名為makefile或Makefile的文件;

     b. 如果找到,它會(huì)找文件中的第一個(gè)target,如上述文件中的build,并作為終極目標(biāo)文件;

     c. 如果第一個(gè)target的文件不存在,或其依賴的.o 文件修改時(shí)間要比target這個(gè)文件新,則會(huì)執(zhí)行緊接著的command來(lái)生成這個(gè)target文件;

     d. 如果第一個(gè)target所依賴的.o文件不存在,則會(huì)在makefile文件中找target為.o的依賴,如果找到則執(zhí)行command,.o的依賴必是.h或.cpp,于是make可以生成 .o 文件了

     e. 回溯到b步執(zhí)行最終目標(biāo)

看一下執(zhí)行結(jié)果

[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這一選項(xiàng),于是可以通過(guò)gdb進(jìn)行調(diào)試,并且會(huì)命中斷點(diǎn),這里感興趣可以再了解一下gdb的使用。

接下來(lái)我們要說(shuō)到如何通過(guò)VS Code進(jìn)行調(diào)試。

三、在VS Code中編譯調(diào)試

首先安裝完VS Code之后,還需要安裝一下擴(kuò)展cpptools,請(qǐng)自行完成。

點(diǎn)擊菜單 查看-> 調(diào)試,或直接快捷鍵ctrl + shift + D

點(diǎn)擊設(shè)置圖標(biāo),在彈出的選擇環(huán)境中選擇C++(GDB/LLDB),會(huì)自動(dòng)創(chuàng)建一個(gè)launch.json文件

顧名思義,laucn.json的作用是告訴VS Code如何執(zhí)行啟動(dòng)任務(wù),也就是我們要把什么文件啟動(dòng)起來(lái),在上述例子中顯然是build這個(gè)可執(zhí)行文件了。修改一下json文件中波浪線的program節(jié)點(diǎn),改成${workspaceRoot}/build,其余的暫時(shí)不變

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,開(kāi)始調(diào)試,結(jié)果可以看到報(bào)了一個(gè)缺少build文件的錯(cuò)誤。原因是我們還沒(méi)執(zhí)行make編譯出可執(zhí)行文件呢。我們?cè)趌aunch.json文件中,添加一個(gè)preLaunchTask的節(jié)點(diǎn),并設(shè)置值為“build”。注意這里的build不是指可執(zhí)行文件build,而是一個(gè)名為build的任務(wù)!

 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,會(huì)提示一個(gè)信息:

點(diǎn)擊配置任務(wù)運(yùn)行程序,并選擇Others, 會(huì)自動(dòng)生成一個(gè)tasks.json文件,這個(gè)文件的作用就是告訴launch或者編譯器需要執(zhí)行什么操作。顯然我們這里要執(zhí)行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節(jié)點(diǎn)是一組任務(wù),注意到其中一個(gè)名為build的任務(wù),這就是launch.json文件中指定的preLaunchTask,表明在啟動(dòng)可執(zhí)行程序之前,會(huì)先執(zhí)行一下preLaunchTask即這里的build任務(wù),重新make一下代碼,更新可執(zhí)行程序之后再啟動(dòng)。

當(dāng)然也可以指運(yùn)行tasks這些任務(wù)而不啟動(dòng)可執(zhí)行程序,直接ctrl + shift + B,在VSC的console里可以看到和終端執(zhí)行一樣的輸出:

執(zhí)行完后,項(xiàng)目中會(huì)多出.o和build文件

關(guān)于VS Code的launch.json和tasks.json中更多節(jié)點(diǎn)的含義,參考

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

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

接著設(shè)置好斷點(diǎn)之后F5,就可以進(jìn)入斷點(diǎn)調(diào)試了

總結(jié)

本文主要總結(jié)了gcc/g++和make/makefile的基礎(chǔ)知識(shí),以及在Linux下使用VS Code進(jìn)行調(diào)試開(kāi)發(fā)的方法,希望對(duì)正在挖坑的同學(xué)有所幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • C++圖文并茂分析講解模板

    C++圖文并茂分析講解模板

    C++語(yǔ)言的模板技術(shù)包括函數(shù)模板和類模板,模板技術(shù)是一種代碼重用技術(shù),函數(shù)和類是C++語(yǔ)言中兩種主要的重用代碼形式,這篇文章主要介紹了C++函數(shù)模板和類模板,需要的朋友可以參考下
    2022-09-09
  • C語(yǔ)言函數(shù)的遞歸和調(diào)用實(shí)例分析

    C語(yǔ)言函數(shù)的遞歸和調(diào)用實(shí)例分析

    一個(gè)函數(shù)在它的函數(shù)體內(nèi)調(diào)用它自身稱為遞歸調(diào)用。這種函數(shù)稱為遞歸函數(shù)。C語(yǔ)言允許函數(shù)的遞歸調(diào)用。在遞歸調(diào)用中,主調(diào)函數(shù)又是被調(diào)函數(shù)。執(zhí)行遞歸函數(shù)將反復(fù)調(diào)用其自身,每調(diào)用一次就進(jìn)入新的一層
    2013-07-07
  • C語(yǔ)言怎樣用指針指向字符串

    C語(yǔ)言怎樣用指針指向字符串

    這篇文章主要介紹了C語(yǔ)言怎樣用指針指向字符串問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • C++ float、double判斷是否等于0問(wèn)題

    C++ float、double判斷是否等于0問(wèn)題

    這篇文章主要介紹了C++ float、double判斷是否等于0問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • C語(yǔ)言實(shí)現(xiàn)出棧序列

    C語(yǔ)言實(shí)現(xiàn)出棧序列

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)出棧序列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++ 詳解數(shù)據(jù)結(jié)構(gòu)中的搜索二叉樹(shù)

    C++ 詳解數(shù)據(jù)結(jié)構(gòu)中的搜索二叉樹(shù)

    搜索二叉樹(shù)是一種具有良好排序和查找性能的二叉樹(shù)數(shù)據(jù)結(jié)構(gòu),包括多種操作,本篇只介紹插入,排序(遍歷),和刪除操作,重點(diǎn)是刪除操作比較復(fù)雜
    2022-04-04
  • C語(yǔ)言編程之動(dòng)態(tài)內(nèi)存與柔性數(shù)組的了解

    C語(yǔ)言編程之動(dòng)態(tài)內(nèi)存與柔性數(shù)組的了解

    本文是C語(yǔ)言編程篇,這篇文章主要為大家介紹了C語(yǔ)言編程中動(dòng)態(tài)內(nèi)存的函數(shù)與柔性數(shù)組的特點(diǎn),有需要的朋友可以借鑒參考下,希望可以有所幫助
    2021-09-09
  • C++實(shí)現(xiàn)LeetCode(118.楊輝三角)

    C++實(shí)現(xiàn)LeetCode(118.楊輝三角)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(118.楊輝三角),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 深入理解二叉樹(shù)的非遞歸遍歷

    深入理解二叉樹(shù)的非遞歸遍歷

    本篇文章是對(duì)二叉樹(shù)的非遞歸遍歷進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 實(shí)現(xiàn)Dijkstra算法最短路徑問(wèn)題詳解

    實(shí)現(xiàn)Dijkstra算法最短路徑問(wèn)題詳解

    這篇文章主要介紹了實(shí)現(xiàn)Dijkstra算法最短路徑問(wèn)題詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論