Makefile 学习 2 - 基于若干 Blog 的汇总
2019獨角獸企業重金招聘Python工程師標準>>>
基于若干 Blog 匯總的 makefile 教程
陳皓 https://blog.csdn.net/haoel/article/details/2886
Makefile 進階
1. Makefile 中的內容
2. Makefile 文件名
默認的情況下,make命令會在當前目錄下按順序找尋文件名為“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解釋這個文件。在這三個文件名中,最好使用“Makefile”這個文件名,因為,這個文件名第一個字符為大寫,這樣有一種顯目的感覺。最好不要用“GNUmakefile”,這個文件是GNU的make識別的。有另外一些make只對全小寫的“makefile”文件名敏感,但是基本上來說,大多數的make都持“makefile”和“Makefile”這兩種默認文件名。
當然,你可以使用別的文件名來書寫Makefile,比如:“Make.Linux”,“Make.Solaris”,“Make.AIX”等,如果要指定特定的Makefile,你可以使用make的“-f”和“--file”參數,如:make -f Make.Linux或make --file Make.AIX。
3. 引用別的 Makefile
在Makefile使用include關鍵字可以把別的Makefile包含進來,這很像C語言的 #include,被包含的文件會原模原樣的放在當前文件的包含位置。include的語法是:
include<filename>filename可以是當前操作系統Shell的文件模式(可以保含路徑和通配符)在include前面可以有一些空字符,但是絕不能是[Tab]鍵開始。include和可以用一個或多個空格隔開。舉個例子,你有這樣幾個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.mkmake命令開始時,會把找尋include所指出的其它Makefile,并把其內容安置在當前的位置。就好像C/C++的#include指令一樣。如果文件都沒有指定絕對路徑或是相對路徑的話,make會在當前目錄下首先尋找,如果當前目錄下沒有找到,那么,make還會在下面的幾個目錄下找:
1.如果make執行時,有“-I”或“--include-dir”參數,那么make就會在這個參數所指定的目錄下去尋找。
2.如果目錄/include(一般是:/usr/local/bin或/usr/include)存在的話,make也會去找。
如果有文件沒有找到的話,make會生成一條警告信息,但不會馬上出現致命錯誤。它會繼續載入其它的文件,一旦完成makefile的讀取,make會再重試這些沒有找到,或是不能讀取的文件,如果還是不行,make才會出現一條致命信息。如果你想讓make不理那些無法讀取的文件,而繼續執行,你可以在include前加一個減號“-”。如:
-include
其表示,無論include過程中出現什么錯誤,都不要報錯繼續執行。和其它版本make兼容的相關命令是sinclude,其作用和這一個是一樣的。
4. Makefile 的工作方式
stage1:
stage2:
第一個階段中,如果定義的變量被使用了,那么,make會把其展開在使用的位置。但make并不會完全馬上展開,make使用的是拖延戰術,如果變量出現在依賴關系的規則中,那么僅當這條依賴被決定要使用了,變量才會在其內部展開。
5. Makefile 中的通配符
~
波浪號(“~”)字符在文件名中也有比較特殊的用途。如果是“~/test”,這就表示當前用戶的$HOME目錄下的test目錄。而“~hchen/test”則表示用戶hchen的宿主目錄下的test目錄。(這些都是Unix下的小知識了,make也支持)而在Windows或是MS-DOS下,用戶沒有宿主目錄,那么波浪號所指的目錄則根據環境變量“HOME”而定。
通配符代替了你一系列的文件,如“.c”表示所以后綴為c的文件。一個需要我們注意的是,如果我們的文件名中有通配符,如:“”,那么可以用轉義字符“\”,如“”來表示真實的“”字符,而不是任意長度的字符串。
clean:rm -f *.o上面這個例子我不不多說了,這是操作系統Shell所支持的通配符。這是在命令中的通配符。
print: *.clpr -p $?touch print上面這個例子說明了通配符也可以在我們的規則中,目標print依賴于所有的[.c]文件。其中的“$?”是一個自動化變量,我會在后面給你講述。
objects = *.o上面這個例子,表示了,通符同樣可以用在變量中。并不是說 [.o] 會展開,不!objects的值就是“.o”。Makefile中的變量其實就是C/C++中的宏。如果你要讓通配符在變量中展開,也就是讓objects的值是所有[.o]的文件名的集合,那么,你可以這樣:
objects := $(wildcard *.o)這種用法由關鍵字“wildcard”指出,關于Makefile的關鍵字,我們將在后面討論。
6. 文件搜尋
在一些大的工程中,有大量的源文件,我們通常的做法是把這許多的源文件分類,并存放在不同的目錄中。所以,當make需要去找尋文件的依賴關系時,你可以在文件前加上路徑,但最好的方法是把一個路徑告訴make,讓make在自動去找。
Makefile文件中的特殊變量“VPATH”就是完成這個功能的,如果沒有指明這個變量,make只會在當前的目錄中去找尋依賴文件和目標文件。如果定義了這個變量,那么,make就會在當當前目錄找不到的情況下,到所指定的目錄中去找尋文件了。
VPATH = src:../headers上面的的定義指定兩個目錄,“src”和“../headers”,make會按照這個順序進行搜索。目錄由“冒號”分隔。(當然,當前目錄永遠是最高優先搜索的地方)
另一個設置文件搜索路徑的方法是使用make的“vpath”關鍵字(注意,它是全小寫的),這不是變量,這是一個make的關鍵字,這和上面提到的那個VPATH變量很類似,但是它更為靈活。它可以指定不同的文件在不同的搜索目錄中。這是一個很靈活的功能。它的使用方法有三種:
vapth使用方法中的< pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符,例如,“%.h”表示所有以“.h”結尾的文件。< pattern>指定了要搜索的文件集,而< directories>則指定了的文件集的搜索的目錄。例如:
vpath %.h ../headers該語句表示,要求make在“../headers”目錄下搜索所有以“.h”結尾的文件。(如果某文件在當前目錄沒有找到的話)
我們可以連續地使用vpath語句,以指定不同搜索策略。如果連續的vpath語句中出現了相同的< pattern>,或是被重復了的< pattern>,那么,make會按照vpath語句的先后順序來執行搜索。如:
vpath %.c foovpath % blishvpath %.c bar其表示“.c”結尾的文件,先在“foo”目錄,然后是“blish”,最后是“bar”目錄。
vpath %.c foo:barvpath % blish而上面的語句則表示“.c”結尾的文件,先在“foo”目錄,然后是“bar”目錄,最后才是“blish”目錄。
轉載于:https://my.oschina.net/u/2362565/blog/2122757
總結
以上是生活随笔為你收集整理的Makefile 学习 2 - 基于若干 Blog 的汇总的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker学习专栏
- 下一篇: 朱晔的互联网架构实践心得S1E3:相辅相