1.1 makefile helloworld
Makefile的規(guī)則如下:
target ... : prerequisites ...
command ... ...
target可以是一個目標(biāo)文件,也可以是Object File(例如helloworld.obj),也可以是執(zhí)行文件和標(biāo)簽。
prerequisites就是生成target所需要的文件或是目標(biāo)。
command也就是要達(dá)到target這個目標(biāo)所需要執(zhí)行的命令。這里沒有說“使用生成target所需要執(zhí)行的命令”,是因為target可能是標(biāo)簽。需要注意的是command前面必須是TAB鍵,而不是空格,因此喜歡在編輯器里面將TAB鍵用空格替換的人需要特別小心了。
我們寫程序一般喜歡寫helloworld,當(dāng)我們寫了一個c的helloworld之后,我們該如何寫helloworld來編譯helloworld.c呢?
下面就是編譯helloworld的makefile。
helloworld : helloworld.o
cc -o helloworld helloworld .o
helloworld.o : helloworld.c
cc -c main.c
clean:
rm helloworld helloworl.o |
之后我們執(zhí)行make就可以編譯helloworld.c了,執(zhí)行make clean就可以清除編譯結(jié)果了(其實就是刪除helloworld helloworl.o)。
可能有人問為什么執(zhí)行make就會生成helloworld呢?這得從make的默認(rèn)處理說起:make將makefile的第一個target作為作為最終的
target,凡是這個規(guī)則依賴的規(guī)則都將被執(zhí)行,否則就不會執(zhí)行。所以在執(zhí)行make的時候,clean這個規(guī)則就沒有被執(zhí)行。
上面的是最簡單的makefile,復(fù)雜點makefile就開始使用高級點的技巧了,例如使用變量,使用隱式規(guī)則,執(zhí)行負(fù)責(zé)點shell命令(常見的是字符串處理和文件處理等),這里不打算介紹這些規(guī)則,后面在分析android的makefile時會結(jié)合具體代碼進(jìn)行具體分析,大家可以先看看陳皓的《跟我一起寫makefile》來了解了解。
makefile的大體的結(jié)構(gòu)是程序樹形的,如下:
這樣寫起makefile也簡單,我們將要達(dá)到的目標(biāo)作為第一個規(guī)則,然后將目標(biāo)分解成子目標(biāo),然后一個個寫規(guī)則,依次類推,直到最下面的規(guī)則很容易實現(xiàn)為止。這其實和算法里面的分治法很像,將一個復(fù)雜的問題分而治之。
說到樹,我想到了編譯原理里面的語法分析,語法分析里面有自頂而下的分析方法和自底而下的分析方法。當(dāng)然makefile并不是要做語法分析,而是要做與語法分析分析相反的事。(語法分析要做的是一個句子是不是根據(jù)語法可以推出來,而makefile要做的是根據(jù)規(guī)則生成一個command 執(zhí)行隊列。)不過makefile的規(guī)則和詞法分析還是很像的。下面出一道編譯原理上面的一個例子,大家可以理解一下makefile和詞法分析的不同點和相同點:
<標(biāo)識符> -> <字母><字母數(shù)字串>
<字母數(shù)字串> -> <字母><字母數(shù)字串>|<數(shù)字><字母數(shù)字串>|<下劃線><字母數(shù)字串>|ε
<無符號整數(shù)> -> <數(shù)字><數(shù)字串>
<數(shù)字串> -> <數(shù)字><數(shù)字串>|ε
<加法運算符> -> +
<減法運算符> -> -
<大于關(guān)系運算符> -> >
<大于等于關(guān)系運算符> -> >=
最后,介紹一下autoconfautomake,使用這兩個工具可以自動生成makefile。

從上面的圖可以看出,通過autoscan,我們可以根據(jù)代碼生成一個叫做configure.scan的文件,然后我們編輯這個文件,參數(shù)一個configure.in的文件。接著我們寫一個makefile.am的文件,然后就可以用automake生成makefile.in,最后,根據(jù)makefile.in和configure就可以生成makefile了。在很多開源的工程里面,我們都可以看到makefile.am,configure.in,makefine.in,configure文件,還有可能看到一個十分復(fù)雜的makefile文件,許多人學(xué)習(xí)makefile的時候想通過看這個文件來學(xué)習(xí),最終卻發(fā)現(xiàn)太復(fù)雜了。如果我們知道這個文件是自動生成的,就理解這個makefile文件為什么這個復(fù)雜了。
欲更加詳細(xì)的理解automake等工具,可以參考http://www.ibm.com/developerworks/cn/linux/l-makefile/。