這個第二部分的makefile教學會說明一些有關於makefile的細節,為前一部分的延伸,已挑選過章節,不會有太難太偏的內容。
在規則中使用通配符
make支援三個通配符:“*”,“?”和“~”。這是和Unix的B-Shell是相同的。
- "*" : "*"可以代表任何文字,"*.c"表示所有後綴為c的文件,例如 rm -f *.o。
- "?" : "?"僅代表單個字。
- "~" : "~"在文件名中也有比較特殊的用途。
如果是"~/test",這就表示當前用戶的$HOME目錄下的test目錄。而"~hchen/test"則表示用戶hchen的宿主目錄下的test目錄;在Windows或是 MS-DOS下,用戶沒有宿主目錄,那麼波浪號所指的目錄則根據環境變量“HOME”而定。
規則中使用通配符範例
clean: rm -f *.o
文件搜尋
在一些大的工程中,有大量的源文件,我們通常的做法是把這許多的源文件分類,並存放在不同的目錄中。所以,當make需要去找尋文件的依賴關係時,你可以在文件前加上路徑,但最好的方法是把一個路徑告訴make,讓make自動去找。
Makefile文件中的特殊變量“VPATH”就是完成這個功能的,如果沒有指明這個變量,make只會在當前的目錄中去找尋依賴文件和目標文件。如果定義了這個變量,那麼,make就會在當前目錄找不到的情況下,到所指定的目錄中去找尋文件了。
1. 特殊變量"VPATH"
VPATH = src : ../headers
上面的的定義指定兩個目錄,“src”和“../headers”,make會按照這個順序進行搜索。目錄由“冒號”分隔。當前目錄永遠是最高優先搜索的地方。
2. 使用make的“vpath”關鍵字
(注意 : vpath是全小寫的,不是變量,是一個make的關鍵字)
- a. vpath <pattern> <directories>
為符合模式<pattern>的文件指定搜索目錄<directories>。
例如:vpath %.h ../headers (“%”的意思是匹配零或若干字符) - b. vpath <pattern>
清除符合模式<pattern>的文件的搜索目錄。 - c. vpath
清除所有已被設置好了的文件搜索目錄。
偽目標
最早先的一個例子中,我們提到過一個“clean”的目標,這是一個“偽目標”,正像我們前面例子中的“clean”一樣,既然我們生成了許多文件編譯文件,我們也應該提供一個清除它們的“目標”以備完整地重編譯而用。 (以“make clean”來使用該目標)
clean: rm -f *.o
因為,我們並不生成“clean”這個文件。“偽目標”並不是一個文件,只是一個標籤,由於“偽目標”不是文件,所以make無法生成它的依賴關係和決定它是否要執行。我們只有通過顯式地指明這個“目標”才能讓其生效。當然,“偽目標”的取名不能和文件名重名,不然其就失去了“偽目標”的意義了。
.phony
為了避免在makefile中定義的只執行命令的目標和工作目錄下的實際文件出現名字沖突,另一種是提交執行makefile時的效率。
隱含規則 - 一般隱含規則
隱含規則也就是一種慣例,make會按照這種慣例運行,即使我們的Makefile中沒有書寫這樣的規則。
- 例如,把[.c]文件編譯成[.o]文件這一規則,不需撰寫make會自動推導出這種規則,並生成我們需要的[.o]文件。
另外,隱含規則會使用一些我們系統變量,我們可以改變這些系統變量的值來定製隱含規則的運行時的參數。
- 例如,系統變量"CFLAGS"可以控制編譯時的編譯器參數。
隱含規則範例
//隱含規則範例 foo : foo.o bar.o cc –o foo foo.o bar.o $(CFLAGS) $(LDFLAGS) //下面兩條規則可以省略: foo.o : foo.c cc –c foo.c $(CFLAGS) bar.o : bar.c cc –c bar.c $(CFLAGS)
隱含規則 - 變量隱含規則
在隱含規則中的命令中,基本上都是使用了一些預先設置的變量。你可以在你的makefile中改變這些變量的值,或是在make的命令行中傳入這些值,或是在你的環境變量中設置這些值,無論怎麼樣,只要設置了這些特定的變量,那麼其就會對隱含規則起作用。
我們可以把隱含規則中使用的變量分成兩種:一種是命令相關的,如"CC";一種是參數相的關,如"CFLAGS"。下面是所有隱含規則中會用到的變量:
1、關於命令的變量。
- AR : 函數庫打包程式。默認命令是“ar”。
- AS : 彙編語言編譯程式。默認命令是“as”。
- CC : C語言編譯程式。默認命令是“cc”。
- CXX : C++語言編譯程式。默認命令是“g++”。
- CO : 從 RCS文件中擴展文件程式。默認命令是“co”。
- CPP : C程式的預處理器(輸出是標準輸出設備)。默認命令是“$(CC) –E”。
- FC : Fortran 和 Ratfor 的編譯器和預處理程式。默認命令是“f77”。
- GET : 從SCCS文件中擴展文件的程式。默認命令是“get”。
- LEX : Lex方法分析器程式(針對於C或Ratfor)。默認命令是“lex”。
- PC : Pascal語言編譯程式。默認命令是“pc”。
- YACC : Yacc文法分析器(針對於C程式)。默認命令是“yacc”。
- YACCR : Yacc文法分析器(針對於Ratfor程式)。默認命令是“yacc –r”。
- MAKEINFO : 轉換Texinfo源文件(.texi)到Info文件程式。默認命令是“makeinfo”。
- TEX : 從TeX源文件創建TeX DVI文件的程式。默認命令是“tex”。
- TEXI2DVI : 從Texinfo源文件創建軍TeX DVI 文件的程式。默認命令是“texi2dvi”。
- WEAVE : 轉換Web到TeX的程式。默認命令是“weave”。
- CWEAVE : 轉換C Web 到 TeX的程式。默認命令是“cweave”。
- TANGLE : 轉換Web到Pascal語言的程式。默認命令是“tangle”。
- CTANGLE : 轉換C Web 到 C。默認命令是“ctangle”。
- RM : 刪除文件命令。默認命令是“rm –f”。
2、關於命令參數的變量
下面的這些變量都是相關上面的命令的參數。如果沒有指明其默認值,那麼其默認值都是空。
- ARFLAGS : 函數庫打包程式AR命令的參數。默認值是“rv”。
- ASFLAGS : 彙編語言編譯器參數。(當明顯地調用“.s”或“.S”文件時)。
- CFLAGS : C語言編譯器參數。
- CXXFLAGS :C++語言編譯器參數。
- COFLAGS : RCS命令參數。
- CPPFLAGS : C預處理器參數。( C 和 Fortran 編譯器也會用到)。
- FFLAGS : Fortran語言編譯器參數。
- GFLAGS : SCCS "get"程式參數。
- LDFLAGS : 鏈接器參數。(如:“ld”)
- LFLAGS : Lex文法分析器參數。
- PFLAGS : Pascal語言編譯器參數。
- RFLAGS : Ratfor 程式的Fortran 編譯器參數。
- YFLAGS : Yacc文法分析器參數。
知道 = 和 := 的差別 知道 patsubstr, wildcard 等指令用法
最後,介紹一下make程式的開發者,都是重量級人物。
Richard Stallman (RMS)
美國的自由軟體運動精神領袖、GNU工程的發起者以及自由軟體基金會的創立者。作為一個著名的黑客,他的主要作品包括Emacs及後來的GNU Emacs,GNU C編譯器及GNU除錯器。他所作的GNU通用公共許可證是世上最廣為採用的自由軟體許可證,為copyleft觀念開拓出一條嶄新的道路。
1990年代中期,斯托曼作為一個政治運動者,為自由軟體辯護,對抗軟體專利及版權法的擴張。他對程式設計方面的投入都放在Emacs上。
他最大的影響是為自由軟體運動豎立道德、政治及法律框架。他被許多人譽為當今自由軟體的鬥士、偉大的理想主義者。
個人主頁:http://www.stallman.org/
1990年代中期,斯托曼作為一個政治運動者,為自由軟體辯護,對抗軟體專利及版權法的擴張。他對程式設計方面的投入都放在Emacs上。
他最大的影響是為自由軟體運動豎立道德、政治及法律框架。他被許多人譽為當今自由軟體的鬥士、偉大的理想主義者。
個人主頁:http://www.stallman.org/
Roland McGrath
下面是他的一些事蹟:
- 合作編寫了並維護GNU make。
- 和Thomas Bushnell一同編寫了GNU Hurd。
- 編寫並維護GNU C library。
- 合作編寫並維護部分的GNU Emacs。
References
跟我一起寫Makefile
http://wiki.ubuntu.org.cn/index.php?title=%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:%E6%A6%82%E8%BF%B0&variant=zh-hant
Wiki - 理查·斯托曼
http://zh.wikipedia.org/wiki/%E7%90%86%E6%9F%A5%E5%BE%B7%C2%B7%E6%96%AF%E6%89%98%E6%9B%BC
跟我一起寫Makefile
http://wiki.ubuntu.org.cn/index.php?title=%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:%E6%A6%82%E8%BF%B0&variant=zh-hant
Wiki - 理查·斯托曼
http://zh.wikipedia.org/wiki/%E7%90%86%E6%9F%A5%E5%BE%B7%C2%B7%E6%96%AF%E6%89%98%E6%9B%BC