make不会在头文件修改时重建目标

时间:2014-08-13 21:51:53

标签: header makefile rule rebuild

我有一个这样的makefile:

program: \
    a/a.o \
    b/b.o 
    $(CXX) $(CXXFLAGS) -o program \
        a/a.o \
        b/b.o

a.o: \
    a/a.cpp \
    a/a.h
    $(CXX) $(CXXFLAGS) -c a/a.cpp

b.o: \
    b/b.cpp \
    b/b.h
    $(CXX) $(CXXFLAGS) -c b/b.cpp

所以在makefile的目录中我有两个子目录a和b 它们分别包含a.h,a.cp​​p和b.h,b.cpp。 问题是如果我修改.cpp文件,发出make重建目标程序 但如果我修改.h文件,请不要重建除了

之外的任何内容
make: `program' is up to date.

我无法理解为什么,因为.h文件位于先决条件行中 以及.cpp文件。 有趣的是,如果我在像

这样的目标文件目标上发出一个make
$ make a.o 

相反,对a / a.h的修改 检测到目标a / a.o重建。 问题在哪里?

1 个答案:

答案 0 :(得分:1)

您之后添加到问题中的子目录确实会导致问题。目标program取决于a/a.ob/b.o,但没有明确的规则来制作.o个文件 - 只有目标a.o和{{ 1}}存在,但那些不在子目录中。

因此,b.o会查找构建makea/a.o的隐式规则。该规则确实存在,您将在运行b/b.o时看到它被找到。该隐式规则仅取决于make -d,而不取决于a/file_a.cpp。因此,根据该隐式规则更改a/file_a.h会使a/file_a.cpp过期,而a/a.o则不会。{/ p>

作为参考,make用户手册有一个Catalogue of Implicit Rules部分。这也解释了您可以使用参数a/file_a.h来避免这种隐式行为。如果您使用该标准,则会看到--no-builtin-rules找不到要制作makea/a.o的任何规则。

最后,运行b/b.o 运行makefile中定义的目标make a.o的配方。该目标确实以a.o为先决条件,因此对该文件的任何更改都将导致重新编译。但实质上,这与目标a/a.h无关,目标program具有不同的先决条件。