Makefile教學: 一篇文章教會妳Phony

GUN官網上的教學對剛開始寫Makefile的學妹來說
大概是看得一頭霧水



簡單來說
.PHONY 一般來說有兩個目的:
    1. 為了避免定義的規則和工作目錄下的檔案名稱發生衝突
    2. 改善效能

      避免衝突

      Makefile 規則如下
      clean:
              rm *.o temp

      官方範例就是假設
      1.在妳的資料夾下已經有一個叫clean的檔案
      2.妳想要執行make clean

      /*注意*/
      可是在妳的目錄下已經有一個clean的檔案啦
      而且他沒有被更動 e.g.clean file永遠保持著最新的狀態
      所以妳的Makefile將永遠不會執行到clean這個目標

      所以說妳就得這麼做:
      .PHONY: clean
      clean:
              rm *.o temp

      告訴Makefile這個clean rule是純的目標,沒有其他意圖(產生檔案)的

      另外make在執行時, 也不會作其他隱性規則的檢查
      提升整個效能です

      改善效能方面還有第二點就是在for loop的時候
      #原來學妹寫的Makefile
      SUBDIRS = foo bar baz
      
      subdirs:
              for dir in $(SUBDIRS); do \
                $(MAKE) -C $$dir; \
              done

      這樣子make在執行的時候沒辦法走平行化模式
      因為目標只有一個,而且這樣寫如果中間發生錯誤
      make會繼續執行完剩下的目標
      這樣子會與我們預期的不同

      所以我們可以這樣寫來達到平行化
      SUBDIRS = foo bar baz
      
      .PHONY: subdirs $(SUBDIRS)
      
      subdirs: $(SUBDIRS)
      
      $(SUBDIRS):
              $(MAKE) -C $@
      
      foo: baz

      #官網這個範例也寫到同時我們可以建立一個規則是在先決條件baz完成前不能執行foo

      官網其他範例
      Phony也是可以有先決條件的唷

      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代替"make prog1 prog2 prog3"了呢

      Reference:
      GUN官方 Makefile教學4.6
      https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html

      留言

      1. 「官方範例就是假設
        1.在妳的資料夾下已經有一個叫clean的檔案
        2.妳想要執行make clean」

        應該是:
        ...假設
        1.在妳的資料夾下沒有叫clean的檔案?
        ...

        回覆刪除

      張貼留言