1?什么是Makefile
? ? 在之前學(xué)習(xí)C程序的編譯過(guò)程中,我們知道編譯一個(gè)程序還比較簡(jiǎn)單, 如果要編譯多個(gè)文件,或者不同文件夾中的文件,需要生成不同的庫(kù)文件,以及確定這些文件的編譯先后順序,往往所需要的命令行特別多,而且比較復(fù)雜,甚至對(duì)于以后項(xiàng)目的維護(hù)也比較麻煩。
? ? 再想想如果我們需要編譯Linux內(nèi)核這樣好幾W個(gè)文件的項(xiàng)目難道需要我們一個(gè)命令的輸入嗎 ? 那估計(jì)是一場(chǎng)噩夢(mèng)。
?
? ? 那么這個(gè)時(shí)候如果我們能夠把所有的編譯規(guī)則全部規(guī)范到文件中,然后通過(guò)解析該文件去執(zhí)行對(duì)應(yīng)的編譯指令,這樣就大大簡(jiǎn)化指令的復(fù)雜度,同時(shí)降低了編譯程序過(guò)程中所帶來(lái)的錯(cuò)誤。
? ? 根據(jù)上面的需求就產(chǎn)生了Makefile,我們的編譯和處理規(guī)則就放在Makefile文件中,通過(guò)Makefile工具解析Makefile文件中的命令來(lái)指導(dǎo)整個(gè)工程的編譯過(guò)程。
? ? 當(dāng)然Makefile文件中的命令書(shū)寫(xiě)是有一定的規(guī)范的,這也是今天我們所要講到的重點(diǎn),一旦該文件編寫(xiě)好以后在Linux命令行中執(zhí)行一條make命令即可自動(dòng)編譯整個(gè)工程,不但提高了開(kāi)發(fā)效率也便于后期維護(hù)。
? ? 當(dāng)然不同廠(chǎng)家的make稍有不同,并且語(yǔ)法上也有點(diǎn)區(qū)別,不過(guò)基本思想都差不多,主要還是落在目標(biāo)依賴(lài)上來(lái),這里以最廣泛的GNU Make跟大家講解。
2?Makefile文件基本規(guī)則
? ? 上面的為大家展示了Makefile的核心規(guī)則,有點(diǎn)類(lèi)似于一位廚師做菜,目標(biāo)就是做一碗好菜,那么所謂的依賴(lài)就是各種食材、各種廚具等等,然而有了這些依賴(lài)還不夠需要廚師有著非常好的廚藝才能做出一道好菜。
? ? 同時(shí)這些依賴(lài)也有可能此時(shí)此刻并不存在,需要現(xiàn)場(chǎng)制作,或者由其他廚師做好,那么這個(gè)依賴(lài)就成為了其他規(guī)則的目標(biāo),該目標(biāo)也會(huì)有它自己的依賴(lài)和命令,這樣形成一層一層遞歸依賴(lài)組成了Makefile文件。
? 總結(jié)
Makefile并不會(huì)關(guān)心命令是如何執(zhí)行的,僅僅只是會(huì)去執(zhí)行所定義的命令,和我們平時(shí)直接輸入命令行是一樣的效果。
Makefile就相當(dāng)于一個(gè)依賴(lài)關(guān)系文件,在執(zhí)行該文件的以后會(huì)遞歸的查找依賴(lài)文件并執(zhí)行對(duì)應(yīng)的命令,最終生成第一個(gè)目標(biāo)。
3?簡(jiǎn)單使用Makefile
? ? 下面小哥就之前代碼簡(jiǎn)單演示一下Makefile:
? ? 上圖是makefile文件,最終為了生成Test文件,需要三個(gè)*.o文件,然后三個(gè).o文件又分別依賴(lài)于對(duì)應(yīng)的*.c文件,這樣加上對(duì)應(yīng)的gcc命令就構(gòu)成了一個(gè)基本的makefile。
? ? 注意 : 2/4/6/8行均為tab鍵。
? ? 下面使用make命令來(lái)編譯生成test目標(biāo)文件
? ? 這樣我們執(zhí)行make命令一鍵就搞定了所有的編譯任務(wù),如果下次需要改變編譯過(guò)程就直接修改對(duì)應(yīng)的makefile文件中的規(guī)則即可。
? ? 有類(lèi)比過(guò)windows里面IDE環(huán)境中編譯器使用的小伙伴都知道在windows里面的開(kāi)發(fā)工具編譯通過(guò)一鍵即可搞定所有編譯內(nèi)容。難道windows中的開(kāi)發(fā)工具更強(qiáng)大一些?
? ? 其實(shí)不然,我們?cè)趙indows中構(gòu)建對(duì)應(yīng)的工程文件的過(guò)程中通過(guò)圖形界面就悄悄的把類(lèi)似的makefile文件給生成了,那么當(dāng)點(diǎn)擊編譯的時(shí)候就相當(dāng)于在命令行里面執(zhí)行make,其實(shí)都是類(lèi)似的,僅僅只是我們平時(shí)使用windows更多一點(diǎn),更加容易接受。
? ?當(dāng)然這里僅僅只是演示了一些最簡(jiǎn)單的操作,比較麻煩的還是命令部分可以使用到通配符和shell指令等等,這樣會(huì)增加一定的復(fù)雜度,其實(shí)makefile本身并沒(méi)有太大的難度。
? ? 下一節(jié)小哥將為大家補(bǔ)充一些makefile更多便捷的操作,當(dāng)然現(xiàn)在也出現(xiàn)了許多類(lèi)似于cmake這樣的便捷工具,不過(guò)其核心還是makefile!
4?指定使用Makefile文件
? ? 在命令行中使用make命令,makefile會(huì)在默認(rèn)路徑中查找對(duì)應(yīng)的makefile文件來(lái)進(jìn)行工程管理,我們一般把對(duì)應(yīng)的makefile文件名命名為Makefile和makefile等,如果名字不匹配可能無(wú)法找到對(duì)應(yīng)的makefile文件,比如:
makefile文件名
Makefile文件名
MAKEFILE文件名-編譯失敗
? 從上面的實(shí)驗(yàn)現(xiàn)象可以了解到make會(huì)查找默認(rèn)的makefile文件名,如果沒(méi)有找到規(guī)定的文件名就會(huì)報(bào)相應(yīng)的故障。
? ? 不過(guò)如果平時(shí)在一個(gè)目錄下存在多個(gè)makefile文件的時(shí)候,一般我們都會(huì)通過(guò)不同命名來(lái)進(jìn)行區(qū)分,那么該如何指定對(duì)應(yīng)的makefile文件進(jìn)行識(shí)別解析呢 ?可以使用make -f選項(xiàng),如下圖所示:
5?注釋文本
? ? 在開(kāi)發(fā)過(guò)程中存在需要注釋掉makefile文件相應(yīng)文本行可以在文件的行首使用#號(hào):
? ? 上面是正常進(jìn)行makefile編譯目標(biāo)文件的完整實(shí)例,并且輸出了正確的結(jié)果,然后小哥使用#號(hào)屏蔽掉前面兩行,如下圖所示:
? ? 繼續(xù)執(zhí)行make命令,根據(jù)makefile的規(guī)則,會(huì)默認(rèn)編譯Test1.o目標(biāo)文件:
? ? 這樣我們獲得了正確的結(jié)果,說(shuō)明注釋生效。
6?取消回顯文本
? ? 在makefile使用過(guò)程中默認(rèn)是會(huì)把相應(yīng)的處理過(guò)程信息進(jìn)行回顯,這樣能夠讓開(kāi)發(fā)者更好的了解makefile的處理過(guò)程.
??? 不過(guò),如果回顯信息非常的龐大也是不利于開(kāi)發(fā)者分析的,所以編輯人員可以使用@來(lái)取消相關(guān)信息的回顯,如下圖所示:
在命令tab鍵后加入@
??? 這里我們可以看到使用make以后沒(méi)有像之前使用的makefile文件那樣存在回顯的命令行信息了。
7?偽目標(biāo)的使用
? ? 在makefile文件中有時(shí)候執(zhí)行一些不需要有依賴(lài)命令的目標(biāo),稱(chēng)為偽目標(biāo)。
? ? 上面是對(duì)應(yīng)的makefile文件,其中里面加入偽目標(biāo)clean,通過(guò)使用.PHONY修飾,這樣可以直接使用make clean 來(lái)執(zhí)行對(duì)應(yīng)的命令。
? ? 上面執(zhí)行make clean確實(shí)執(zhí)行了清除操作。
8?變量的使用
? ? 在makefile中為了減少代碼的重復(fù),使用變量的概念來(lái)簡(jiǎn)化編寫(xiě),如下面的makefile進(jìn)行如下改造:
? ??使用$(obj)來(lái)代替所有的目標(biāo)文件,以后需要添加其他目標(biāo)文件的話(huà)就只需要在變量obj處進(jìn)行相應(yīng)修改即可。
? ??同時(shí)系統(tǒng)還存在其他默認(rèn)的自動(dòng)化變量,這樣可以大大簡(jiǎn)化makefile文件,便于設(shè)計(jì)和后期維護(hù),如:
$^??? 表示所有的依賴(lài)文件
$@ ?? 表示生成的目標(biāo)文件
$?? 代表第一個(gè)依賴(lài)文件
等等? ??
? ? makefile基礎(chǔ)知識(shí)點(diǎn)小哥暫時(shí)就講到這里,其實(shí)大部分工程項(xiàng)目自己完完全全編寫(xiě)的并不是很多,更多的修修改改,所以遇到了具體的疑問(wèn)在進(jìn)行查找或許效率更高。
審核編輯:劉清
評(píng)論
查看更多