Makefile詳解(續(xù))

由于用的是Chrome,上一篇的末尾不知道為何突然退出隧饼,點(diǎn)進(jìn)去好多次,依然是一有動(dòng)作就自動(dòng)退出。之前用插件馬克飛象的時(shí)候就出現(xiàn)過(guò)這種情況较解。好像跟字?jǐn)?shù)有關(guān)系艺挪,字?jǐn)?shù)超過(guò)上限就會(huì)崩潰厢塘。

接上次的尉桩。這種方法,也就是make的隱式規(guī)則妻献。上面文件內(nèi)容中蛛株,.PHONY表示,clean是個(gè)偽目標(biāo)文件育拨。

另類風(fēng)格的makefile

既然我們的 make 可以自動(dòng)推導(dǎo)命令谨履,那么我看到那堆.o.h的依賴就有點(diǎn)不爽,那么多的重復(fù)的.h]熬丧,能不能把其收攏起來(lái)笋粟,其實(shí)這個(gè)對(duì)于make來(lái)說(shuō)還挺容易的。更為簡(jiǎn)潔的Makefile可以這樣寫(xiě):

objects = main.o kbd.o command.o display.o \
          insert.o search.o files.o utils.o

edit: $(objects)
    cc -o edit $(objects)

$(objects): defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o: buffer.h

.PHONY: clean
clean:
    rm edit $(objects)

這種風(fēng)格析蝴,讓我們的 makefile 變得很簡(jiǎn)單害捕,但我們的文件依賴關(guān)系就顯得有點(diǎn)凌亂了。魚(yú)和熊掌不可兼得闷畸。還得看個(gè)人喜好了尝盼。有些人是不喜歡這種風(fēng)格的,一是文件的依賴關(guān)系看不清楚佑菩,二是如果文件一多盾沫,要加入幾個(gè)新的.o文件,那就理不清楚了殿漠。

清空目標(biāo)文件的規(guī)則

每個(gè)Makefile中都應(yīng)該寫(xiě)一個(gè)清空目標(biāo)文件(.o和執(zhí)行文件)的規(guī)則赴精,這不僅便于重編譯,也很利于保持文件的清潔绞幌。一般的風(fēng)格都是:

clean:
    rm edit $(objects)

更為穩(wěn)健的做法是:

.PHONY : clean
clean :
    -rm edit $(objects)

前面說(shuō)過(guò)蕾哟,.PHONY意思表示 clean 是一個(gè)偽目標(biāo)。而在rm命令前面加了一個(gè)減號(hào)的意思就是莲蜘,也許某些文件出現(xiàn)問(wèn)題谭确,但不要管,繼續(xù)做后面的事菇夸。當(dāng)然琼富,clean 的規(guī)則不要放在文件的開(kāi)頭仪吧,不然庄新,這就會(huì)變成make的默認(rèn)目標(biāo),相信誰(shuí)也不愿意這樣。不成文的規(guī)矩是——“clean從來(lái)都是放在文件的最后”择诈。

Makefile文件名規(guī)則

默認(rèn)的情況下械蹋,make命令會(huì)在當(dāng)前目錄下按順序找尋文件名為GNUmakefilemakefile羞芍、Makefile的文件哗戈,找到了解釋這個(gè)文件。在這三個(gè)文件名中荷科,最好使用Makefile這個(gè)文件名唯咬,因?yàn)椋@個(gè)文件名第一個(gè)字符為大寫(xiě)畏浆,這樣有一種顯目的感覺(jué)胆胰。最好不要用 GNUmakefile,這個(gè)文件是GNU的 make 識(shí)別的刻获。有另外一些 make 只對(duì)全小寫(xiě)的makefile文件名敏感蜀涨,但是基本上來(lái)說(shuō),大多數(shù)的 make 都支持makefileMakefile這兩種默認(rèn)文件名蝎毡。

