第四部分、Makefile總述
一、Makefile 裡有什麼?
Makefile 裡主要包含了五個東西:顯式規則、隱晦規則、變數定義、檔案指示和註釋。
1 、顯式規則
顯式規則說明了,如何生成一個或多的的目標檔案。這是由 Makefile 的書寫者明顯指出,要生成的檔案,檔案的依賴檔案,生成的命令。
2 、隱晦規則
由於我們的 make 有自動推導的功能,所以隱晦的規則可以讓我們比較粗糙地簡略地書寫 Makefile
3 、變數的定義
當 Makefile 被執行時,其中的變數都會被擴充套件到相應的引用位置上。
4 、檔案指示
其包括了三個部分:
a. 在一個 Makefile 中引用另一個 Makefile,就像 C 語言中的include 一樣;
b. 根據某些情況指定 Makefile 中的有效部分,就像 C 語言中的預編譯#if 一樣;
c. 定義一個多行的命令
5 、註釋
Makefile 中只有行註釋,和 UNIX 的 Shell 指令碼一樣,其註釋是用“#”字元,這個就像 C/C++中的“//”一樣。如果你要在你的 Makefile 中使用“#”字元,可以用反斜框進行轉義,如:“\#”。
二、Makefile 的檔名
預設的情況下,make 命令會在當前目錄下按順序找尋檔名為“GNUmakefile”、“makefile”、“Makefile”的檔案,找到了解釋這個檔案。當 然 , 你 可 以 使 用 別 的 文 件 名 來 書 寫 Makefile , 比 如 : “Make.Linux” ,
“Make.Solaris”,“Make.AIX”等,如果要指定特定的 Makefile,你可以使用 make 的“-f”和“--file”引數,如:make -f Make.Linux 或 make --file Make.AIX。
三、引用其它的 Makefile
在 Makefile 使用 include 關鍵字可以把別的 Makefile 包含進來,這很像 C 語言的#include,被包含的檔案會原模原樣的放在當前檔案的包含位置。include 的語法是:
include <filename>
filename 可以是當前作業系統 Shell 的檔案模式(可以保含路徑和萬用字元) 在 include前面可以有一些空字元,但是絕不能是[Tab]鍵開始。include 和<filename>可以用一個或多個空格隔開。
舉個例子,你有這樣幾個 Makefile:a.mk、b.mk、c.mk,還有一個檔案叫foo.make,以及一個變數$(bar),其包含了 e.mk 和 f.mk,那麼,下面的語句:
include foo.make *.mk $(bar)
等價於:
include foo.make a.mk b.mk c.mk e.mk f.mk
如果檔案都沒有指定絕對路徑或是相對路徑的話,make 會在當前目錄下首先尋找,如果當前目錄下沒有找到,那麼,make 還會在下面的幾個目錄下找:
a. 如果 make 執行時,有“-I”或“--include-dir”引數,那麼 make 就會在這個引數所指定的目錄下去尋找
b. 如果目錄<prefix>/include(一般是:/usr/local/bin 或/usr/include)存在的話,make 也會去找。
如果你想讓 make不理那些無法讀取的檔案,而繼續執行,你可以在 include 前加一個減號“-”。
如: -include <filename>
其表示,無論 include 過程中出現什麼錯誤,都不要報錯繼續執行。
四、環境變數 MAKEFILES
如果你的當前環境中定義了環境變數 MAKEFILES,那麼,make 會把這個變數中的值做一個類似於 include 的動作。這個變數中的值是其它的 Makefile,用空格分隔。只是,它和 include不同的是,
從這個環境變數中引入的 Makefile 的“目標”不會起作用,如果環境變數中定義的檔案發現錯誤,make 也會不理。有時候你的 Makefile 出現了怪事,那麼你可以看看當前環境中有沒有定義這個變數。
五、make 的工作方式
GNU 的 make 工作時的執行步驟入下:
1、讀入所有的 Makefile。
2、讀入被 include 的其它 Makefile。
3、初始化檔案中的變數。
4、推導隱晦規則,並分析所有規則。
5、為所有的目標檔案建立依賴關係鏈。
6、根據依賴關係,決定哪些目標要重新生成。
7、執行生成命令。
1-5 步為第一個階段,6-7 為第二個階段。第一個階段中,如果定義的變數被使用了,那麼,make 會把其展開在使用的位置。但 make 並不會完全馬上展開,如果變量出現在依賴關係的規則中,
那麼僅當這條依賴被決定要使用了,變數才會在其內部展開。