1. Makefile的內(nèi)容
一個完整的 Makefile 中,包含了 5 個東西:顯式規(guī)則、隱含規(guī)則、變量定義、 指示符和注釋
1.1 顯式規(guī)則
描述了在何種情況下如何更新一個或者多個被稱為目標(biāo)的文件。
1.2 隱含規(guī)則
它是make根據(jù)一類目標(biāo)文件(典型的是根據(jù)文件名的后綴)而自 動推導(dǎo)出來的規(guī)則
1.3 變量定義
使用一個字符或字符串代表一段文本串
1.4 Makefile指示符
指示符指明在 make 程序讀取 makefile 文件過程中所要執(zhí) 行的一個動作。包含
- 讀取一個文件
- 決定(通常是根據(jù)一個變量的得值)處理或者忽略Makefile中的某一特定
部分 - 定義一個多行變量
1.5 注釋
Makefile 中“#”字符后的內(nèi)容被作為是注釋內(nèi)容(和 shell 腳本一樣) 處理。如果此行的第一個非空字符為“#”,那么此行為注釋行
2. Makefile文件的命名
2.1
一般情況下,make 會在工作目錄(執(zhí)行 make 的目錄)下按照文件名順序?qū)ふ?makefile 文件讀取并執(zhí)行,查找的文件名順序為:“GNUmakefile”、“makefile”、 “Makefile”。
2.2
通常應(yīng)該使用“makefile”或者“Makefile”作為 makefile 的文件名(建議使用 Makefile )
2.3
如果make程序在工作目錄下無法找到以上三個文件中的任何一個,它將不讀取任 何其他文件作為解析對象。
當(dāng) makefile 文件的命名不是這三個任何一個時,需要通過 make 的“-f”或者“--file”選項來指定 make 讀取的 makefile 文件。給 make 指定 makefile 文件的格式為:“-f NAME”或者“—file=NAME”。也可以指定多個文件,多個文件將按輸出順序解析。
3. 包含其它makefile文件
Makefile的文件包含和c語言一致,使用include關(guān)鍵字
-include FILENAMES...
4. 變量
4.1 MAKEFILES
如果在當(dāng)前環(huán)境定義了一個“MAKEFILES”環(huán)境變量,make執(zhí)行時首先將此變量的值作為需要讀入的Makefile文件,多個文件之間使用空格分開。類似使用指示符“include”,但是它和include有幾個區(qū)別
- 環(huán)境變量指定的makefile文件中的“目標(biāo)”不會被作為make執(zhí)行的“終極目 標(biāo)”。
- 環(huán)境變量所定義的文件列表,在執(zhí)行make時,如果不能找到其中某一個文件 (不存在或者無法創(chuàng)建)。make不會提示錯誤,也不退出
- make 在執(zhí)行時,
首先讀取的是環(huán)境變量“MAKEFILES”所指定的文件列表,“include”所指定的文件是在make發(fā)現(xiàn)此關(guān)鍵字的時暫停正在讀取的文件而轉(zhuǎn)去讀取“include”所指定的文件
實際應(yīng)用中很少設(shè)置此變量
4.2 MAKEFILE_LIST
MAKEFILE_LIST是make程序讀取的文件名自動添加的
4.3 VARIABLES
VARIABLES是一個特殊的變量,不能通過任何途經(jīng)給它賦值。它被展開為一個特定的值。
5 make解析Makefile文件過程
Gun make執(zhí)行過程分為兩個階段
- 讀取所有的Makefile文件(包含MAKEFILES變量指定的和include的以及命令行-file的),內(nèi)建所有的變量、明確規(guī)則和隱含規(guī)則并建立依賴關(guān)系結(jié)構(gòu)
- 根據(jù)第一階段建立的關(guān)系,覺得那些目標(biāo)需要更新,并依靠規(guī)則重建這些目標(biāo)
其中,在第一步如果變量和函數(shù)被展開,則成為立即展開,之后的展開,成為延后展開
5.1 立即和延后
5.1.1 條件語句
所有使用的條件語句,make會根據(jù)程序預(yù)設(shè)條件展開,即條件分支的展開是“立即”的,包含
“ifdef”、“ifeq”、“ifndef”和 “ifneq”
5.1.2 規(guī)則
IMMEDIATE : IMMEDIATE ; DEFERRED
[Tab] DEFERRED
規(guī)則中的目標(biāo)和依賴用到的變量,是立即展開,而命令行中的變量,則是延后展開
6 總結(jié)
make執(zhí)行過程如下
- 依次讀取變量“MAKEFILES”定義的makefile文件列表
- 讀取工作目錄下的 makefile 文件(根據(jù)命名的查找順序“GNUmakefile”,
“makefile”,“Makefile”,首先找到那個就讀取那個) - 依次讀取工作目錄makefile文件中使用指示符“include”包含的文件
- 查找重建所有已讀取的makefile文件的規(guī)則(如果存在一個目標(biāo)是當(dāng)前讀取的
某一個 makefile 文件,則執(zhí)行此規(guī)則重建此 makefile 文件,完成以后從第一步
開始重新執(zhí)行) - 初始化變量值并展開那些需要立即展開的變量和函數(shù)并根據(jù)預(yù)設(shè)條件確定執(zhí)行
分支 - 根據(jù)“終極目標(biāo)”以及其他目標(biāo)的依賴關(guān)系建立依賴關(guān)系鏈表
- 執(zhí)行除“終極目標(biāo)”以外的所有的目標(biāo)的規(guī)則(規(guī)則中如果依賴文件中任一個
文件的時間戳比目標(biāo)文件新,則使用規(guī)則所定義的命令重建目標(biāo)文件) - 執(zhí)行“終極目標(biāo)”所在的規(guī)則