c++ makefile 未检测到 .h 文件中的更改

c++ makefile not detecting the changes in the .h files

我有一个较长的 make 文件,它编译我的源代码文件的部分在这里

$(MAINFILE):    $(BINDIR) $(OBJDIR) $(SCIPLIBFILE) $(LPILIBFILE) $(NLPILIBFILE) $(MAINOBJFILES)
        $(LINKCXX) $(MAINOBJFILES) $(LINKCXXSCIPALL) $(LDFLAGS)  -I$(GRBPATH)/mac64/include -L$(GRBPATH)/mac64/lib -lgurobi_c++ -lgurobi81 $(LINKCXX_o)$@

$(OBJDIR)/%.o:  $(SRCDIR)/%.cpp  
        $(CXX) $(FLAGS) $(OFLAGS) $(BINOFLAGS) $(CXXFLAGS) -I$(GRBPATH)/mac64/include -c  $< $(CXX_o)$@

仅当我清除所有内容然后从头开始编译时,头文件更改才会生效。我试过这个:

$(MAINFILE):    $(BINDIR) $(OBJDIR) $(SCIPLIBFILE) $(LPILIBFILE)   $(NLPILIBFILE) $(MAINOBJFILES)
            $(LINKCXX) $(MAINOBJFILES) $(LINKCXXSCIPALL) $(LDFLAGS)  -I$(GRBPATH)/mac64/include -L$(GRBPATH)/mac64/lib -lgurobi_c++ -lgurobi81 $(LINKCXX_o)$@

$(OBJDIR)/%.o:  $(SRCDIR)/%.cpp   (SRCDIR)/%.hpp  (SRCDIR)/%.h
        $(CXX) $(FLAGS) $(OFLAGS) $(BINOFLAGS) $(CXXFLAGS) -I$(GRBPATH)/mac64/include -c  $< $(CXX_o)$@ 

但我收到错误消息:

make: *** No rule to make target `obj/static/O.darwin.x86_64.gnu.opt/ColG_main.o

我对 makefile 有点陌生,我想知道我是否可以解决这个问题。

make 只知道您在 makefile 中指定的依赖项。一般来说,这个问题的解决方案是将适当的 header 命名为 object 文件的附加先决条件。这就是这条规则似乎试图做的......

$(OBJDIR)/%.o:  $(SRCDIR)/%.cpp   (SRCDIR)/%.hpp  (SRCDIR)/%.h
        $(CXX) $(FLAGS) $(OFLAGS) $(BINOFLAGS) $(CXXFLAGS) -I$(GRBPATH)/mac64/include -c  $< $(CXX_o)$@

,但它在句法和语义上都有问题。

从句法上讲,您从表达式中省略了两个 $,这些 (SRCDIR) 而不是 $(SRCDIR)

这很容易修复,但它只是主要问题的补充:(更正的)规则仅适用于构建具有相应 .cpp 的 object 文件和对应的.hpp对应的.h存在或可以自己建造。也许您要构建的所有 object 都是这种情况,但根据我的经验,C++ 源文件具有两个对应的 header 是不典型的。除非你有一些其他适用于构建 object 的规则,make 将报告一个错误,例如你观察到的 objects 没有对应的 headers

此外,如果您的任何 object 文件依赖于 header 而非直接对应的文件,则该规则不会捕获这些依赖项。因此,它不会可靠地生成受给定 header 更改影响的所有 object 的重建。

解决方案是为每个目标正确指定所有依赖项。您可能无法通过您的模式规则执行此操作,但您可以提供附加的 prerequisite-only 规则来指定 header 依赖项。您可以手动编写此类规则,但如果您有很多目标,或者如果它们的依赖项列表经常更改,那么编写和维护起来会很痛苦 error-prone。但是,如果您使用的是支持它的工具链,则可以通过多种方式自动生成这些依赖关系规则。有很多在线资源对此进行讨论,例如