Phony Targets
PHONY 目标并非實際的檔案名:隻是在顯式請求時執行指令的名字。有兩種理由需要使用PHONY 目标:避免和同名檔案沖突,改善性能。
如果編寫一個規則,并不産生目标檔案,則其指令在每次make 該目标時都執行。例如:
clean:
rm *.o temp
因
為"rm"指令并不産生"clean"檔案,則每次執行"make
clean"的時候,該指令都會執行。如果目錄中出現了"clean"檔案,則規則失效了:沒有依賴檔案,檔案"clean"始終是最新的,指令永遠不會
執行;為避免這個問題,可使用".PHONY"指明該目标。如:
.PHONY : clean
這樣執行"make clean"會無視"clean"檔案存在與否。
已知phony 目标并非是由其它檔案生成的實際檔案,make 會跳過隐含規則搜尋。這就是聲明phony 目标會改善性能的原因,即使你并不擔心實際檔案存在與否。
完整的例子如下:
clean :
phony 目标可以有依賴關系。當一個目錄中有多個程式,将其放在一個makefile 中會更友善。因為預設目标是makefile 中的第一個目标,通常将這個phony 目标叫做"all",其依賴檔案為各個程式:
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
假設你的一個項目最後需要産生兩個可執行檔案。你的主要目标 是産生兩個可執行檔案,但這兩個檔案是互相獨立的——如果一
個檔案需要重建,并不影響另一個。你可以使用“假象目的”來 達到這種效果。一個假象目的跟一個正常的目的幾乎是一樣的,
隻是這個目的檔案是不存在的。是以, make 總是會假設它需要 被生成,當把它的依賴檔案更新後,就會執行它的規則裡的指令 行。
如果在我們的 makefile 開始處輸入:
all : exec1 exec2
其中 exec1 和 exec2 是我們做為目的的兩個可執行檔案。 make 把這個 'all' 做為它的主要目的,每次執行時都會嘗試把
'all' 更新。但既然這行規則裡沒有哪個指令來作用在一個叫 'all' 的 實際檔案(事實上 all 并不會在磁碟上實際産生),是以這個規
則并不真的改變 'all' 的狀态。可既然這個檔案并不存在,是以 make 會嘗試更新 all 規則,是以就檢查它的依靠 exec1,
exec2 是否需要更新,如果需要,就把它們更新,進而達到我們的目的。
假象目的也可以用來描述一組非預設的動作。例如,你想把所有由 make 産生的檔案删除,你可以在 makefile 裡設立這樣一個規則:
veryclean :
rm *.o
rm myprog
前提是沒有其它的規則依靠這個 'veryclean' 目的,它将永遠 不會被執行。但是,如果你明确的使用指令 'make veryclean' , make 會把這個目的做為它的主要目标,執行那些 rm 指令。
如果你的磁碟上存在一個叫 veryclean 檔案,會發生什麼事?這 時因為在這個規則裡沒有任何依靠檔案,是以這個目的檔案一定是
最新的了(所有的依靠檔案都已經是最新的了),是以既使使用者明 确指令 make 重新産生它,也不會有任何事情發生。解決方法是标
明所有的假象目的(用 .PHONY),這就告訴 make 不用檢查它們 是否存在于磁碟上,也不用查找任何隐含規則,直接假設指定的目
的需要被更新。在 makefile 裡加入下面這行包含上面規則的規則:
.PHONY : veryclean
就可以了。注意,這是一個特殊的 make 規則,make 知道 .PHONY 是一個特殊目的,當然你可以在它的依靠裡加入你想用的任何假象 目的,而 make 知道它們都是假象目的。