我們來思考一下makefile中的目標究竟是什么?實際上,在默認情況下:
1、make將makefile的目標認為是一個文件;
2、make解釋器比較目標文件和依賴文件的新舊關系,決定是否執行命令;
3、make以文件作為第一優先級。
如果不進行特殊的makefile控制,make解釋器在解析makefile文件時,在解析到一個規則時,會將這個規則中的目標認為是一個文件,並進一步判斷目標文件和依賴文件的新舊關系。
編寫以下的makefile文件,並執行make clean。
正常情況下,當前目錄下的*.o hello.out文件全部被刪除了,沒有任何錯誤,但當我們在當前目錄下新建一個名字為clean的文件,然后再執行make clean,此時會提示clean文件是最新的。如下所示:
這是因為make解釋器默認將clean目標當作一個文件處理,而不是一個標簽。將clean當成一個文件時,make發現當前目錄下有此文件,而且此目標沒有依賴,即認為目標是最新的。最終make給出了clean是最新的結論。
那么怎么解決這個問題呢?幸好,gun make中提供了關鍵字.PHONY,這個關鍵字用於定義一個偽目標,此時,偽目標不再對應任何實際的文件,make不再將偽目標當作文件處理,而是當成一個標簽。不管偽目標的依賴是否更新,命令總是執行。將程序更改如下所示:
此時,保持當前目錄下存在clean文件,並再次執行make clean,可以成功刪除相應的文件。此時,make不再將clean目標當作文件處理,而是始終執行這個目標下的命令。
偽目標的用法是先聲明后使用,偽目標實質:偽目標是make中特殊目標.PHONY的依賴。
偽目標的妙用:規則調用(函數調用),如下所示:
上圖定義了三個偽目標,當執行make rebuild時,clean目標對應的規則會先被執行,然后執行all目標對應的規則。原理為:當一個目標的依賴包含偽目標時,偽目標所定義的命令總是會被執行。這樣就完成了規則調用的目的,執行rebuild規則,該規則調用clean和all規則。
繞開.PHONY關鍵字定義偽目標,.PHONY是gun make中的關鍵字,在其他平台中,或許不存在這個關鍵字,那么怎么辦呢?請看如下處理方式。
定義一個目標FORCE,該目標沒有依賴,該規則下也沒有命令,並讓clean依賴這個目標。此時,就算當前路徑下存在clean文件,執行make clean時,clean目標對應的命令也始終會被執行。
原理:
如果一個規則沒有命令或者依賴,並且它的目標不是一個存在的文件名;在執行此規則時,目標總會被認為是最新的。當前目錄下不能有文件名為FORCE的文件存在。FORCR總會被認為是最新的,因此,即使當前目錄下有clean文件,那么clean對應的規則也會被執行。
參考如下:
狄泰軟件教程與課件
GUN make手冊
專業嵌入式軟件開發
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
