Linux環境下的C++編程基礎

目錄

一、工具準備

二、程序的編譯及調試

1、程序的編譯及常用命令

2、gdb調試

三、Makefile文件基礎

1、Makefile介紹

2、Makefile編寫

3、make的運行和退出


一、工具準備

gcc是GNU的C編譯器(GNU C Compiler)

g++是GNU的C++編譯器(GNU C++ Compiler)

gdb是Linux下常用的調試工具,主要功能如下

  • 啓動你的程序,可以按照你的自定義的要求隨心所欲的運行程序。
  • 可讓被調試的程序在你所指定的調置的斷點處停住(斷點可以是條件表達式)。
  • 當程序被停住時,可以檢查此時你的程序中所發生的事。
  • 你可以改變你的程序,將一個BUG產生的影響修正從而測試其他BUG。

Makefile文件:Makefile是程序編譯的規則,makefile記錄着整個工程的編譯規則(如源文件的編譯順序、依賴關係等),通過make工具進行編譯。make根據makefile定義的規則將源代碼編譯成二進行文件。在跨平臺(特別是類Unix系統中)的程序中,一般都會通過makefile來進行編譯。

二、程序的編譯及調試

1、程序的編譯及常用命令

$ g++ main.cpp     #編譯程序,在當前目錄自動生成一個a.out的可執行文件

$ ./a.out     # 執行可執行文件,即運行程序

$ g++ main.cpp -o test        # 指定自己想要生成的可執行程序的別名 (test)

$ g++ -c main.cpp      # 將源代碼編譯成目標文件(main.o),不進行鏈接

$ g++ main.o -o test1($ g++ -o test1 main.o)     #g++接編譯後的(*.o)文件進行鏈接,生成可執行程序 (test1)

$ ldd test1       #該命令可以看到可執行程序 (test1)所鏈接的庫

$ g++ -o test1 main.cpp -L /usr/Lib -l /usr/include      #將依賴的函數庫和庫路徑加入

  • -L 指定連接的動態庫或者靜態庫路徑 ;

  • -I(大寫i) 指定頭文件路徑 ,即include文件(也就是包含的*.h頭文件)所在的目錄;

  • -l(小寫L) 指定需要鏈接的庫的名稱

$ gcc -g main.c -o test      #使用gdp調試C/C++程序, 在編譯時,必須要把調試信息加到可執行文件中

$ g++ -g main.cpp -o test

注: 編譯過程包括預處理、編譯,鏈接 ;linux系統上的編譯生成.o文件,windows系統上的編譯生成.obj文件 ;linux系統上生成沒有後綴的可執行文件,windows系統中生成.exe文件 ; linux系統下的靜態函數庫的後綴是.a,動態庫是.so ; windows系統下的靜態函數庫的後綴是.lib,動態庫是.dll。

2、gdb調試

GDB是一個由GNU開源組織發佈的、UNIX/LINUX操作系統下的、基於命令行的、功能強大的程序調試工具。可以用來調試C,C++程序。

gdp功能及其常用命令

命令形式 功能解釋
gdb -g main.cpp -o test 編譯代碼時的命令,要把調試信息加到可執行文件中
gdb 進入gdb調試命令
help 顯示幫助信息,例:help quit,顯示quit命令的信息
q/quit 退出GDB調試
file test 加載被調試的可執行程序文件test;或者直接使用gdb ./test進行debug調試命令
l/list 列出文件的內容
b/break <line number> 在某一行設置普通斷點,運行到該行即停止,例:b 7
b/break <line number> if condition 在某一行設置條件斷點,運行到該行滿足條件即停止,例:b 7 if index=2
b/break <function name> 在某一個函數調用處設置斷點,運行到函數調用出即停止,例:b getSum
r/run 運行調試的程序(如果程序中沒有設置斷點,則程序會一直運行到結束或者出現異常結束,如果設置斷點,則會在斷點處停止)
d/delete <break number> 刪除斷點編號對應的斷點,例:d 1
clear 清空所有的斷點信息
start 開始調試
c/continue 繼續執行程序直到下一個斷點或者程序結束
n/next 逐行調試
s/step 遇到函數時進到函數內部調試
p/print <value> 顯示變量的值,即查看變量數據,例:p index

