makefile中的目標的含義:
預設情況下,
- make認為目標對應著一個檔案
- make比較目標檔案和依賴檔案的新舊關係,決定是否執行命令
- make以檔案處理作為第一優先順序
程式設計實驗1:(make預設認為目標對應著一個檔案)
當前目錄結構如下:
func.c原始檔如下:void fun()
{
printf("void fun():hello makefile \n");
}
複製程式碼
main.c原始檔如下:
extern void fun();
int main()
{
fun();
return 0;
}
複製程式碼
makefile原始檔如下:
hello.out:main.o func.o
gcc -o hello.out main.o func.o
main.o:main.c
gcc -o main.o -c main.c
func.o:func.c
gcc -o func.o -c func.c
clean:
rm *.o hello.out
複製程式碼
命令列執行結果如下:
分析: 執行make clean命令會將當前目錄下的所有.o檔案和hello.out一起刪除;而當再次執行make clean的時候由於當前目錄下已經沒有.o檔案和hello.out檔案,所以會出現提示資訊無法移除檔案程式設計實驗2:(make以檔案處理作為第一優先順序)
當前目錄結構如下:
main.c func.c makefile檔案內容均與程式設計實驗1保持一致,命令列執行結果如下:分析: 由於當前目錄下存在檔案clean,故當執行make clean的命令時,make以檔案處理作為第一優先順序,而當前檔案已經是最新的,故不會再執行make clean命令。
出現此問題的解決方法為增加偽目標,,具體分析請看程式設計實驗3。
程式設計實驗3:(偽目標的引入,保證與目標的依賴無關,目標中的命令總是被執行)
當前目錄結構如下:
main.c func.c 檔案內容均與程式設計實驗1保持一致,makefile檔案做如下修改(在clean目標之前增加程式碼:.PHONY:clean):## makefile
hello.out :main.o func.o
gcc -o hello.out main.o func.o
main.o:main.c
gcc -o main.o -c main.c
func.o:func.c
gcc -o func.o -c func.c
.PHONY:clean
clean:
rm *.o hello.out
複製程式碼
命令列執行結果如下:
偽目標知識:
- 通過.PHONY關鍵字宣告一個偽目標
- 偽目標不對應任何實際的檔案
- 不管偽目標的依賴是否更新,命令總是執行
- 偽目標的語法:先宣告,後使用
本質:
偽目標是make中特殊目標.PHONY的依賴
程式設計實驗4(使用偽目標模擬C語言中的函式呼叫)
當前目錄結構如下:
main.c func.c 檔案內容均與程式設計實驗1保持一致,makefile檔案做如下修改(在clean目標之前增加程式碼:.PHONY:clean):## makefile
hello.out :main.o func.o
gcc -o hello.out main.o func.o
main.o:main.c
gcc -o main.o -c main.c
func.o:func.c
gcc -o func.o -c func.c
.PHONY:rebuild clean all
rebuild:clean all
all:hello.out
clean:
rm *.o hello.out
複製程式碼
- 原理: 當一個目標的依賴包含偽目標時,偽目標所定義的命令總是會被執行 命令列執行結果如下:
分析: 由於reuild、clean、all被.PHONY定義為偽目標;故每次執行rebuild、all、clean目標的時候與目標對應的命令都會被執行;所以當執行make rebuild的時候,實際上是先執行clean命令(移除當前目錄下所有的.o檔案和hello.out檔案),然後執行all命令(執行hello.out命令)
程式設計實驗5(繞開.PHONY關鍵字定義偽目標 )
- 原理: 如果一個規則沒有命令或者依賴,並且它的目標不是一個存在的檔名;在執行此規則時,目標總是會被認為是最新的
當前目錄結構如下: main.c func.c 檔案內容均與程式設計實驗1保持一致,makefile檔案做如下修改(將clean目標依賴於FORCE,而FORCE定義為空目標):
##makefile
hello.out :main.o func.o
gcc -o hello.out main.o func.o
main.o:main.c
gcc -o main.o -c main.c
func.o:func.c
gcc -o func.o -c func.c
clean:FORCE
rm *.o hello.out
FORCE:
複製程式碼
命令列執行結果如下:
- 分析: 因為FORCE目標是最新的,所以每次執行make clean的時候都會執行clean的命令
小結:
- 預設情況下,make認為目標對應著一個檔案
- .PHONY用於宣告一個偽目標,偽目標不對應實際的檔案
- 偽目標的本質是make中特殊目標.PHONY的依賴
- 使用偽目標可以模擬“函式呼叫”,方法請參考上文程式設計實驗5