【问题标题】:make does not rebuild target on header file modificationmake 不会在头文件修改时重建目标
【发布时间】:2014-08-14 13:02:13
【问题描述】:

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

make: `program' is up to date.

我不明白为什么,因为 .h 文件在先决条件行中 以及 .cpp 文件。 有趣的是,如果我对像

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

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

【问题讨论】:

  • 我无法重现您的问题;您提供的示例对我来说很好。因此,您的实际情况必须与此示例在某些实质性方面有所不同。在我们提供帮助之前,您需要让您的示例失败,就像您的实际情况失败一样。
  • 好的,为了简洁起见,我删减了真正的 makefile。事实上,在您发表评论后,我已经尝试过,发现这个简短的示例也适用于我。因此,我寻找与真正的 makefile 的一些实质性差异,我看到的唯一一个是文件实际上包含在子目录中。从这个意义上说,我已经编辑了要更新的问题。

标签: header makefile rule rebuild


【解决方案1】:

您稍后添加到问题中的子目录确实导致了问题。目标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 用户手册有一个部分Catalogue of Implicit Rules。这也说明您可以使用参数--no-builtin-rules 来避免这种隐式行为。如果你使用它,你会看到make 找不到任何规则来制作a/a.ob/b.o

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

【讨论】:

  • 很好的答案。它让我走上了正确的轨道。通过一些工作,我发现要获得所需的行为,我必须将目标名称写为目标文件的“完整路径”(不是 a.o 而是 a/a.o),最重要的是添加到配方 -o a/a.o在目录中构建目标文件。不知道这是否是最优雅的方式,但现在可以正常工作
猜你喜欢
  • 2012-05-25
  • 2017-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多