- make/makefile介紹
1.1 基本認(rèn)識(shí)
make是一個(gè)命令,makefile是一個(gè)文件(Makefile和makefile是相同的,字母大小寫不影響),這是我們首先需要了解的。
1.2 依賴關(guān)系、依賴方法
為什么需要這個(gè)自動(dòng)化構(gòu)建工具呢?當(dāng)我們創(chuàng)建一個(gè)文件并在其中寫入內(nèi)容后,需要使用gcc或g++工具進(jìn)行編譯。如果文件被修改后,我們需要重新編譯,這時(shí)又得輸入命令gcc -o 目標(biāo)文件 源文件。每一次修改后輸入編譯命令都很麻煩,這時(shí)我們可以使用自動(dòng)化構(gòu)建工具,通過依賴關(guān)系和依賴方法來解決這個(gè)問題。
1.3 具體操作步驟
首先,創(chuàng)建一個(gè)test.c文件,并使用vim在其中寫入內(nèi)容,可以通過不同模式之間的切換來實(shí)現(xiàn)。然后,創(chuàng)建一個(gè)makefile文件,里面包含依賴關(guān)系和依賴方法。
在makefile中,”test:test.c”表示依賴關(guān)系,意思是test文件是test.c文件編譯后的結(jié)果。第二行是依賴方法,即編譯的命令。
clean命令用于清理編譯生成的文件,使用的是”rm -f test”。
創(chuàng)建makefile文件和寫入test.c文件后,直接使用make命令。make命令會(huì)執(zhí)行makefile中的第一個(gè)命令,即編譯test.c文件。這樣,我們就不需要重復(fù)輸入編譯命令。但要注意,第一次使用make后,如果再次使用,系統(tǒng)會(huì)提示”test up to date”,表示test文件(編譯后的文件)已保存,除非對(duì)test.c內(nèi)容進(jìn)行修改,否則無法重新編譯。
輸入”make clean”命令,可以清除編譯生成的文件。
1.4 進(jìn)一步理解源文件到可執(zhí)行文件
我們可以將這個(gè)過程寫得更復(fù)雜一些,顯示中間文件的生成過程,然后重新編譯,分析依賴關(guān)系和依賴方法。
在這個(gè)例子中,test文件依賴于test.o文件,test.o依賴于test.s文件,test.s依賴于test.i文件,test.i依賴于test.c文件。這個(gè)過程類似于遞歸過程(實(shí)際操作中可以使用簡(jiǎn)便寫法)。
這個(gè)例子是為了說明多層依賴關(guān)系在執(zhí)行時(shí)的順序問題。使用make命令時(shí),執(zhí)行順序與makefile中寫入的順序相反,類似于遞歸的歸過程。由于依賴關(guān)系,后出現(xiàn)的指令會(huì)先被執(zhí)行,因?yàn)樽钕刃枰氖莟est.i文件,它直接由test.c文件生成,按照這個(gè)順序才能實(shí)現(xiàn)編譯過程。
實(shí)際上,我們輸入的是4組指令,每組都有依賴關(guān)系和依賴方法。我們可以隨意更換這4組指令的順序,輸出結(jié)果不變,可以正常運(yùn)行。因此,make會(huì)自動(dòng)推導(dǎo)makefile中的依賴關(guān)系,與順序無關(guān)。但如果缺少任意一個(gè)中間環(huán)節(jié),過程將無法正常運(yùn)行,因?yàn)樗鼈冎g是相互依賴的。
1.5 默認(rèn)設(shè)置
make會(huì)自頂向下訪問命令。我們?cè)趍akefile中添加新的內(nèi)容,即文件的清理。什么是默認(rèn)設(shè)置呢?就是在執(zhí)行make命令時(shí),會(huì)默認(rèn)執(zhí)行文件編譯的中間過程。要清理文件,需要使用”make clean”命令。這是因?yàn)樵谀J(rèn)的make命令作用下,會(huì)先執(zhí)行上面的文件指令。如果我們將清理指令放在gcc命令的前面,就會(huì)優(yōu)先執(zhí)行清理命令。
但我們一般不會(huì)將文件清理放在前面,因?yàn)槲覀冞€需要對(duì)相關(guān)文件進(jìn)行操作,刪除清理后就無法操作了。
1.6 make二次使用的解釋
第一次編譯后使用make會(huì)執(zhí)行相關(guān)操作,但第二次或更多次使用make就無法有效發(fā)揮作用,這是為了提高編譯效率。
如何做到:源文件編譯成可執(zhí)行文件時(shí),如果源文件最近修改時(shí)間早于可執(zhí)行文件,我們對(duì)源文件修改后(未編譯),新文件比可執(zhí)行程序更新,這時(shí)可以直接使用make命令(這時(shí)會(huì)重新編譯)。
這也是為什么文件編譯一次后只能make一次,但修改后就可以再次使用make命令的原因。
1.7 兩個(gè)文件的時(shí)間問題
我們上面介紹了源文件和可執(zhí)行文件的時(shí)間早晚問題,以確定make命令能否有效使用。在Linux中,我們可以使用stat命令查看相關(guān)時(shí)間。
“stat test.c”顯示源文件的相關(guān)時(shí)間,”stat test”顯示編譯后的可執(zhí)行文件的相關(guān)時(shí)間,stat命令用于查看時(shí)間,后面可以跟文件名。
顯示的內(nèi)容相同,只是具體數(shù)值不同:
下面顯示了文件的相關(guān)信息,access是訪問文件的最新時(shí)間(訪問范圍較廣,使用cat查看文件內(nèi)容、修改文件內(nèi)容、打開文件等都算訪問),modify是修改時(shí)間,change相當(dāng)于改變,兩個(gè)很相似,有什么區(qū)別呢?簡(jiǎn)稱ACM。
之前介紹權(quán)限時(shí)說過,文件=文件內(nèi)容+文件屬性,modify相當(dāng)于改變文件內(nèi)容,只對(duì)文件屬性進(jìn)行修改,我們稱之為change。因此,對(duì)文件操作時(shí),可能修改文件內(nèi)容和屬性,內(nèi)容就是modify,屬性就是change。
但這三個(gè)時(shí)間不是割裂的,改變文件內(nèi)容時(shí),modify時(shí)間肯定變,文件內(nèi)容改變會(huì)引起文件大小改變,change時(shí)間也會(huì)改變,要修改內(nèi)容肯定要打開文件,access時(shí)間也會(huì)改變,因此這三個(gè)時(shí)間不是沒有聯(lián)系。
1.8 總是被執(zhí)行
我們上面介紹的時(shí)間,實(shí)際上是判斷源文件和目標(biāo)文件的生成時(shí)間,以決定make是否會(huì)被執(zhí)行。如果我們希望make命令輸入后一定被執(zhí)行,可以在第一行前面添加”.PHONY:文件名字”。
上面的就是makefile中應(yīng)該輸入的內(nèi)容,使用make后就會(huì)發(fā)現(xiàn)它一定會(huì)被執(zhí)行。但我們一般不會(huì)這樣做,可以將總是被執(zhí)行的設(shè)置放在clean那一行,這樣我們的清除操作就可以總是被執(zhí)行(默認(rèn)實(shí)際上也可以被多次執(zhí)行),但并不一定只有文件清理的其他指令,這不是多此一舉,書寫格式如下所示:
1.9 特殊符號(hào)介紹
我們?cè)谑褂胓cc進(jìn)行編譯時(shí),@可以表示依賴關(guān)系前面的文件,^可以表示依賴關(guān)系后面的文件,我們可以使用這些符號(hào)代替涉及到的兩個(gè)文件。
但實(shí)際上在查看文件內(nèi)容時(shí),這些特殊符號(hào)會(huì)以文件名的形式回顯出來。
我們?cè)诿钋懊嫣砑右粋€(gè)@符號(hào),就可以讓make后的結(jié)果不會(huì)顯示在屏幕上,這是隱藏功能。