使用以下makefile片段:
main: main.o f1.o f2.o
$(CC) $(CFLAGS) -o program main.o f1.o f2.o
main.o: main.cc
$(CC) $(CFLAGS) -c main.cc
f1.o: f1.cc
$(CC) $(CFLAGS) -c f1.cc
f2.o: f2.cc
$(CC) $(CFLAGS) -c f2.cc
如果我只更改了一个文件,那么当我重新运行make时,只会根据需要重新编译该文件。但是,我很难概括这一点,而无需单独列出每个文件。当我尝试类似的东西时:
$(OBJECTS): $(SOURCES)
$(CC) $(CFLAGS) -o $@ -c $(patsubst %.o,%.cc,$@)
它单独构建每个目标文件,但每个目标文件都依赖于我的所有源,因此任何一个文件中的更改都会导致完全重新编译。什么是实现这个目标的好方法?
答案 0 :(得分:1)
基本上,
您必须单独列出每个.o
文件的依赖项。
例如,每个.o
可能依赖于不同的标头集。
拿走f1.o
,您需要以下内容:
f1.o: include/i.h
f1.o: another.h dir/and-another.h
f1.o: f1.cc
$(CC) $(CFLAGS) -c f1.cc
(您可以根据需要为目标设置尽可能多的依赖关系。)
维护该列表是一场噩梦。 破坏的依赖关系列表会使您的 Makefile 比无用更糟糕 - 您也可以使用批处理文件。
一切都不会丢失! 如果你整洁, 你可以得到compiler to do it automatically, 几乎是免费的。 使 Makefile 更整洁。 赢了。
答案 1 :(得分:0)
正如Ismail Badawi评论的那样,pattern rules提供了一个很好的解决方案。它们是制作implicit rule的一种类型。基本上,隐式规则是基于文件扩展名的自动配方。例如,make知道如何隐式地将.c文件转换为.o文件。默认情况下,make将为.c文件运行以下配方(请参阅rule catalogue):
$(CC) $(CPPFLAGS) $(CFLAGS) -c
您可以通过设置变量CC,CPPFLAGS和CFLAGS或通过定义模式规则来修改过程:
%.o: %.c
$(CC) $(CFLAGS) -c $<
“$&lt;”以上匹配第一个先决条件的名称,在此示例中将是.c文件。请参阅Beta的评论和automatic variables。