2014-08-30 113 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