天天看點

make的靜态模式

make的靜态模式

靜态模式可以更加容易地定義多目标的規則,可以讓我們的規則變得更加的有彈性和靈活。我們還是先來看一下文法:

<targets ...>: <target-pattern>: <prereq-patterns ...>

<commands>

...

targets定義了一系列的目标檔案,可以有通配符。是目标的一個集合。

target-pattern是指明了targets的模式,也就是的目标集模式。

prereq-patterns是目标的依賴模式,它對target-pattern形成的模式再進行一次依賴目标的定義。

這樣描述這三個東西,可能還是沒有說清楚,還是舉個例子來說明一下吧。如果我們的<target-pattern>定義成“%. o”,意思是我們的<target>集合中都是以“.o”結尾的,而如果我們的<prereq-patterns>定義成 “%.c”,意思是對<target-pattern>所形成的目标集進行二次定義,其計算方法是,取<target- pattern>模式中的“%”(也就是去掉了[.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”。而指令中的“$<”和“$@”則是自動化變量,“$<”表示所有的依賴目标集(也就是 “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”有幾百個,那種我們隻要用這種很簡單的“靜态模式規則”就可以寫完一堆規則,實在是太有效率了。“靜态模式規則”的用法很靈活,如果用得好,那會一個很強大的功能。再看一個例子:

files = foo.elc bar.o lose.o

$(filter %.o,$(files)): %.o: %.c

$(filter %.elc,$(files)): %.elc: %.el

emacs -f batch-byte-compile $<

$(filter %.o,$(files))表示調用Makefile的filter函數,過濾“$files”集,隻要其中模式為“%.o”的内容。其的它内容,我就不用多說了吧。這個例子展示了Makefile中更大的彈性。

原文

http://wiki.ubuntu.org.cn/index.php?title=%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:%E4%B9%A6%E5%86%99%E8%A7%84%E5%88%99&variant=zh-hant