當(dāng)然厚柳,你可以使用別的文件名來(lái)書(shū)寫(xiě) Makefile,比如:Make.Linux沐兵,Make.Solaris别垮,Make.AIX等,如果要指定特定的 Makefile扎谎,你可以使用 make 的-f--file參數(shù)宰闰,如:make -f Make.Linuxmake --file Make.AIX

引用其他的Makefile

在Makefile使用include關(guān)鍵字可以把別的Makefile包含進(jìn)來(lái)簿透,這很像C語(yǔ)言的#include移袍,被包含的文件會(huì)原模原樣的放在當(dāng)前文件的包含位置。include的語(yǔ)法是:

include <filename>;

filename可以是當(dāng)前操作系統(tǒng)Shell的文件模式(可以包含路徑和通配符)老充。在include前面可以有一些空字符葡盗,但是絕不能是Tab鍵開(kāi)始。include<filename>;可以用一個(gè)或多個(gè)空格隔開(kāi)啡浊。

make 命令開(kāi)始時(shí)觅够,會(huì)找尋include所指出的其它 Makefile,并把其內(nèi)容安置在當(dāng)前的位置巷嚣。就好像C/C++的#include指令一樣喘先。如果文件都沒(méi)有指定絕對(duì)路徑或是相對(duì)路徑的話,make 會(huì)在當(dāng)前目錄下首先尋找廷粒,如果當(dāng)前目錄下沒(méi)有找到窘拯,那么红且,make還會(huì)在下面的幾個(gè)目錄下找:

  • 如果make執(zhí)行時(shí),有-I--include-dir參數(shù)涤姊,那么make就會(huì)在這個(gè)參數(shù)所指定的目錄下去尋找暇番。
  • 如果目錄<prefix>/include(一般是:/usr/local/bin/usr/include)存在的話,make 也會(huì)去找思喊。

如果有文件沒(méi)有找到的話壁酬,make會(huì)生成一條警告信息,但不會(huì)馬上出現(xiàn)致命錯(cuò)誤恨课。它會(huì)繼續(xù)載入其它的文件舆乔,一旦完成makefile 的讀取, make 會(huì)再重試這些沒(méi)有找到剂公,或是不能讀取的文件蜕煌,如果還是不行,make 才會(huì)出現(xiàn)一條致命信息诬留。如果你想讓 make 不理那些無(wú)法讀取的文件斜纪,而繼續(xù)執(zhí)行,你可以在include前加一個(gè)減號(hào)-文兑。如:-include <filename>;

總結(jié)

根據(jù)以上細(xì)節(jié)盒刚,關(guān)于Makefile的的基本組成和工作的流程就可總結(jié)如下。

Makefile里主要包含了五個(gè)東西:顯式規(guī)則绿贞、隱式規(guī)則因块、變量定義、文件指示和注釋籍铁。

  • 顯式規(guī)則涡上。顯式規(guī)則說(shuō)明了,如何生成一個(gè)或多個(gè)目標(biāo)文件拒名。要生成的文件吩愧,文件的依賴文件,生成的命令增显。
  • 隱式規(guī)則雁佳。由于 make 有自動(dòng)推導(dǎo)的功能,所以隱式規(guī)則可以讓我們比較簡(jiǎn)略地書(shū)寫(xiě)Makefile同云。
  • 變量的定義糖权。在Makefile中我們要定義一系列的變量,變量一般都是指代文件名或路徑名的字符串炸站,這個(gè)有點(diǎn)像C語(yǔ)言中的宏星澳,當(dāng) Makefile 被執(zhí)行時(shí),其中的變量都會(huì)被擴(kuò)展到相應(yīng)的引用位置上旱易。
  • 文件指示禁偎。其包括了三個(gè)部分腿堤,一個(gè)是在一個(gè) Makefile 中引用另一個(gè) Makefile,就像C語(yǔ)言中的include一樣届垫;另一個(gè)是指根據(jù)某些情況指定 Makefile 中的有效部分,就像C語(yǔ)言中的預(yù)編譯#if一樣全释;還有就是定義一個(gè)多行的命令装处。
  • 注釋。Makefile 中只有行注釋浸船,和Linux的Shell腳本一樣妄迁,其注釋是用#字符,這個(gè)就像C/C++中的//一樣李命。如果你要在你的 Makefile 中使用#字符登淘,可以用反斜線進(jìn)行轉(zhuǎn)義,如:#封字。

