#
演示目標體,依賴體和命令的簡單makefile文件
howdy: howdy.o helper.o helper.h
gcc howdy.o
helper.o -o howdy
helper.o: helper.c helper.h
gcc -c
helper.c
howdy.o: howdy.c
gcc -c howdy.c
hello: hello.c
gcc
hello.c -o hello
all: howdy hello
clean:
rm howdy hello
*.o
這個makefile文件包含6條規則.第一個目標體howdy稱為默認(default)目標體--這是make要創建的文件.howdy有3個依賴體,分別為howdy.o,helper.o和helper.h;要編譯生成howdy,必須要有這3個文件.
第二行調用編譯器的命令供make執行來創建howdy.把頭文件helper.h作為一個依賴體列入是為了避免編譯器調用未聲明的函數產生出錯信息.
接下來的兩條規則告訴make怎樣生成單個目標文件,helper.o和howdy.o.這些規則使用了gcc的-c選項,只創建目標文件但跳過鏈接.如果只想生成兩個目標文件而不生成howdy本身,可以使用下面兩條命令:
$make
helper.o
$make howdy.o
更簡潔一點,只需使用
$make helper.o howdy.o
makefile是一個文本形式的數據庫文件,其中包含一些規則告訴make編譯哪些文件,怎樣編譯以及在什么條件下去編譯.每條規則包含以下內容:
.一個"目標體"(target),即make最終需要創建的東西.
.包含一個或多個"依賴體"(dependency)的列表,依賴體通常是編譯目標體需要的其他文件.
.為了從指定的依賴體創建出目標體所需執行的"命令"(command)的列表.
雖然目標體通常是程序,但它們可以是諸如文本文件,手冊頁面等任何東西.目標體甚至能測試和設置環境變量.類似地,也可以定義依賴體以確保編譯開始前存在
某個特殊的環境變量.最后,makefile中的命令可以是編譯器的命令或shell命令,它們能設置環境變量,刪除文件,或者任何命令行所能完成的功
能,如從FTP站點下載文件等.GNU
make被調用后會順序查找名為GNUmakefile,makefile或Makefile的文件.出于某種原因,可能只是習慣和長期形成的約定吧,大
多數Linux程序員使用最后一種形式Makefile.
Makefile規則有下列通用形式:
target
: dependency [dependency [...]]
command
command
[...]
假設有下面這樣的一個makefile:
OBJS = editor.o screen.o keyboard.o
edit :
$(OBJS)
cc -o editor $(OBJS)
.PHONY : clean
clean
:
rm editor
$(OBJS)
此時,make就使用所謂的隱式規則,實際上,對每一個名為somefile.o的目標(object)文件,make首先找到與之相應的源代碼somefile.c,并且用gcc
-c somefile.c -o somefile.o
編譯生產這個目標文件.
實際的機制比這個所描述的要全面.目標文件(.o)可以從c,Pascal和Fortran等源代碼中生產,所以make也應去查找符合實際情況的相關文件.
通過定義用戶自己的隱式規則,模式規則提供了開展make的隱式規則的一種方法.模式規則類似于普通規則,但是它們的目標必定含有符號"%".這個符號可以與任何非空字符串匹配:為與目標中的"%"匹配,這個規則的相關文件部分也必須使用"%".例如,下面的規則:
%.o
:
%.c
告訴make所有形為somename.o的目標(object)文件都應從源文件somename.c編譯而來.
與隱式規則一樣,make預定義了一些模式規則:
%.o
: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
???????????????????????
常用的make命令行選項 選項?????????????? 說明 -f
file????????????指定makefile的文件名 -n????????????????
打印將需要執行的命令,但實際上并不執行這些命令 -Idirname??????????指定被包含的makefile所在的目錄 -s????????????????
在執行時不打印命令名 -w???????????????? 如果make在執行時改變目錄,打印當前目錄名 -Wfile????????????
如果文件已修改,則使用-n來顯示make將要執行的命令 -r????????????????
禁止使用所有make的內置規則 -d???????????????? 打印調試信息 -i????????????????
忽略makefile規則中的命令執行后返回的非零錯誤碼,此時,即使某個命令返回非零的退出狀態值,make仍將繼續執行. -k????????????????
如果某個目標編譯失敗,繼續編譯其他目標.通常,make在一個目標編譯失敗后終止 -jN????????????????每次運行N個命令,這里N是非零整數 |
如果在使用make時遇到問題,-d選項能夠使make在執行命令時打印打量的額外調試信息.其中包括如下信息:
.在重新編譯時make需要檢查的文件
.被比較的文件以及比較的結果
.需要被重新生產的文件
.make想要使用的隱式規則
.make實際使用的隱式規則以及所執行的命令
.No rule to make target 'target'.Stop
makefile中沒有包含創建指定的target所需要的規則,而且也沒有合適的默認規則可用.
.'target' is up to date 指定
target 的相關文件沒有變化.
.Target 'target' not remade because of errors
在編譯target時出錯,這一消息僅在使用make的-k選項時才會出現.
.command: Command not found make
找不到命令.通常是因為命令被拼寫錯誤或者不在路徑$PATH下.
.Illegal option - option
在調用make時包含了不能被make識別的選項.
出了clean的目標,外編寫makefile時還有一些常用的目標.
名為install的目標把最終的二進制,所支持的庫文件或shell腳本,以及相關的文檔移動到文件系統中與之相應的最終位置,并適當設置文件的權限和屬主.
uninstall目標則刪除由install目標所安裝的那些文件.
dist目標可以用來生產準備發布的軟件包.最低限度,dist目標將刪除編譯工作目標中舊的二進制文件和目標文件并創建一個歸檔文件(如普通的壓縮包),以便上載到萬維網頁或FTP站點.
indent能夠按照許多預先定義好的或者自定義的標準調整源代碼以及代碼縮進的格式以達到所需的風格.tags程序(它在emacs上的對應程序,
etags)生成的文件能夠增強編輯器瀏覽和分析源代碼的能力.lclint程序是在編譯源代碼之前做個快速語法檢查.它能檢查代碼,找出大量問題,包括
未聲明的變量和函數,可能的內存破壞(memory corruption),當然它能檢查的問題不僅僅就這幾種.
網上這類工具中最好的資源是"動態存儲分配和內存管理信息庫"(Dynamic Store
Allocation and Memory Management Information Repository),它的Web地址為 http://www.cs.colorado.edu/~zorn/DSA.html/.
|