Linux Makefile通配符问题

Linux Makefile通配符问题,linux,compilation,makefile,gnu,Linux,Compilation,Makefile,Gnu,因此,我在理解%通配符在使用makefile时实际如何工作时遇到了一些问题。我已经看过GNU Maker man中的静态模式规则,但是我仍然很困惑,我觉得我已经看到它们做了一些类似于下面的事情 EXEC = a.out CC = gcc FLAGS = -Wall -c $(EXEC): %.o $(CC) -o $(EXEC) $< %.o: %.c $(CC) $(FLAGS) $< clean: rm -rf *.o 我一直收到一个错误,显示%.o

因此,我在理解%通配符在使用makefile时实际如何工作时遇到了一些问题。我已经看过GNU Maker man中的静态模式规则,但是我仍然很困惑,我觉得我已经看到它们做了一些类似于下面的事情

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

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

clean:
    rm -rf *.o

我一直收到一个错误,显示%.o规则未定义。如果有人能从很多方面解释为什么这是错误的,那么猜测自动变量部分也是错误的,这将是非常感谢的

很久以前我使用makefiles时,它们看起来更像下面这样。对于每个可执行文件,我们明确列出了所需的对象文件

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

很久以前,当我使用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

我不确定你的意图,但我很确定这条规则:

$(EXEC): %.o
    $(CC) -o $(EXEC) $<
注意使用。或者将其限制为EXEC列表a中的可执行文件:

另一方面,如果要使用它能找到的所有源文件来构建此可执行文件,则必须执行以下操作:

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 $^ $<

请注意and的用法,它扩展到先决条件列表,还请注意*.o对您没有多大好处。

我不确定您的意图,但我非常确定这条规则:

$(EXEC): %.o
    $(CC) -o $(EXEC) $<
注意使用。或者将其限制为EXEC列表a中的可执行文件:

另一方面,如果要使用它能找到的所有源文件来构建此可执行文件,则必须执行以下操作:

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 $^ $<

请注意and的用法,它扩展到先决条件列表,还请注意*.o对您没有多大好处。

%匹配目标名称的任何部分-因此它将匹配a.out的任何部分。除非您的源文件被称为类似a.out.c的东西,否则它将完全不匹配。当然,您可能希望尝试使用*.o,但风险自负。另外,$您希望它使用哪些对象文件来构建.out?如果有两个源文件a.c和b.c,它应该同时使用这两个文件,还是只使用a.o?%匹配目标名称的任何部分-因此它将匹配a.out的任何部分。除非您的源文件被称为类似a.out.c的东西,否则它将完全不匹配。当然,您可能希望尝试使用*.o,但风险自负。另外,$您希望它使用哪些对象文件来构建.out?如果有两个源文件,a.c和b.c,它应该同时使用,还是只使用a.o?当我尝试你的第二个示例时,我得到了一个什么都不做的结果。你能告诉我你是如何运行它的吗?@PandaRaid:在你的示例或我的答案中没有全部目标。您的makefile中是否有all目标?您是否通过键入makeall来调用Make?当你说我的第二个例子时,你是指模式规则还是静态模式规则?对不起,模式匹配不是静态的。我想按照模式匹配中10.5.2GNU示例中给出的思路做一些事情。基本上是%.o:%.c但就像你说的,默认情况下它不会使用模式,我希望对目录中的所有c文件都这样做。@PandaRaid:如果你想使用目录中的所有c文件,为什么不使用我的最后一个例子呢?是的,我试过了,它很管用,这更像是一个实验,试图理解如何使用%通配符。我感谢你的帮助!当我尝试你的第二个例子时,我什么都没做。你能告诉我你到底是怎么做到的吗?@PandaRaid:在你的例子或我的答案中,没有一个完全的目标。您的makefile中是否有all目标?您是否通过键入makeall来调用Make?当你说我的第二个例子时,你是指模式规则还是静态模式规则?对不起,模式匹配不是静态的。我想按照模式匹配中10.5.2GNU示例中给出的思路做一些事情。基本上是%.o:%.c但就像你说的,默认情况下它不会使用模式,我希望对目录中的所有c文件都这样做。@PandaRaid:如果你想使用目录中的所有c文件,为什么不使用我的最后一个例子呢?是的,我试过了,它很管用,这更像是一个实验,试图理解如何使用%通配符。我感谢你的帮助!