1. 程式人生 > >【makefile學習記錄3】偽目標的引入

【makefile學習記錄3】偽目標的引入

通過前兩課的學習,我們知道makefile中的基本組成的元素是規則。那麼makefile中的目標究竟是什麼呢?

在預設情況下:

  • make認為目標對應著一個檔案;
  • make比較目標檔案和依賴檔案的新舊關係,決定是否執行命令;
  • make以檔案處理作為第一優先順序。

make的誕生就是為了自動管理和編譯一個專案中的C程式檔案。當我們有以下makefile檔案時:

hello.out all : fun.o main.o
     gcc fun.o main.o -o hello.out
fun.o : fun.c
     gcc -c fun.c -o fun.o 
main.o : main.c
     gcc -c main.c -o main.o
clean :
     rm *.o hello.out

執行make clean時,刪除當前目錄檔案下所有的.o檔案和hello.out檔案。但是噹噹前目錄存在一個與clean目標同名的檔案時,執行make clean時,提示clean是最新的,makefile中clean處所對應的命令不予執行。是因為make預設情況下認為目標對應著檔案,檔案無變化時即不執行相應命令。

1、makefile中的偽目標

  • 通過.PHONY關鍵字宣告為一個偽目標
  • 偽目標不對應任何實際的檔案
  • 不管偽目標的依賴更新與否,命令總是執行

偽目標的語法: 先宣告,後使用。

    本質:偽目標是make中特殊目標.PHONY的依賴

用法為:

.PHONY : clean
##註釋##
clean : 
    rm *.o hello.out

此時即可暢通無阻的執行clean處的命令。

2、偽目標的妙用:規則掉用(函式呼叫)

原理:當一個目標的依賴包含偽目標時,偽目標所定義的命令總是會被執行。

hello.out : fun.o main.o
     gcc fun.o main.o -o hello.out
fun.o : fun.c
     gcc -c fun.c -o fun.o 
main.o : main.c
     gcc -c main.c -o main.o

.PHONY : clean rebulid all
rebuild : clean all 
all : hello.out
clean :
     rm *.o hello.out

當makefile改為以上內容時,執行rebuild檔案,先刪除之前的,在執行all生成新的檔案。

技巧:繞開.PHONY關鍵字定義偽目標

原理:如果一個規則沒有命令或者依賴,並且它的目標不是一個存在的檔名,執行此規則時,目標總會被認為是最新的。

背景:當我們所使用的編譯器為GNU MAKE時,.PHONY是標準的關鍵字。但是當我們所使用的編譯器不是的時候,就不能用.PHONY關鍵字來定義偽目標。此時我們可以改為如下:

clean : FORCE
    rm *.o hello.out
FORCE :

此時,每次執行make時,都會執行clean處的命令,並且避開了以.PHONY關鍵字來定義偽目標。因為當一個目標沒有命令或者依賴,並且它不是一個已經存在的檔名,在執行此規則時,目標總會認為是最新的。