Linux命令【三】gcc编译+静态库+动态库+makefile+gdb调试
用C編譯器編譯源文件:gcc 源文件 -o 可執(zhí)行文件名
詳細(xì)步驟:
- gcc -E a.c -o a.i預(yù)處理器將頭文件展開,宏替換,去掉注釋
- gcc -S a.i -o a.s編譯器將C文件變成匯編文件
- gcc -c a.s -o a.o匯編器將會(huì)變文件變成二進(jìn)制文件
- gcc a.o -o a鏈接器進(jìn)行鏈接
ESc+鏈接
如果不使用參數(shù)-o 則自動(dòng)生成a.out
制定頭文件的路徑gcc a.c -I 頭文件的目錄 -o 生成可執(zhí)行文件的名字在比較舊的版本上-I和頭文件目錄之間不能有空格,現(xiàn)版本無所謂
指定宏-D 宏名
優(yōu)化-O1/O2/O3O3優(yōu)化速度最高
輸出警告信息-Wall
生成調(diào)試信息-g
靜態(tài)庫
lib+庫的名字+.a
生成對應(yīng)的.o文件,直接使用參數(shù)-c得到.o文件,記得不要使用-o參數(shù),否則將會(huì)直接生成可執(zhí)行文件
將生成的.o文件進(jìn)行打包,需要使用軟件ar將.o打包為.a
打包靜態(tài)庫和頭文件,將所有的靜態(tài)庫放到lib文件夾中,將所有的頭文件放到include文件夾中,制作好靜態(tài)庫以后可以發(fā)送這兩個(gè)文件夾。
用戶通過頭文件知道有哪些函數(shù)接口。通過直接和源文件編譯靜態(tài)庫使用。
打包的最小單元為.o
優(yōu)點(diǎn):
缺點(diǎn):
動(dòng)態(tài)庫/共享庫
lib+名字+.so
(1) 生成與位置無關(guān)的代碼(.o)
(2) 將.o打包成共享庫
Linux每一個(gè)運(yùn)行的程序操作系統(tǒng)都會(huì)為其分配一個(gè)0-4G的地址空間。Linux下可執(zhí)行文件格式:ELF
再講lib中的.so文件和include中的頭文件發(fā)送給用戶
使用ldd查看可執(zhí)行文件所依賴的所有的共享庫的名字
動(dòng)態(tài)庫的使用需要動(dòng)態(tài)鏈接器幫助。我們需要讓動(dòng)態(tài)鏈接器找到我們自己的動(dòng)態(tài)鏈接庫
正常情況下使用會(huì)出現(xiàn)動(dòng)態(tài)庫無法找到的問題。然后就需要我們?nèi)ソ鉀Q。
可是我自己嘗試的時(shí)候沒有遇到這個(gè)情況。。。我也不清楚為什么,可能是現(xiàn)在版本的gcc已經(jīng)智能地解決這個(gè)問題了。
(1)將動(dòng)態(tài)庫放到系統(tǒng)的lib文件夾中
(2) 配置環(huán)境變量LD_LIBRARY_PATH(如果你的動(dòng)態(tài)庫沒有在默認(rèn)的環(huán)境變量中,會(huì)先在這個(gè)環(huán)境變量中查找)
用于臨時(shí)測試
關(guān)掉終端后失效
(3)
永久
(4)工作中更加常用的方法
-
找到動(dòng)態(tài)鏈接器的配置文件
/etc/ld.so.conf
需要使用管理員權(quán)限 -
將動(dòng)態(tài)庫的路徑寫到配置文件中
-
更新sudo ldconfig -v -v是提示信息
動(dòng)態(tài)庫沒有加載到源文件中,而是在需要使用的位置加上了一個(gè)標(biāo)記,在使用的時(shí)候才進(jìn)行訪問。
優(yōu)點(diǎn):
缺點(diǎn):
gdb 調(diào)試
- l 默認(rèn)展示包含main()的文件
- l 文件名:行號(hào) 展示以行號(hào)為中心上下文件的內(nèi)容
- l 文件名:函數(shù)名 展示文件中的函數(shù),輸入l繼續(xù)展示后面的內(nèi)容,然后后面再直接按回車,會(huì)繼續(xù)向下展示文件,一次展示10行
- break 行號(hào)在某一行打斷點(diǎn)b 行號(hào)
- b 行號(hào) if 條件條件斷點(diǎn),條件斷點(diǎn)只能設(shè)置在循環(huán)內(nèi)部,如果設(shè)置在邊界不會(huì)停止
- b filename:行號(hào)在某個(gè)文件的某一行設(shè)置斷點(diǎn)
- info break i b查看斷點(diǎn)信息
- start gdb開始運(yùn)行程序,每次運(yùn)行一行,n單步調(diào)試,c繼續(xù)執(zhí)行到斷點(diǎn)
- s下一步,會(huì)進(jìn)入函數(shù)體內(nèi)部(step)
- n下一步,不會(huì)進(jìn)入函數(shù)內(nèi)部
- run直接運(yùn)行到斷點(diǎn),如果沒有斷點(diǎn)直接運(yùn)行結(jié)束
- p 變量 展示某個(gè)變量的值
- ptype 變量 展示變量的類型
- display 變量追蹤某個(gè)變量的值
- undisplay 變量編號(hào)取消追蹤某個(gè)變量
- info display 打印所有追蹤變量的信息
- u將循環(huán)運(yùn)行結(jié)束,結(jié)束循環(huán)
- finish 跳出當(dāng)前函數(shù),需要將函數(shù)中的斷點(diǎn)消除
- d 斷點(diǎn)編號(hào)刪除斷點(diǎn)(del)
- set var 變量=x直接運(yùn)行到變量為x的時(shí)候
- quit退出gdb
makefile
makefile項(xiàng)目管理工具,用于管理源代碼
簡單makefile文件
命名規(guī)則
(1) makefile
(2) Makefile
編寫規(guī)則
makefile 一般情況下要和.c文件在一個(gè)文件夾中,如果不在需要絕對路徑
三要素:
make
進(jìn)階makefile文件
當(dāng)一些文件修改以后需要重新編譯,為了解決這個(gè)問題:
例如:
上面的寫法會(huì)自動(dòng)查找文件是否修改,如果沒有修改就不會(huì)編譯,從而提高效率
工作原理:通過比較修改時(shí)間,目標(biāo)應(yīng)該比依賴的修改時(shí)間遲,如果發(fā)現(xiàn)目標(biāo)比依賴的修改時(shí)間早則重新生成目標(biāo)。
進(jìn)進(jìn)階makefile文件
上面的寫法有些冗余,通過變量來將寫法變得簡潔
obj=main.o add.o sub.o mul.o target=app $(target):$(obj) //$取obj變量中的值gcc $^ -o $@ //模式規(guī)則 %.o:%.cgcc -c $< -o &@makefile中的自動(dòng)變量:
- $<規(guī)則中的第一個(gè)依賴
- $@規(guī)則中的目標(biāo)
- $^規(guī)則中的所有依賴
- 只能夠在規(guī)則中的命令來使用
makefile自己維護(hù)的變量: - 都是大寫,例如CC,CPPFLAGS,CFLAGS,LDFLAGS
進(jìn)進(jìn)進(jìn)階makefile文件
在makefile中的函數(shù)都是有返回值的
- 獲取指定目錄下所有的.c文件
- 獲取指定目錄下所有的.o文件
- 自動(dòng)刪除以前生成的目標(biāo)文件
生成文件 時(shí)候:
make clean #會(huì)刪除目標(biāo)文件,只會(huì)執(zhí)行生成clean的語句如果目錄中真的存在clean目標(biāo),則會(huì)提示目標(biāo)是最新的而不會(huì)運(yùn)行。
.PHONY:clean #聲明clean為偽目標(biāo),不會(huì)與目錄中的目標(biāo)進(jìn)行比較在命令前面加上-,則命令執(zhí)行失敗以后也不會(huì)停下來,繼續(xù)向后執(zhí)行
總結(jié)
以上是生活随笔為你收集整理的Linux命令【三】gcc编译+静态库+动态库+makefile+gdb调试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都大熊猫繁育基地上午去好还是下午去好
- 下一篇: Linux命令【四】文件+虚拟内存+常用