1. 程式人生 > >makefile(01)_初識

makefile(01)_初識

makefile 偽目標 目標 依賴

0. 聲明

本系列(makefile)文章,從零基礎開始,通過實驗逐步分析makefile的語法特性,並最終打造一個可復用、可移植的專業編譯環境。
參考:
1.DT 唐老師門徒計劃課程
2.GNU make 手冊:http://www.gnu.org/software/make/manual/make.html

1.Make與makefile

  • Make是一個應用程序:接續源程序之間的依賴關系,根據依賴關系自動維護編譯工作,執行宿主操作系統中的各種命令。
  • Makefile是一個描述文件:定義了系列的規則來指定源文件編譯後的先後順序,擁有特定的語法規則,支持函數定義和函數調用,能夠直接集成操作系統的各種命令,本質上也是一種腳本。
    兩者的聯系:
  • Makefile中的描述用於指導make程序如何完成工作;
  • make根據Makefile中的規則執行命令,最後完成編譯輸出;
    簡單示例:
    hello: // 目標
    echo “hello makefile” // 實現目標要執行的命令,註意行首是一個table(\t)

make -f mf.txt hello // -f表示指定mf.txt文件為規則定義文件(Makefile),並執行文件裏的hello目標

make // 執行默認規則定義文件(Makefile/makefile)中的默認目標(第一個目標)

2.Makefile結構

2.1.Makefile的意義:

Makefile 用於定義源文件和依賴關系,說明如何編譯各個源文件並生成可執行文件
依賴的定義:

targets:prerequests; command1
Command2

2.2.Makefile中的元素含義:

targets         // 通常是需要生成的目標文件名,make所需要執行的命令名稱
prerequisite        // 當前目標所依賴的其他目標或文件
command         // 完成目標所需要的命令

2.3.註意事項:

目標和依賴可以有多個,使用空格分隔
每一個命令行必須以【tab】字符開始,用於高速make程序(解析器),此行時一個命令行

續行符: \ 可以將內容分開寫到下一行,提高可讀性
Makefile中可以在命令前加上@符,作用為命令無回顯(Makefile默認會打印執行的每一個條命令)

技巧:

開發中可以將可執行文件名和all 同時作為makefile中第一條規則的目標,這樣,當執行make命令並且目標已經存在時,將不會繼續執行(除非依賴文件有更新)

2.4.依賴規則:

當目標對應的文件不存在,執行對應命令
當依賴在時間上比目標更新,執行對應命令
當依賴關系發生時,對比依賴鏈上每一個目標

hello.out all : func.o main.o
    gcc -o hello.out func.o main.o

func.o : func.c
    gcc -o func.o -c func.c

main.o : main.c
    gcc -o main.o -c main.c

技術分享圖片

3.偽目標的引入

3.1.Makefile中的目標究竟是什麽?

默認情況下,make認為目標對應著一個文件,make會比較文件和依賴關系的新舊關系,決定執行是否執行命令,make以文件處理作為第一優先級。
所以當出現和目標同名的文件時,則在文件不被更新的前提下,目標不會被執行
技術分享圖片

3.2.Makefile中的偽目標

通過PHONY關鍵字聲明一個偽目標,偽目標不對應任何實際的文件,不管偽目標的依賴時否更新,命令總是執行。
偽目標的語法:先聲明,後使用
本質:偽目標是make中特殊的目標:.PHONY的依賴

.PHONY : clean

clean :
    rm *.o hello.out -rf 

3.3.偽目標的妙用:

規則調用,模擬C語言函數的概念。
原理:當一個目標的依賴包含偽目標時,偽目標所定義的命令總是會被執行。

.PHONY : rebuild clean all

rebuild : clean all

all : hello.out

clean :
    rm *.o hello.out  -rf 

3.4.繞開.PHONY關鍵字定義偽目標

原理:如果一個規則沒有命令或者依賴,並且他的目標不是一個存在的文件名,在執行此規則是,目標總會被認為是最新的。

clean : FORCE
    rm *.o hello.out -rf 
FORCE : 

makefile(01)_初識