2014-08-30 111 views
0

所以我有一些問題了解%通配符實際如何使用makefile工作。我已經看過GNU make man中的靜態模式規則,但我仍然很困惑,我覺得我已經看到他們做了類似於我下面的東西。Makefile通配符問題

EXEC = a.out 
CC = gcc 
FLAGS = -Wall -c 

$(EXEC): %.o 
    $(CC) -o $(EXEC) $< 
%.o: %.c 
    $(CC) $(FLAGS) $< 

clean: 
    rm -rf *.o 

我不斷收到一個錯誤,指出%.o規則未定義。如果有人可以解釋爲什麼這是錯誤的(可能在很多方面,猜測自動變量部分也是不正確的),這將不勝感激!

+0

'%'匹配*目標*名稱的任何部分 - 因此它將匹配'a.out'的任何部分。除非你的源文件被稱爲'a.out.c',否則它不會匹配任何東西。您可能想嘗試使用'* .o'(當然,風險自負)。 – isedev 2014-08-30 21:08:14

+0

'$ <'僅對應於第一個依賴項。因此,如果您有多個源文件(並因此有多個目標文件),則只有第一個將被編譯並鏈接到可執行文件中。如果使用GNU make,則可以使用'$ *'代替。 – isedev 2014-08-30 21:13:09

+0

你想讓它用來構建'a.out'的對象文件是什麼?如果有兩個源文件,'a.c'和'b.c',它們應該同時使用,還是隻使用'a.o'? – Beta 2014-08-30 23:09:44

回答

2

我不知道你想什麼,但我敢肯定,這條規則:

$(EXEC): %.o 
    $(CC) -o $(EXEC) $< 

沒有做到這一點。在這條規則中,'%'不是任何一種通配符,它​​只是一個字符。所以當Make嘗試構建a.out時,它會尋找一個名爲%.o的文件,找不到它,沒有建立它的規則(因爲沒有%.c而且沒有辦法構建),並放棄。

你的意圖不清楚。如果您希望規則能夠建立從a.oa.out(從foo.o同樣foo.out,並從bar.obar.out,等等),寫一個pattern rule

%.out: %.o 
    $(CC) -o [email protected] $< 

$(EXEC): # Make will not use a pattern rule as the default, so we need this 

(注意用[email protected]。)或(將其限制到可執行文件中EXEC列表)一個static pattern rule

$(EXEC): %.out : %.o 
    $(CC) -o [email protected] $< 

如果,另一方面,你要請使用所有的源文件它可以找到建立這個可執行文件,你必須做這樣的事情:

SOURCES = $(wildcard *.c) # make a list a.c foo.c bar.c 
OBJECTS = $(patsubst %.c, %.o, $(SOURCES)) # translate it into a.o foo.o bar.o 
$(EXEC): $(OBJECTS) 
    $(CC) -o $^ $< 

注意使用the wildcard function$^其擴展爲先決條件的列表,同時還指出,「*的.o」不會你有多好。

+0

當我嘗試你的第二個例子時,我得到了「沒有任何事情可以爲所有人完成」,你能告訴我你到底是如何運行的嗎? – PandaRaid 2014-08-31 01:56:40

+0

@PandaRaid:在你的例子或我的答案中沒有「全部」目標。你的makefile中有「全部」目標嗎?你是否通過輸入「make all」來調用Make?當你說我的「第二個例子」時,你的意思是模式規則還是靜態模式規則? – Beta 2014-08-31 02:14:51

+0

對不起,模式匹配不是靜態的。我想按照10.5.2 GNU模式匹配示例中的內容進行操作。基本上%.o:%.c但是就像你說的那樣默認情況下不會使用模式,我希望它可以在dir中的所有c文件中完成。 – PandaRaid 2014-08-31 03:30:11

0

當我很久以前使用makefile時,他們看起來更像下面。對於每個可執行文件,我們明確列出了所需的目標文件

CC = gcc 
FLAGS = -Wall -c 

prog1: mod1.o mod2.o 
    $(CC) mod1.o mod2.o -o prog1 

prog2: mod1.o mod3.o 
    $(CC) mod1.o mod3.o -o prog2 

%.o: %.c 
    $(CC) $(FLAGS) $< 

clean: 
    rm -rf *.o