gdb調試技巧總結下載 

三、Makefile文件基礎

1、Makefile介紹

Makefile文件關係到了整個工程的編譯規則,它定義了一系列的規則來指定哪些文件需要先編譯,哪些文件需要後編譯,哪些文件需要重新編譯,甚至於進行更復雜的功能操作,因爲 makefile就像一個Shell腳本一樣,其中也可以執行操作系統的命令。

Makefile帶來的好處就是“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。

make是一個命令工具,是一個解釋makefile中指令的命令工具, 在終端中輸入make命令,會自動搜索當前路徑下的makefile或者是Makefile文件 。

2、Makefile編寫

(1)Makefile示例1及分析

edit:main.o test.o          #需要生成的目標:生成目標的依賴項
    g++ main.o test.o -o test       #以Tab鍵開始,具體要執行的命令
test.o:
    g++ -c test.cpp
main.o:
    g++ -c main.cpp

clean:
    rm main.o test.o
  • makefile書寫規則包含兩個部分,一個是依賴關係,一個是生成目標的方法。
  • 我們可以把這個內容保存在文件爲“Makefile”或“makefile”的文件中(最好使用 “Makefile”這個文件名),然後在該目錄下直接輸入命令“make”就可以生成執行文件edit。
  • 如果要刪除執行文件和所有的中間目標文件,那麼,只要簡單地執行一下“make clean”就可以。
  • 在Makefile中使用“#”字符,表示註釋。

通過示例1看make的工作過程:

  • 首先,輸入make命令,make會在當前目錄下找名字叫“Makefile”或“makefile”的文件;
  • 如果找到,它會找文件中的第一個目標文件,即“edit”文件,並把這個文件作爲最終的目標文件;
  • 如果edit文件不存在,或是edit所依賴的後面的 .o 文件的文件修改時間要比edit這個文件新,那麼,他就會執行後面所定義的命令來生成edit這個文件;
  • 如果edit所依賴的.o文件也不存在,那麼make會在當前文件中找目標爲.o文件的依賴性,如果找到則再根據那一個規則生成.o文件。(這有點像一個堆棧的過程);
  • 然後再用 .o 文件生成make的終極任務,也就是執行文件edit。

這就是整個make的依賴性,make會一層又一層地去找文件的依賴關係,直到最終編譯出第一個目標文件。在尋找的過程中,如果出現錯誤,比如最後被依賴的文件找不到,那麼make 就會直接退出,並報錯,而對於所定義的命令的錯誤或是編譯不成功,make根本不理。make 只管文件的依賴性。

(2)Makefile示例2及分析

#################################################
# Example for call LTP libraries under UNIX     #
#################################################
cc=g++
ccflags=-O2
all: cws \
	pos

cws: cws.cpp
	${cc} ${ccflags} -o cws cws.cpp -I./ \
		-I../include/ \
		-I../thirdparty/boost/include \
		-L../lib/ -lsegmentor -lboost_regex

pos: pos.cpp
	${cc} ${ccflags} -o pos pos.cpp -I./ \
		-I../include/ \
		-L../lib/ -lpostagger

.PHONY: clean

