1. 程式人生 > >[makefile 筆記]之一--Make的工作方式、命令執行、偽目標與冒號

[makefile 筆記]之一--Make的工作方式、命令執行、偽目標與冒號

GNU的make工作時的執行步驟入下:(想來其它的make也是類似)

     1、讀入所有的Makefile。
     2、讀入被include的其它Makefile。
     3、初始化檔案中的變數。
     4、推導隱晦規則,並分析所有規則。
     5、為所有的目標檔案建立依賴關係鏈。
     6、根據依賴關係,決定哪些目標要重新生成。
     7、執行生成命令。

命令執行

當依賴目標新於目標時,也就是當規則的目標需要被更新時,make會一條一條的執行其後的命令。需要注意的是,如果你要讓上一條命令的結果應用在下一條命令時,你應該使用分號分隔這兩條命令。比如你的第一條命令是cd命令,你希望第二條命令得在 cd之後的基礎上執行,那麼你就不能把這兩條命令寫在兩行上,而應該把這兩條命令寫在一行上,用分號分隔。如:

    示例一:
        exec:
                cd /home/hchen
                pwd

    示例二:
        exec:
                cd /home/hchen; pwd

當我們執行“make exec”時,第一個例子中的cd沒有作用,pwd會打印出當前的Makefile目錄,而第二個例子中,cd就起作用了,pwd會打印出“/home/hchen”。(因為第一個例子中兩條命令其實是在不同的shell中執行的)

make一般是使用環境變數SHELL中所定義的系統Shell來執行命令,預設情況下使用UNIX的標準Shell——/bin/sh來執行命令。

偽目標

最早先的一個例子中,我們提到過一個“clean”的目標,這是一個“偽目標”,

     clean:
             rm *.o temp

正像我們前面例子中的“clean”一樣,即然我們生成了許多檔案編譯檔案,我們也應該提供一個清除它們的“目標”以備完整地重編譯而用。 (以“make clean”來使用該目標)

因為,我們並不生成“clean”這個檔案。“偽目標”並不是一個檔案,只是一個標籤,由於“偽目標”不是檔案,所以make無法生成它的依賴關 系和決定它是否要執行。我們只有通過顯示地指明這個“目標”才能讓其生效。當然,“偽目標”的取名不能和檔名重名,不然其就失去了“偽目標”的意義了。

當然,為了避免和檔案重名的這種情況,我們可以使用一個特殊的標記“.PHONY”來顯示地指明一個目標是“偽目標”,向make說明,不管是否有這個檔案,這個目標就是“偽目標”。

     .PHONY : clean

只要有這個宣告,不管是否有“clean”檔案,要執行“clean”這個目標,只有“make clean”這樣。於是整個過程可以這樣寫:

      .PHONY: clean
     clean:
             rm *.o temp

關於冒號

      makefile中,“:”除了表示目標依賴關係外,還用於分隔不同的目錄,如:

      SRC_PATH ?= .:..