靜态模式
makefile中,一個規則中可以有多個目标,規則所定義的指令對所有的目标有效。一個具有多目标的規則相當于多個規則。使用多目标可以使makefile檔案變得簡潔。
靜态模式規則是這樣一個規則:規則存在多個目标,并且不同的目标可以根據目标檔案的名字來自動構造出依賴檔案。
靜态模式可以更加容易地定義多目标的規則,可以讓我們的規則變得更加的有彈性和靈活。我們還是先來看一下文法:
<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>
...
targets定義了一系列的目标檔案,可以有通配符。是目标的一個集合。
target-parrtern是指明了targets的模式,也就是的目标集模式。
prereq-parrterns是目标的依賴模式,它對target-parrtern形成的模式再進行一次依賴目标的定義。
簡單的解釋一下:如果我們的<target-parrtern>定義成 “%.o”,意思是我們的<target>集合中都是以“.o”結尾的,而如果我們的<prereq-parrterns>定義成“%.c”,意思是對<target-parrtern>所形成的目标集進行二次定義,其計算方法是,取<target- parrtern>模式中的“%”(也就是去掉了[.o]這個結尾),并為其加上[.c]這個結尾,形成的新集合。
是以,我們的“目标模式”或是“依賴模式”中都應該有“%”這個字元,如果你的檔案名中有“%”那麼你可以使用反斜杠“\”進行轉義,來标明真實的“%”字元。
看一個例子:
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
上面的例子中,指明了我們的目标從$object中擷取,“%.o”表明要所有以“.o”結尾的目标,也就是“foo.o bar.o”,也就是變量$object集合的模式,而依賴模式“%.c”則取模式“%.o”的“%”,也就是“foo bar”,并為其加下“.c”的字尾,于是,我們的依賴目标就是“foo.c bar.c”。而指令中的“$<”和“$@”則是自動化變量(見[makefile筆記]之七),“$<”表示所有的依賴目标集(也就是 “foo.c bar.c”),“$@”表示目标集(也就是“foo.o bar.o”)。于是,上面的規則展開後等價于下面的規則:
foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o
試想,如果我們的“%.o”有幾百個,那種我們隻要用這種很簡單的“靜态模式規則”就可以寫完一堆規則,實在是太有效率了