clean:
    rm cws
    rm pos
  • 反斜槓(\)是換行符的意思。這樣比較便於Makefile的閱讀;
  • -I../include/表示依賴的頭文件路徑,-L../lib/表示依賴的庫路徑;
  • -O2:表示編譯時使用二級優化
  • makefile中使用變量,比如:cc=g++,makefile中以“$(cc)”的方式來使用這個變量;變量的命名字可以包含字符、數字,下劃線(可以是數字開頭),但不應該含有“:”、“#”、“=”或是空字符(空格、回車等)。變量是大小寫敏感的,“foo”、“Foo”和“FOO”是三個不同的變量名。
  • 清空目標文件的規則:爲了避免和文件重名的這種情況,我們可以使用一個特殊的標記“.PHONY”來顯示地指明一個目標是“僞目標”,向make說明,不管是否有這個文件,這個目標就是“僞目標”。只要有“.PHONY : clean ”這個聲明,不管是否有“clean”文件,要運行“clean”這個目標,只需“make clean” 即可。

(3)Makefile編寫規則

  • 顯式規則。顯式規則說明了,如何生成一個或多的的目標文件。這是由Makefile的書寫者明顯指出,要生成的文件,文件的依賴文件,生成的命令。
  • 隱晦規則。由於make有自動推導的功能,所以隱晦的規則可以讓我們比較粗糙地簡略地書寫Makefile,這是由make所支持的。
  • 變量的定義。在Makefile中我們要定義一系列的變量,變量一般都是字符串,當Makefile被執行時,其中的變量都會被擴展到相應的引用位置上。
  • 文件指示。其包括了三個部分,一個是在一個Makefile中引用另一個Makefile,就像C語言中的include一樣;另一個是指根據某些情況指定Makefile中的有效部分,就像C語言中的預編譯#if一樣;還有就是定義一個多行的命令。
  • 註釋。Makefile中只有行註釋,和UNIX的Shell腳本一樣,其註釋是用“#”字符,這個就像C/C++中的“//”一樣。如果你要在你的Makefile中使用“#”字符,可以用反斜框進行轉義,如:“#”。

注:在Makefile中的命令,必須要以[Tab]鍵開始。

(4)make工作時執行過程

  • 讀入所有的Makefile;
  • 讀入被include的其它Makefile;
  • 初始化文件中的變量;
  • 推導隱晦規則,並分析所有規則;
  • 爲所有的目標文件創建依賴關係鏈;
  • 根據依賴關係,決定哪些目標要重新生成;
  • 執行生成命令。

(5)makefile文件中使用通配符

我們想定義一系列比較類似的文件,可以使用通配符。make支持三種通配符:“*”,“?”和“[...]”;通配符可以代替一系列的文件,如“*.cpp”表示所有後綴爲cpp的文件。一個需要我們注意的是,如果我們的文件名中有通配符,如:“*”,那麼可以用轉義字符“\”,如“\*”來表示真實的“*”字符。

(6)Makefile中的-Wall -O2 -Os -g等選項介紹

  • -Wall:選項可以打印出編譯時所有的錯誤或者警告信息。這個選項很容易被遺忘,編譯的時候,沒有錯誤或者警告提示,以爲自己的程序很完美,其實,裏面有可能隱藏着許多陷阱。變量沒有初始化,類型不匹配,或者類型轉換錯誤等警告提示需要重點注意,錯誤就隱藏在這些代碼裏面。沒有使用的變量也需要注意,去掉無用的代碼,讓整個程序顯得乾淨一點。下次寫Makefile的時候,一定加-Wall編譯選項。
  • -O0: 表示編譯時沒有優化。
  • -O1: 表示編譯時使用默認優化。
  • -O2: 表示編譯時使用二級優化。
  • -O3: 表示編譯時使用最高級優化。
  • -Os:相當於-O2.5優化。

3、make的運行和退出

(1)make的運行

直接在命令行下輸入make命令,make命令會找當前目錄的makefile來執行,一切都是自動的。

(2)make的退出

make命令執行後有三個退出碼:

  • 0 —— 表示成功執行。
  • 1 —— 如果make運行時出現任何錯誤,其返回1。
  • 2 —— 如果你使用了make的“-q”選項,並且make使得一些目標不需要更新,那麼返回2。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章