4.編寫規則

ignorantshr發表於2019-01-06

本系列文章均翻譯自make官方文件:make Manual,github同步專案:question

Phony Targets

一個偽目標不是一個真正的檔名,只是一個當你明確的執行make請求時會被執行的recipe名字。有兩個原因使用偽目標:

  • 避免同名檔案衝突
  • 提升效能

解決的問題:

clean:
        rm *.o temp

這種寫法在沒有檔名衝突的時候可以通過make clean正常執行。但是如果在這個目錄下有一個同名的檔案cleanclean總是會被考慮是最新的檔案,它的recipe不會執行。

新增一個偽目標即可解決這個問題:

.PHONY: clean
clean:
        rm *.o temp

與make的遞迴呼叫結合使用:

SUBDIRS = foo bar baz

subdirs:
        for dir in $(SUBDIRS); do \
          $(MAKE) -C $$dir; \
        done

這種寫法的問題:任何在sub-make中的錯誤都會被忽視;不能並行構建目標。

改進後的寫法:

SUBDIRS = foo bar baz

.PHONY: subdirs $(SUBDIRS)

subdirs: $(SUBDIRS)

$(SUBDIRS):
        $(MAKE) -C $@

foo: baz

最後一句宣告瞭baz完成之後才能構建foo。

對於偽目標將跳過隱含規則的搜尋。

偽目標不應該成為一個真實的目標檔案的prerequisites,負責每次make更新檔案都會執行偽目標的recipe

偽目標也可以有prerequisites

all : prog1 prog2 prog3
.PHONY : all

prog1 : prog1.o utils.o
        cc -o prog1 prog1.o utils.o

prog2 : prog2.o
        cc -o prog2 prog2.o

prog3 : prog3.o sort.o utils.o
        cc -o prog3 prog3.o sort.o utils.o

一個偽目標的prerequisites是另一個偽目標時,表現為另一個的子程式:

.PHONY: cleanall cleanobj cleandiff

cleanall : cleanobj cleandiff
        rm program

cleanobj :
        rm *.o

cleandiff :
        rm *.diff

執行順序:rm *.o -> rm *.diff -> rm program

相關文章