Makefile中的 標記和系統萬用字元 的區別

2021-06-25 21:53:17 字數 2128 閱讀 7260



(本文的測試環境是windows7下使用mingw提供的make.exe)

例如,如果你想編譯乙個資料夾下的所有.c檔案,你可能會這樣寫:

1 %.o:%.c

2 gcc -o $@ $<

但是如果整個檔案只有這兩行的話,就會出現這樣的錯誤:

make: *** target not found. stop.
要知道原因,我們先來看看另乙個makefile的執行過程,例如有makefile如下:

1

test1.o:test1.c

23 gcc -o test1.o test1.c45

6test2.o:test2.c

78 gcc -o test2.o test2.c910

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」)的時候才會把他要尋找的目標套用萬用字元%中。

所以萬用字元%的意思是:

而萬用字元*的意思是:

所以雖然連個符號的意思有點沾邊,但是他們的工作方式時完全不一樣。

現在知道了為什麼檔案中只有

1 %.o:%.c

2 gcc -o $@ $<

會找不到目標了吧。因為沒有-f引數時make會自動找到makefile中第乙個目標中沒有萬用字元的目標進行構造,所以就等於找不到目標了。它的意思並不會自動把檔案中所有的檔案都編譯。

所以正確的**應該是:

1 all:$(subst .c,.o,$(wildcard *.c))

23 %.o:%.c

4 gcc -o $@ $<

這才是把目錄下所有檔案都編譯的命令。

下面是幾個特舒符號的意思:

$@:目標的名字

$^:構造所需檔案列表所有所有檔案的名字

$<:構造所需檔案列表的第乙個檔案的名字

$?:構造所需檔案列表中更新過的檔案

例如:

1

test1.o:test1.c

2 gcc -o $@ $<

$@:就是test1.o

$

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

Makefile中的 標記和系統萬用字元 的區別

本文的測試環境是windows7下使用mingw提供的make.exe 例如,如果你想編譯乙個資料夾下的所有.c檔案,你可能會這樣寫 1 o c 2 gcc o 但是如果整個檔案只有這兩行的話,就會出現這樣的錯誤 make target not found.stop.要知道原因,我們先來看看另乙個m...

matplotlib中的顏色和標記

在matplotlib中繪圖標誌有兩種,一種是點標誌 marker 一種是線標誌 linestle 可選的引數如下。linestyle solid line style dashed line style dash dot line style dotted line style linestyle...

makefile中的all和 PHONY的作用

請編寫乙個makefile同時編譯 鏈結下面兩個程式 main1.c include int main void main2.c include int main void 分析 這裡需要生成兩個可執行檔案main1和main2 兩個目標 由於makefile只能有乙個目標,所以可以構造乙個沒有規則...