makefile--偽目標語法與程式設計例項

sun_shine發表於2018-03-06

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
複製程式碼

命令列執行結果如下:

makefile--偽目標語法與程式設計例項
分析: 執行make clean命令會將當前目錄下的所有.o檔案和hello.out一起刪除;而當再次執行make clean的時候由於當前目錄下已經沒有.o檔案和hello.out檔案,所以會出現提示資訊無法移除檔案

程式設計實驗2:(make以檔案處理作為第一優先順序)

當前目錄結構如下:

示例
main.c func.c makefile檔案內容均與程式設計實驗1保持一致,命令列執行結果如下:

makefile--偽目標語法與程式設計例項

分析: 由於當前目錄下存在檔案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

相關文章