如何寫 makefile文件
學(xué)習(xí)別人的程序就面臨著重寫makefile的問(wèn)題.下面以問(wèn)答的形式來(lái)解釋如何寫makefile文件.
1.makefile的核心:
target...(目標(biāo)文件|object文件|可執(zhí)行文件|標(biāo)簽) : prerequisites( 生成target所需要的文件,也可以是target中的一種...)
Command (shell 命令)
target這一個(gè)或多個(gè)的目標(biāo)文件依賴于prerequisites中的文件,其生成規(guī)則定義在command中。prerequisites中如果有一個(gè)以上的文件比target文件更新的話,command所定義的命令就會(huì)執(zhí)行。
2.make 的工作原理:
例, 文件名:makefiletest
test : test.o
gcc -o test test.o
test.o: test.h test.c
gcc -c test.c
clean:
rm test.o test
在默認(rèn)方式下,只輸入make命令。其會(huì)做如下工作:
make會(huì)在當(dāng)前目錄下找名字為“Makefile文件”或“makefile文件”的文件。如果找到,它會(huì)找文件中的第一個(gè)目標(biāo)文件(target)。在上面的例子中,它會(huì)找到makefiletest這個(gè)文件,并把test作為最終的目標(biāo)文件;如果test文件不存在,或是test所依賴的后面的 .o 文件的修改時(shí)間要比test這個(gè)文件新,它就會(huì)執(zhí)行后面所定義的命令來(lái)生成test文件。
如果test所依賴的.o文件也存在,make會(huì)在當(dāng)前文件中找目標(biāo)為.o文件的依賴性,如果找到,則會(huì)根據(jù)規(guī)則生成.o文件(這有點(diǎn)像一個(gè)堆棧的過(guò)程)。
當(dāng)然,C文件和H文件如果存在,make會(huì)生成 .o 文件,然后再用 .o 文件生成make的最終結(jié)果,也就是執(zhí)行文件test。
這就是整個(gè)make的依賴性,make會(huì)一層又一層地去找文件的依賴關(guān)系,直到最終編譯出第一個(gè)目標(biāo)文件。在找尋的過(guò)程中,如果出現(xiàn)錯(cuò)誤,比如最后被依賴的文件找不到,make就會(huì)直接退出,并報(bào)錯(cuò)。而對(duì)于所定義的命令的錯(cuò)誤,或是編譯不成功,make就不會(huì)處理。如果在make找到了依賴關(guān)系之后,冒號(hào)后面的文件不存在,make仍不工作
通過(guò)上述分析,可以看出像clean這樣沒(méi)有被第一個(gè)目標(biāo)文件直接或間接關(guān)聯(lián)時(shí),它后面所定義的命令將不會(huì)被自動(dòng)執(zhí)行,不過(guò),可以顯式使make執(zhí)行。即使用命令make clean,以此來(lái)清除所有的目標(biāo)文件,并重新編譯。
在編程中,如果這個(gè)工程已被編譯過(guò)了,當(dāng)修改了其中一個(gè)源文件時(shí),比如test.c,根據(jù)依賴性,目標(biāo)test.o會(huì)被重新編譯(也就是在這個(gè)依賴性關(guān)系后面所定義的命令),則test.o文件也是最新的,即test.o文件的修改時(shí)間要比test要新,所以test也會(huì)被重新連接了。
3 定義變量:
ltest=test.h test.c
上面的makefiletest可以改寫為:
test : test.o
gcc -o test test.o
test.o: $(ltest)
gcc -c test.c
clean:
rm test.o test
4 makefile文件的自動(dòng)推導(dǎo)
test : test.o
gcc -o test test.o
test.o: test.h
clean:
rm test.o test
看一下test.o這個(gè)target,省略了 prerequisites的 test.c和command的gcc -c test.c,這些是target為test.o能推導(dǎo)出來(lái)的.
5 清空目標(biāo)文件
.PHONY : clean
clean :
-rm test.o test
前面說(shuō)過(guò),.PHONY表示clean是一個(gè)“偽目標(biāo)”,而在rm命令前面加了一個(gè)小減號(hào)的目的是,如果某些文 件出現(xiàn)問(wèn)題將被忽略,繼續(xù)進(jìn)行后面的操作。當(dāng)然,clean的規(guī)則不要放在文件的開(kāi)頭,否則會(huì)變成make的 默認(rèn)目標(biāo)。不成文的規(guī)矩是“clean從來(lái)都放在文件的最后”
6.注釋:
#. 為行注釋,與//類似
7.顯示指定makefile文件名
將makefiletest改為make.test
make -f make.test
8.TAB鍵
為command命令的識(shí)別鍵,在command頭使用,最好不要用在其它地方
9.包含 其它 makefile文件
include <filename>
filename可以是當(dāng)前操作系統(tǒng)Shell的文件模式(可以保含路徑和通配符)。在include前面可以有一些空字符,但是絕不能以[Tab]鍵開(kāi)始。include和<filename>可以用一個(gè)或多個(gè)空格隔開(kāi)。舉個(gè)例子,有這樣幾個(gè)makefile文件:a.mk、b.mk、c.mk,還有一個(gè)文件叫foo.make,以及一個(gè)變量$(bar),其包含了e.mk和f.mk,下面的語(yǔ)句:
include foo.make *.mk $(bar)
等價(jià)于:
include foo.make a.mk b.mk c.mk e.mk f.mk
10 -include和sinclude 都可以ignore error,
11. make的工作順序
(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í)行生成命令。
12.轉(zhuǎn)義字符與通配符
/
*,?,[...],~
其它請(qǐng)參見(jiàn)用戶手冊(cè).
聯(lián)系客服