Makefile中的%標記和系統通配符*的區別在於,*是應用在系統中的,%是應用在這個Makefile文件中的。
(本文的測試環境是Windows7下使用MinGW提供的make.exe)
例如,如果你想編譯一個文件夾下的所有.c文件,你可能會這樣寫:
1 %.o:%.c 2 gcc -o $@ $<
但是如果整個文件只有這兩行的話,就會出現這樣的錯誤:
Make: *** target not found. stop.
要知道原因,我們先來看看另一個makefile的運行過程,例如有Makefile如下:
1 test1.o:test1.c 2 3 gcc -o test1.o test1.c 4 5 6 test2.o:test2.c 7 8 gcc -o test2.o test2.c 9 10 11 all:test1.o test2.o
如果沒有指定輸出項目的時候Make會自動找到makefile中第一個目標中沒有通配符的目標進行構造,所以步驟是:
- 構造all,發現需要test1.o和test2.o
- 這個時候他就會在Makefile文件中找到目標能匹配test1.o和test2.o的規則。
- 找到test1.o的規則並且知道test1.c存在,運行下面的命令。
- 同步驟三構造出test2.o
- 現在構造all的源文件已經齊全,構建all
其中最重要的是第2步。
Makefile的通配符是在帶着目的(如“尋找test1.o”)的時候才會把他要尋找的目標套用通配符%中。
所以通配符%的意思是:
- 我要找test1.o的構造規則,看看Makefile中那個規則符合。
- 然后找到了%.o:%.c,
- 來套一下來套一下:
- %.o 和我要找的 test1.o 匹配
- 套上了,得到%=test1。
- 所以在后面的%.c就表示test1.c了。
- OK進行構造
而通配符*的意思是:
- 我不知道目標的名字,系統該目錄下中所有后綴為.c的文件都是我要找的。
- 然后遍歷目錄的文件,看是否匹配。找出所有匹配的項目。
所以雖然連個符號的意思有點沾邊,但是他們的工作方式時完全不一樣。
現在知道了為什么文件中只有
1 %.o:%.c 2 gcc -o $@ $<
會找不到目標了吧。因為沒有-f參數時Make會自動找到makefile中第一個目標中沒有通配符的目標進行構造,所以就等於找不到目標了。它的意思並不會自動把文件中所有的文件都編譯。
所以正確的代碼應該是:
1 all:$(subst .c,.o,$(wildcard *.c)) 2 3 %.o:%.c 4 gcc -o $@ $<
這才是把目錄下所有文件都編譯的命令。
下面是幾個特舒符號的意思:
$@:目標的名字
$^:構造所需文件列表所有所有文件的名字
$<:構造所需文件列表的第一個文件的名字
$?:構造所需文件列表中更新過的文件
例如:
1 test1.o:test1.c 2 gcc -o $@ $<
$@:就是test1.o
$<:就是test1.c
1 test1.o:test1.c head.c 2 gcc -o $@ $^
$^:就是test1.c head.c
$(subst 要被替換的字符串,用來替換的字符串,被處理的字符串):
用“用來替換的字符串”替換“被處理的字符串”中的“要被替換的字符串”
所以:
$(subst .c,.o,test1.c test2.c)
就會得到test1.o test2.o
$(wildcard 尋找的文件):
在系統中尋找文件
例如:
$(wildcard *.c)
就等於找到系統中所有后綴為.c的文件,返回成以空格隔開的一整行字符
例如:test1.c test2.c test3.c 這樣
$(basename 文件名):
取得文件的名字(去掉后綴的意思)
例如:
$(basename test1.c)
就會取得test1
轉載本文請保留以下網址:http://www.cnblogs.com/warren-wong/p/3979270.html
如果發現文中有錯誤之處,請務必告訴我,謝謝大家。