經過長時間學習linux makefile檔案,我針對乙個簡單的例項進行了對linux makefile檔案的總結:於是和大家分享一下,看完本文你肯定有不少收穫,希望本文能教會你更多東西。
#sample makefile
edit : main.o kbd.o command.o display.o \ #第一次:作為目標「edit」的依賴檔案列表出現
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \#第二次:規則命令列中作為「cc」的引數列表
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
在書寫時,乙個較長行可以使用反斜線(\)分解為多行,這樣做可以使makefile清晰、容易閱讀。注意:反斜線之後不能有空格(這也是大家最容易犯的錯誤,而且錯誤比較隱蔽)。大家在書寫makefile時,推薦者中將較長行分解為使用反斜線連線得多個行的方式。當我們完成了這個maekfile以後;建立可執行程式 「edit」,你所要做的就是在包含此makefile的目錄(當然也在**所在的目錄)下輸入命令「make」。刪除已經本目錄下生成的檔案和所有的.o檔案,只需要輸入命令「make clean」就可以了。
為了避免編寫**時工作量重複的這個問題,在實際工作中大家都比較認同的方法是,使用乙個變數「objects」、「objects」、 「objs」、「objs」、「obj」或者「obj」來作為所有的.o檔案的列表的替代。在使用到這些檔案列表的地方,使用此變數來代替。在上例的 makefile中可是新增這樣一行:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
「objects」作為乙個變數,它代表所有的.o檔案的列表。在定義了此變數後,我們就可以在需要使用這些.o檔案列表的地方使用「$(objects)」來表示它,而不需要羅列所有的.o檔案列表。因此上例的規則就可以這樣寫:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
…….…….
clean :
rm edit $(objects)
需要增加或者去掉乙個.o檔案時。我們只需要改變「objects」的定義(加入或者去掉若干個.o檔案)。這樣做不但減少維護的工作量,而且可以避免由於遺漏而產生錯誤的可能。
在使用make編譯.c原始檔時,可以省略編譯乙個.c檔案所使用的命令。這是因為make存在乙個預設的規則,能夠自動完成對.c檔案的編譯並生成對應的.o檔案。它執行命令「cc -c」來編譯.c原始檔。對於上邊的例子,此預設規則就使用命令「cc -c main.c -o main.o」來建立檔案「main.o」。
書寫makefile時,對於乙個.c檔案如果使用make的隱含規則,那麼它會被自動作為對應.o檔案的乙個依賴檔案(對應是指:檔名除字尾外,其餘都相同的兩個檔案)。因此我們也可以在規則中省略目標的倚賴.c檔案。
上邊的例子就可以以更加簡單的方式書寫,使用了變數「objects」。簡化版本的makefile
gun make中文手冊如下:
# sample makefile
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.phony : clean
clean :
rm edit $(objects)
書寫規則建議的方式是:單目標,多依賴。就是說盡量要做到乙個規則中只存在乙個目標檔案,可有多個依賴檔案。盡量避免多目標,單依賴的方式。這樣後期維護也會非常方便,而且makefile會更清晰、明了。
.phony : clean
clean :
-rm edit $(objects)
這兩個實現有兩點不同: 1. 通過「.phony」特殊目標將「clean」目標宣告為偽目標。防止當磁碟上存在乙個名為「clean」檔案時,「clean」所在規則的命令無法執行。2. 在命令列之前使用「-」,意思是忽略命令「rm」的執行錯誤。
預設的情況下,make會在工作目錄(執行make的目錄)下按照檔名順序尋找linux makefile檔案讀取並執行,查詢的檔名順序為:「gnumakefile」、「makefile」、「makefile」。
如果make程式在工作目錄下無法找到以上三個檔案中的任何乙個,它將不讀取任何其他檔案作為解析物件。當linux makefile檔案的命名不是這三個任何乙個時,需要通過make的「-f」或者「--file」選項來指定make讀取的makefile檔案。給make指定makefile檔案的格式為:「-f name」或者「—file=name」,它指定檔案「name」作為執行make時讀取的linux makefile檔案。也可以通過多個「-f」或者「--file」選項來指定多個需要讀取的 makefile檔案,多個makefile檔案將會被按照指定的順序進行連線並被make解析執行。當通過「-f」或者「--file」指定make讀取makefile的檔案時,make就不再自動查詢這三個標準命名的makefile檔案
make是如何工作的
在預設的方式下,也就是我們只輸入make命令。那麼,
1、make會在當前目錄下找名字叫「makefile」或「makefile」的檔案。
2、如果找到,它會找檔案中的第乙個目標檔案(target),在上面的例子中,他會找到「
edit」這個檔案,並把這個檔案作為最終的目標檔案。
3、如果edit檔案不存在,或是edit所依賴的後面的 .o 檔案的檔案修改時間要比edit這個
檔案新,那麼,他就會執行後面所定義的命令來生成edit這個檔案。
4、如果edit所依賴的.o檔案也不存在,那麼make會在當前檔案中找目標為.o檔案的依賴性
,如果找到則再根據那乙個規則生成.o檔案。(這有點像乙個堆疊的過程)
5、當然,你的c檔案和h檔案是存在的啦,於是make會生成 .o 檔案,然後再用 .o 檔案生
命make的終極任務,也就是執行檔案edit了。
這就是整個make的依賴性,make會一層又一層地去找檔案的依賴關係,直到最終編譯出第
乙個目標檔案。在找尋的過程中,如果出現錯誤,比如最後被依賴的檔案找不到,那麼ma
ke就會直接退出,並報錯,而對於所定義的命令的錯誤,或是編譯不成功,make根本不理
。make只管檔案的依賴性,即,如果在我找了依賴關係之後,冒號後面的檔案還是不在,
那麼對不起,我就不工作啦。
通過上述分析,我們知道,像clean這種,沒有被第乙個目標檔案直接或間接關聯,那麼它
後面所定義的命令將不會被自動執行,不過,我們可以顯示要make執行。即命令——「ma
ke clean」,以此來清除所有的目標檔案,以便重編譯。
於是在我們程式設計中,如果這個工程已被編譯過了,當我們修改了其中乙個原始檔,比如fi
le.c,那麼根據我們的依賴性,我們的目標file.o會被重編譯(也就是在這個依性關係後
面所定義的命令),於是file.o的檔案也是最新的啦,於是file.o的檔案修改時間要比ed
it要新,所以edit也會被重新鏈結了(詳見edit目標檔案後定義的命令)。
而如果我們改變了「command.h」,那麼,kdb.o、command.o和files.o都會被重編譯,並
且,edit會被重鏈結。
linux makefile檔案分析
cflags wall wstrict prototypes g fomit frame pointer ffreestanding all crt0.s leds.c arm linux gcc cflags c o crt0.o crt0.s arm linux gcc cflags c o l...
Linux makefile檔案的編寫
main.c include mytool1.h include mytool2.h intmain int argc,char ar mytool1.h ifndef mytool 1 h define mytool 1 h void mytool1 print char print str en...
linux makefile檔案管理工程
make在執行時,需要乙個命名為makefile的檔案.make廢了檔案描述了整個工程編譯,鏈結的規則.其中包括 工程中的哪些原始檔需要編譯以及如何編譯 需要建立哪些庫檔案以及如何建立這些庫檔案 如何最後產生我們想要得可執行檔案.這就是乙個規則 targets prerequisites comma...