makefile文件的一些解读
hit2015spring晨鳧追風(fēng)歡迎關(guān)注我的博客晨鳧追風(fēng)
這篇文章算是一個學(xué)習(xí)的筆記吧,在很多的程序構(gòu)建過程中的一些東西
gcc編程的四個步驟
命令格式如下
Gcc [選項] 要編譯的文件 [選項] [目標(biāo)文件]其中[目標(biāo)文件]可以缺省,Gcc默認(rèn)生成可執(zhí)行的文件名為:要編譯的文件.out
例子:
# vi hello.c #include <stdlib.h> #include <stdio.h> void main(void) { printf("hello world!\r\n"); }編譯的命令為
gcc hello.c -o hello.exe輸出的是可執(zhí)行文件 hello.exe
預(yù)處理
Gcc –E hello.c –o hello.i主要處理#include和#define
把#include包含進來的.h文件插入到#include所在的位置 把源程序中使用到的#define定義,用實際定義的字符串代替上面命令中輸出的是.i文件,該文件是經(jīng)過預(yù)處理的C源程序。這個文件是可以查看的文本文件
編譯
首先檢查代碼規(guī)范,是否有語法錯誤 把代碼翻譯成匯編語言該階段的命令如下,它也可以接受.c后綴的文件
gcc -S hello.i -o hello.s輸出的是.s后綴名的文件,可以查看的文本文件
匯編
這個階段是把上面的匯編程序翻譯成二進制的機器指令文件這個階段接受的是.c或者.i或者.s文件都是沒有問題的
命令行如下,它可以接受.c或者.i或者.s
Gcc –c hello.s –o hello.o生成的是二進制文件,需要反匯編器GDB幫助才能讀懂
鏈接
這里涉及到兩種函數(shù)庫:
靜態(tài)庫:編譯鏈接時,把庫代碼全部加入到可執(zhí)行文件中去,生成的文件比較大,運行時不在需要庫文件,后綴名一般為.lib(win).a(Linux) 動態(tài)庫:在編譯鏈接時并沒有把庫文件代碼,加入到可執(zhí)行文件中,而是在程序執(zhí)行時,由運行時的鏈接文件加載庫,節(jié)省系統(tǒng)開銷,后綴一般為.dll(win).so(linux)這里生成庫的方法為:
生成靜態(tài)庫的方法: ar cr libxxx.a file1.o file2.o 就是把file1.o和file2.o打包生成libxxx.a靜態(tài)庫 使用的時候 gcc test.c -L/path -lxxx -o test 動態(tài)庫的話: gcc -fPIC -shared file1.c -o libxxx.so 也可以分成兩部來寫: gcc -fPIC file1.c -c //這一步生成file1.o gcc -shared file1.o -o libtest.so在運行程序時,需要在環(huán)境變量中指定動態(tài)庫的位置,這里舉例在Linux中的配置
export LD_LIBRARY_PATH=path這里需要說明一個情況:
庫中有同名的動態(tài)庫和靜態(tài)庫文件時,系統(tǒng)會優(yōu)先選擇鏈接動態(tài)庫,如果想要指定用靜態(tài)庫,則在編譯的時候加入編譯選項 -static,就會找到靜態(tài)庫。
靜態(tài)庫鏈接時的搜索路徑順序
1 ld會去找GCC命令中的參數(shù)-L 2 再找gcc的環(huán)境變量LIBRARY_PATH 3 再找內(nèi)定目錄 /lib /usr/lib /usr/local/lib 這是當(dāng)初compile gcc時寫在程序內(nèi)的動態(tài)庫鏈接執(zhí)行時的搜索路徑順序
1 編譯目標(biāo)代碼時指定的動態(tài)庫搜索路徑 2 環(huán)境變量LD_LIBRARY_PATH指定的動態(tài)庫搜索路徑 3 配置文件/etc/ld.so.conf中指定的動態(tài)庫搜索路徑 4 默認(rèn)的動態(tài)庫搜索路徑/lib 5 默認(rèn)的動態(tài)庫搜索路徑/usr/lib于是這個階段的命令如下
Gcc hello.o –o hello生成可執(zhí)行文件 hello
上面是用一個個命令行來對一個簡單的程序進行生產(chǎn)的過程,然而很多的工程需要很多的代碼,然后就有一個叫make的工具來管理這些文件。
Makefile文件的一些知識
make工具是根據(jù)Makefile文件來對編譯過程建立一個描述數(shù)據(jù)庫,這個數(shù)據(jù)庫記錄了所有各個文件之間的相互關(guān)系,以及它們的的關(guān)系描述,當(dāng)其中一個文件修改時,他通過比較前后兩個文件修改的時間來決定是不是需要重新編譯。
1 所有的文件都沒有被編譯過,則對各個C源文件進行編譯鏈接,生成可執(zhí)行程序
2 每一個在上次執(zhí)行make之后修改過的C源代碼文件,在本次執(zhí)行make時會被重新編譯
3 頭文件在上一次執(zhí)行make之后被修改。則所有的包含這個頭文件的C源文件在本次執(zhí)行Make時會被重新編譯
這些文件重新編譯生成中間文件.o文件,這些.o文件重新連接,就能形成可執(zhí)行文件
makefile簡單規(guī)則:
target ...:prerequisites .......command.......target是一個目標(biāo)文件,
1 可以是Object File 2 也可以是可執(zhí)行文件 3 標(biāo)簽prerequisites
是生成這個target所需要的文件或者目標(biāo)command 是
make需要執(zhí)行的命令target 這個目標(biāo)文件依賴于prerequisites這些文件,生成的規(guī)則在command里面,如果prerequisites里面有至少一個文件的時間比target要新的話,那就會執(zhí)行command命令
這個command命令是以一個Tab鍵作為開頭
make的工作方式:
這里舉個例子
edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o輸入make命令
“`
1 make會在當(dāng)前目錄下找到名字叫Mkaefile或者makefile的文件
2 如果找到了,它會找文件中的第一個目標(biāo)文件,并把它(上面的edit)作為最終的目標(biāo)文件
3 如果edit不存在或者后面所依賴的.o文件比它要新,就會執(zhí)行后面所定義的命令來生成這個edit文件
4 如果edit所依賴的.o文件也存在,那么make會在當(dāng)前文件中找目標(biāo)為.o文件的依賴性,如果找到了,就根據(jù)規(guī)則生成.o文件
“`
就像是剝洋蔥一樣,一層套著一層,直到最后的c代碼文件和H文件,最后編譯吃第一個目標(biāo)文件
make只是找文件之間的依賴關(guān)系,像clean這樣的,沒有被目標(biāo)文件關(guān)聯(lián)或者間接關(guān)聯(lián)的,那么它后面的命令將不會被自動執(zhí)行,但是可以用make指令顯式的要求執(zhí)行它 make clean
當(dāng)然 clean是放在最后的,這是一個不成文的規(guī)定吧
當(dāng)然還有很多的編譯選項沒有說明,會再接著學(xué)習(xí)記錄
福利答謝大家!
感謝您閱讀本篇文章,對此特別發(fā)放一個無門檻的現(xiàn)金紅包,打開支付寶掃碼領(lǐng)取,可以領(lǐng)到錢的哦!
總結(jié)
以上是生活随笔為你收集整理的makefile文件的一些解读的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TI公司dsp的cmd配置文件的说明
- 下一篇: 12星座的出生年月日性格_星座六点半/今