如何在Makefile中将变量列表用作目标?

38

假设我正在处理一个Makefile,并且在顶部有以下变量声明:

FILES = file1.cpp file2.cpp file3.cpp

现在假设我想使用特殊命令编译它们,而不需要像这样指定每个目标:

file1.o : file1.cpp
    custom_command file1.cpp
file2.o : file2.cpp
    custom_command file2.cpp
file3.o : file3.cpp
    custom_command file3.cpp

使用我上面声明的$(FILES)变量有更好的方法吗?

比如:

$(FILES:.cpp=.o) : $(FILES)
    custom_command $(FILES)

...只需要对$(FILES)变量中的每个文件执行此操作。

3个回答

63

是的,有所谓的模式规则。最简单易懂的例子如下:

%.o: %.cpp
       $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

(请记住,Makefile 需要 使用制表符)。这个规则描述了如何从cpp文件生成对象文件。

如果您不想使用这样宽泛的规则,可以使用所谓的静态模式。

objects = file1.o file2.o file3.o

all: $(objects)

$(objects): %.o: %.cpp
        $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

这里是GNU Make手册中关于静态模式规则模式规则的章节。


12

根据以下方法,您可以这样做:

SRCS=a.c b.c
OBJS=$(SRCS:.c=.o)

$(OBJS): $(SRCS)
        cc -c -o a.o a.c
        cc -c -o b.o b.c

但是你必须记住,依赖关系是完整的 - 它假设 a.o 也依赖于 b.c,而这可能并不是实际情况。

你可能想要的是一个单一的规则来将一种文件类型转换为另一种:

SRCS=a.c b.c
OBJS=$(SRCS:.c=.o)

all: $(OBJS)

.c.o:
        gcc -c -o $@ $<

.c.o是一个规则,它规定了将.c文件转换为.o文件所需运行的命令。在实际命令中,$@会被替换为具体的目标文件名,$<会被替换为第一个先决条件的名称。

还有许多其他的自动变量,你可以使用info make来查找它们,或者如果没有info的话,可以寻找一本关于make的好书。


是的,那基本上就是我想做的。 - Nathan Osman
另一种精确指定依赖关系的方法是使用先决条件的二次扩展(GNU Make 特有功能)。 - ruvim
供大家参考- 如果有人在寻找文档,.c.o规则在GNU-make中被称为后缀规则。GNU-make建议使用模式规则而不是后缀规则。 - user650654

1
SRCS = a.c b.c
OBJS = $(SRCS:.c=.o)

.c.o:
        ${CC} ${CFLAGS} -c -o $@ $<

虽然 $< 不太可移植(如果我没记错,bsdmake 的 $^$< 的含义与 gmake 使用的完全相反),但这是在任何实现中都会生效的 .c.o 的默认配方。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接