GNU的make工作時(shí)的執(zhí)行步驟如下:

  1. 讀入所有的Makefile黔州。
  2. 讀入被include的其它Makefile。
  3. 初始化文件中的變量阔籽。
  4. 推導(dǎo)隱式規(guī)則流妻,并分析所有規(guī)則。
  5. 為所有的目標(biāo)文件創(chuàng)建依賴關(guān)系鏈笆制。
  6. 根據(jù)依賴關(guān)系绅这,決定哪些目標(biāo)要重新生成。
  7. 執(zhí)行生成命令在辆。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末证薇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子匆篓,更是在濱河造成了極大的恐慌浑度,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸦概,死亡現(xiàn)場(chǎng)離奇詭異俺泣,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)完残,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門伏钠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谨设,你說(shuō)我怎么就攤上這事熟掂。” “怎么了扎拣?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵赴肚,是天一觀的道長(zhǎng)素跺。 經(jīng)常有香客問(wèn)我,道長(zhǎng)誉券,這世上最難降的妖魔是什么指厌? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮踊跟,結(jié)果婚禮上踩验,老公的妹妹穿的比我還像新娘。我一直安慰自己商玫,他們只是感情好箕憾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著拳昌,像睡著了一般袭异。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炬藤,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天御铃,我揣著相機(jī)與錄音,去河邊找鬼沈矿。 笑死畅买,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的细睡。 我是一名探鬼主播谷羞,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼溜徙!你這毒婦竟也來(lái)了湃缎?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蠢壹,失蹤者是張志新(化名)和其女友劉穎嗓违,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體图贸,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹂季,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疏日。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片偿洁。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沟优,靈堂內(nèi)的尸體忽然破棺而出涕滋,到底是詐尸還是另有隱情,我是刑警寧澤挠阁,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布宾肺,位于F島的核電站溯饵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锨用。R本人自食惡果不足惜丰刊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望增拥。 院中可真熱鬧啄巧,春花似錦、人聲如沸跪者。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)渣玲。三九已至,卻和暖如春弟晚,著一層夾襖步出監(jiān)牢的瞬間忘衍,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工卿城, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枚钓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓瑟押,卻偏偏與公主長(zhǎng)得像搀捷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子多望,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 來(lái)自陳浩的一片老文嫩舟,但絕對(duì)營(yíng)養(yǎng)。 示例工程:3 個(gè)頭文件*.h怀偷,和 8 個(gè) C 文件*.c家厌。 初 編譯過(guò)程,源文件...
    周筱魯閱讀 4,700評(píng)論 0 17
  • makefile關(guān)系到整個(gè)工程的編譯規(guī)則椎工,一個(gè)工程中的源文件不計(jì)其數(shù)饭于,按其類型、功能维蒙、模塊分別放在若干的目錄當(dāng)中掰吕,...
    Joe_HUST閱讀 1,883評(píng)論 0 3
  • @(linux 編程)[開(kāi)發(fā)技能, 工具使用] What is GNU Make Make 是控制工程中通過(guò)源碼生...
    orientlu閱讀 11,348評(píng)論 0 26
  • 今年小學(xué)的課減少了,只保留了Prek的課颅痊,于是待在Prek 教室里的時(shí)間多了許多畴栖。每天早上跟著Prek 的老師一起...
    素秋微菊閱讀 497評(píng)論 0 4
  • 170126 從前一日陰郁的情緒里慢慢恢復(fù),再怎么也得先面對(duì)眼前的考試八千。 和LuLu在廚房拉開(kāi)陣仗開(kāi)始學(xué)習(xí)吗讶,兩個(gè)人...
    XxXxXxN閱讀 157評(píng)論 0 0