Make不能在头文件修改时重新生成目标



我有这样一个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.p p和b.h, b.p p。问题是,如果我修改一个.cpp文件,发出make命令会重新构建目标程序但是如果我修改一个。h文件,make不会重建任何东西,只会说

make: `program' is up to date.

我不明白为什么,因为。h文件在先决条件行与.cpp文件一起。有趣的是,如果我在object文件目标上执行make命令,比如

$ make a.o 

,对a/a.h的修改被检测到,目标a/a。O是重建。问题在哪里?

您稍后添加到问题中的子目录确实导致了这个问题。目标program依赖于a/a.ob/b.o,但是没有明确的规则将它们变成.o文件——只有目标a.ob.o存在,但它们不在子目录中。

因此,make将寻找隐式规则来构建a/a.ob/b.o。该规则确实存在,您将在运行make -d时看到它被找到。这个隐式规则只依赖于a/file_a.cpp,而不是a/file_a.h。因此,根据隐式规则,更改a/file_a.cpp将使a/a.o过时,而a/file_a.h不会。

make用户手册中有一节"隐式规则目录"供您参考。这也解释了为什么可以使用参数--no-builtin-rules来避免这种隐式行为。如果你使用它,你会看到make找不到任何规则来创建a/a.ob/b.o

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

相关内容

最新更新