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。但是,如果您使用的是支持它的工具链,则可以通过多种方式自动生成这些依赖关系规则。有很多在线资源对此进行讨论,例如
- SO 的其他地方:Makefile (Auto-Dependency Generation)
- 在 GNU
make
手册中:Generating Prerequisites Automatically
- 在疯狂科学家的网站上:Auto-Dependency Generation
我有一个较长的 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。但是,如果您使用的是支持它的工具链,则可以通过多种方式自动生成这些依赖关系规则。有很多在线资源对此进行讨论,例如
- SO 的其他地方:Makefile (Auto-Dependency Generation)
- 在 GNU
make
手册中:Generating Prerequisites Automatically - 在疯狂科学家的网站上:Auto-Dependency Generation