Makefile介紹:
make命令屬於gnu工具(gcc,g++,gdb,make,cvs,patch,diff,binutils等),make命令會在當前目錄下按順序查找文件“Makefile”、“makefile”、“GNUmakefile”,也可以使用其他的名字來書寫Makefile,需要再make後面使用 “-f”、“-file”參數來指定文件名,如:make -f Make.Linux;每條規則中的命令和操作系統 Shell的命令行是一致的。make會一按順序一條一條的執行命令,每條命令的開頭必須以[Tab]鍵開頭,除非 命令是緊跟在依賴規則後面的分號後的。在命令行之間中的空格或是空行會被忽略,但是如果該空格或空行是以Tab鍵開頭的,那麼make會認爲其是一個空命令。
一、自動化變量:
$^:代表所有依賴的文件
$@:代表目標
$<:代表第一個依賴的文件
大多說的c/c++編譯器都支持一個”-M“的選項,即自動尋找文件中依賴的頭文件,如果使用的是GNU的c/c++編譯器,需要使用”-MM“參數,否則”-M“會將
標準庫的頭文件包含進來
二、靜態模式與多目標
<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>
targets定義了一系列的目標文件,可以有通配符。是目標的一個集合。
target-parrtern是指明瞭targets的模式,也就是的目標集模式。
prereq-parrterns是目標的依賴模式,它對target-parrtern形成的模式再進行一次依賴目標的定義。
例1:展開:
obj = foo.o bar.o foo.o:foo.c
all: $(obj) $(CC) -c $(CFLAGS) foo.c -o foo.o
$(obj): %.o : %.c => bar.o: bar.c
$(CC) -c $(CFLAGS) $< -o $@ $(CC) -c $(CFLAGS) bar.c -o bar.o
注:上面的例子中,指明瞭我們的目標從$object中獲取,“%.o”表明要所有以“.o”結尾的目標,也就是“foo.o bar.o”,也就是變量
$object集合的模式,而依賴模式“%.c”則取模式“%.o”的“%”,也就是“foo bar”,併爲其加下“.c”的後綴,於是,我們的依賴目標
就是“foo.c bar.c”。
例2:
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o :%.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc:%.el
emacs -f batch-byte-compile
注:$(filter %.o,$(files))表示調用Makefile函數,過濾”$filter“集合,只要其中模式爲"%.o"的內容
三、 清空目標文件的規則:
每個Makefile中都應該有一個清空目標文件(.o)的規則,這不僅便於重新編譯,也很利於保持文件的清潔;
1、clean:
rm edit $(obj)
2、更爲穩健的方式
.PHONY: clean
clean:
-rm edit $(obj)
.PHONY表示clean是一個“僞目標”在行前面加上 “-”表示即使出問題,略過,仍要繼續後面的操作。clean 最好放在Makefile的最後。”make
clean" 將清除所有被清除的文件。”cleanobj“ 和 ”cleandiff“這兩個僞目標有點像子程序。可以通過輸入”make cleanall“和 ”make cleanobj“以
及”makediff“來達到清除不同類文件的目的
三、引用其他Makefile
1)include <filename> #filename 可以是當前操作系統Shell的文件模式(可以保含路徑和通配符)
如: include foo.mk
注:在include前面可以有一些空字符,但是絕不能是[Tab]鍵開始。
三、在規則中引用通配符
和shell相同make支持“*”,“?”,“[...]”三個通配符。
obj = *.o #表示obj的值爲"*.o",並不是所有的 .o文件,如果想代表所有的.o文件則 obj = $(wildcard *.o)
注:在Makefile中的命令,必須要以[Tab]鍵開始,Makefile第一次編譯的錯誤不會爲致命錯誤,會在整個
Makefile編譯結束,再次重新編譯錯誤位置,如果還未通過則生成致命錯誤
4、shell函數 (:來自 《跟我一起寫Makefile》)
shell函數與其他函數不同,它的參數應該就是linux命令。shell函數把執行操作系統命令後的輸出作爲函數返回值。如:
contents:=$(shell cat foo) 或者 files:=$(shell echo *.c)
注意,這個函數會生成一個shell程序執行命令,所以你要注意其運行性能,如果在Makefile中有比較複雜的規則,並且大量使用該函數,那麼對於你的系統性能是有害的
特別的是Makefile的隱晦的規則可能會讓你的shell函數執行的次數比你想象的多得多。