Makefile解耦依赖项

时间:2016-02-17 21:23:18

标签: makefile gnu-make

使用以下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,$@)

它单独构建每个目标文件,但每个目标文件都依赖于我的所有源,因此任何一个文件中的更改都会导致完全重新编译。什么是实现这个目标的好方法?

2 个答案:

答案 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