Compiling
僅在需要時重新製作包含 makefile
假設我有一個 Makefile,它有兩個“主要”目標:
foo.o
和clean
. 前者有一個創建foo.o
文件的方法。後者刪除所有臨時文件。為了消除
foo.o
手動指定依賴項的需要,我的目標foo.d
是有效的 makefile,指定格式的依賴項foo.o foo.d : dep1 dep2 depn
。此依賴文件包含在 makefile 中。生成文件如下所示:
;; This buffer is for text that is not saved, and for Lisp evaluation. ;; To create a file, visit it with C-x C-f and enter text in its buffer. foo.o: foo.c cc -c -o $@ $< foo.d: foo.c sh deps.sh $< > $@ include foo.d .PHONY: clean clean: rm …
當我想製作
foo.o
時,一切正常:foo.d
得到(重新)製作,它被包含foo.o
並被製作。問題是當我想製作clean
目標時,foo.d
被包含,甚至被製作。如何防止製作包括製作目標的
foo.d
時間clean
?(或者,如何僅在foo.o
製作時包含它?)該解決方案可以使用 GNU Make 的功能。
解決方案非常簡單,但會導致 Makefile 程式碼有些不可讀。
首先,我們必須知道
include
指令試圖包含該文件,如果它不存在,則失敗。如果文件不存在,也有-include
(或sinclude
)不包含該文件。但這不是我們想要的,因為它仍然會嘗試重新製作包含的 makefile,如果可能的話。我們可以通過兩種方式避免這種情況:要麼以 Makefile 認為它無法生成包含文件的方式更改 include 指令參數(例如相對路徑與絕對路徑等),要麼在文件不包含時省略參數存在。這可以通過多種方式完成:
-include $(wildcard foo.d*)
但這有一個問題:它也匹配其他文件。所以我們可以這樣寫:
-include $(filter foo.d,$(wildcard foo.d*))
甚至這個:
-include $(filter foo.d,$(wildcard *))
而我們又犯了一個問題:
foo.d
沒有得到。這可以通過將其添加為的另一個目標來解決foo.o
:foo.o: foo.c foo.d
或將其添加為命令:
foo.o: foo.c $(MAKE) foo.d cc …
或直接,不呼叫
make
:foo.o: foo.c sh script.sh … cc …