一、makefile
1、make && makefile
makefile帶來的好處就是——自動化編譯,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率
下面我們通過如下示例來進一步體會它們的作用:
①編寫makefile文件
touch makefile
vim makefile
使用vim編輯器編輯makefile
文件:
#makefile文件中的內容
hello.exe:hello.c gcc hello.c -o hello.exe
.PHONY:clean
clean:rm -f hello.exe
此時我們只需一個make
命令即可完成自動編譯:
make
make
命令的作用,即是執行makefile
中的命令,此處執行的命令是:
gcc hello.c -o hello.exe
當我們輸入:
make clean
此處就執行了:
rm -f hello.exe
2、make執行步驟
當我們在Linux中輸入并執行make
命令時,make
會干些什么呢?
step 1:
make
會在當前目錄下尋找Makefile
文件,找到了就會用這個文件作為后續操作的依據;如果沒找到Makefile
,就會尋找名為makefile
的文件;兩個都沒找到就報錯;step 2:找到
Makefile
或者makefile
之后,默認文件中第一行作為第一個目標;make
命令會分析第一個目標的依賴關系,并且執行該目標的依賴方法**;
2.1 依賴關系
hello.exe:hello.c #依賴關系
makefile
文件中hello.exe
就是目標(期望生成的內容);我們編譯文件hello.c
,期望生成它對應的可執行文件hello.exe
,而你要編譯生成這個目標文件,需要依賴hello.c
這個文件,這就是依賴關系。
2.2 依賴方法
有了依賴關系,我們就知道了生成目標可執行文件hello.exe
需要依賴hello.c
這個文件,那么我們該怎么利用hello.c
文件生成hello.exe
文件呢?我們是不是還缺少一個方法,而這個使用目標的依賴關系文件生成期望的目標文件的方法就是依賴方法。
gcc hello.c -o hello.exe #依賴方法
需要注意的是,依賴文件列表可以為空
3、項目清理
# makefile文件中的清理部分
.PHONY:clean
clean:rm -f code
上述makefile
文件中,該部分即為項目清理部分;在上述介紹中,我們知道需要顯式輸入make clean
才能實現清除編譯好的文件hello.exe
以便重新編譯:
其中.PHONY
的使用,是將它設置為偽目標,偽目標的特性是:總是被執行的?
4、偽目標 .PHONY
👉 怎樣理解總是被執行的?我們試著多次輸入make
指令,發現結果如下:
結果:當第一次使用make命令時,目標被執行生成了一個可執行文件,而當我們再使用make命令時發現make雖然不會報錯但是會告訴我們生成的文件的已經是最新的了,目標并沒有被執行
那么多次輸入make clean
指令呢?結果如下:
可以一直執行rm -f hello.exe
這條指令!(即使已經重復執行了)
我們將生成可執行文件過程更改為偽目標(使用vim編輯器):
# 修改makefile文件
.PHONY:hello.exe
hello.exe:hello.cgcc hello.c -o hello.exe
再測試一下:
二、GDB
GDB是命令行模式的調試工具,能夠讓用戶在程序運行時觀察程序的內部結構和內存的使用情況。
1、準備工作
gdb_test.c:
#include<time.h>void Print(int sum)
{long long timestamp=time(NULL);printf("result=%d,timestamp:%lld\n",sum,timestamp);
}int AddtoVal(int from,int to)
{int sum=0;for (int i = from; i <= to; i++){sum+=i;}return sum;
}int main()
{int sum=AddtoVal(0,100);Print(sum);return 0;
}
生成可執行文件:
1、debug版本:程序本身會被加入更多的調試信息,以便于進行調試。
?2、release版本:不會添加任何調試信息,是不可調試的。
在Linux當中gcc/g++默認生成的可執行程序是release版本的,是不可被調試的。如果想生成debug版本,就需要在使用gcc/g++生成可執行程序時加上-g
選項。
gdb_test_g.exe:gdb_test.cgcc gdb_test.c -o gdb_test_g.exe -g
.PHONY:clean
clean:rm -rf gdb_test_g.exe
可使用工具讀取可執行程序符號表debug部分:
[Kevin@VM-8-13-centos code1]$ readelf -S gdb_test_g.exe | grep debug[26] .debug_aranges PROGBITS 0000000000000000 00001095[27] .debug_info PROGBITS 0000000000000000 000010c5[28] .debug_abbrev PROGBITS 0000000000000000 00001536[29] .debug_line PROGBITS 0000000000000000 000016af[30] .debug_str PROGBITS 0000000000000000 000017d5
總結:要用gdb調試,首先要進行給編譯器添加-g
2、正式調試
調試命令:
進入gdb:gdb?文件名
顯示代碼:l?n 顯示從第n行開始的源代碼,每次顯示10行,若n未給出則默認從上次的位置往下顯示。
打一個斷點:b?n在第n行設置斷點。
查看已打斷點:info b
去掉打的斷點:d 斷點編號 刪除指定編號(不是行號)的斷點。
開始調試運行:r(run)
逐過程:n(next)
逐語句:s(step)會進入函數體中
運行到下一個斷點處:c(continue)
查看函數調用堆棧:bt
直接運行完當前函數:finish 個性化跑完自定義的一個個函數,方便定位代碼錯誤的位置
打印變量的值/地址:p(print)變量/&變量
將變量的值/地址加入常顯示:display 變量/&變量
取消指定編號變量的常顯示:undisplay 編號
跳出循環/跳轉至指定行:until 行號
修改變量值:set var 變量=x 將變量的值修改為x
退出gdb:quit/ql
continue)
查看函數調用堆棧:bt
直接運行完當前函數:finish 個性化跑完自定義的一個個函數,方便定位代碼錯誤的位置
打印變量的值/地址:p(print)變量/&變量
將變量的值/地址加入常顯示:display 變量/&變量
取消指定編號變量的常顯示:undisplay 編號
跳出循環/跳轉至指定行:until 行號
修改變量值:set var 變量=x 將變量的值修改為x
退出gdb:quit/ql