使模式自动生成依赖项

时间:2018-06-12 15:48:12

标签: makefile gnu-make

我想允许模式规则为我生成正确的标头依赖项。我试过这样做,但它失败了

例如,如果我有文件foo.cppfoo.hbar.cppbar.hfoo.h包含bar.h。使用Makefile:

foo_H=foo.h $(bar_H)
bar_H=bar.h

%.o: %.cpp $(%_H)
    $(CPP) $(CPPFLAGS) $< -o $@

但在foo.hbar.h更改时,make不会更新。

为什么会失败以及如何解决?

3 个答案:

答案 0 :(得分:1)

这不是gnu的工作方式。

  1. 在分配bar_H时,变量foo_H未定义。因此foo_H只有foo.h
  2. 模式扩展在$(...)内无效。它只会查找不存在的变量%_H,即为空。
  3. %<%@错了。您可能打算撰写$<$@
  4. makefile需要至少一个非目标。图案规则是不够的。
  5. 除非存在所有依赖项,否则不会使用带图案的规则。这可能不是这里的。
  6. 您的图案规则不适用,因为它会搜索foo.c而不是foo.cpp
  7. 预期的行为是通过

    实现的
    foo.o : foo.h bar.h
    bar.o : bar.h
    
    %.o: %.cpp
        $(CPP) $(CPPFLAGS) $< -o $@
    

    请注意,依赖项是与可执行命令分开指定的。

    另一个注意事项:如果你想摆脱包含依赖性地狱,你可能想看看 cmake

答案 1 :(得分:1)

如果您真的想这样做,可以使用secondary expansion

foo_H = foo.h $(bar_H)
bar_H = bar.h

.SECONDEXPANSION:
%.o: %.cpp $$($$*_H)
        $(CPP) $(CPPFLAGS) $< -o $@

答案 2 :(得分:0)

$(%_H)无法扩展,因为正如

中所述

https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html

Note that expansion using ‘%’ in pattern rules occurs after any variable or function expansions, which take place when the makefile is read

所以似乎使用模式来实现这种逻辑是一个死胡同

作为替代方案,我使用了foreachinclude,如下所示:

makedep.mk

$(CUR_OBJ): $(CUR_OBJ:.o=.cpp) $($(CUR_OBJ:.o=_H))
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) $< -o $@

生成文件

foo_H=foo.h $(bar_H)
bar_H=bar.h

SRCS=foo.cpp bar.cpp
OBJS=$(SRCS:.cpp=.o)


$(foreach obj,$(OBJS),$(eval CUR_OBJ:=$(obj)) $(eval include makedep.mk))

因为只有make变量而没有模式匹配%所有内容都可以正常扩展