在Gnu中,ifndef include guard在嵌套条件上进行中断



我正试图在Gnu Make中实现包含守卫。在这个Makefile中,第一个包含是OK的,而第二个包含失败并报错。

ifndef INCLUDED
INCLUDED = 1
$(info Including)
define macro
ifneq ($(1),)
define inner_macro
macro content...
endef
else
define inner_macro
endef
endif
endef
endif

同样的效果可以通过在包含前显式地给出INCLUDED = 1来模拟,例如在命令行中。

Gentoo下的Gnu Make 4.1显示Makefile:14: *** missing separator. Stop.,而Debian Wheezy下的Gnu Make 3.81显示Makefile:14: *** extraneous `endef'. Stop.。在第一个包含中,它们都说:

Including
make: *** No targets.  Stop.

如果我在第一次包含之后尝试$(eval $(call macro,whatever)),它将按预期定义inner_macro

我分别使用make INCLUDED=1make命令得到所描述的行为。

当我清除环境并禁用内置规则和变量:env -i make -rR INCLUDE=1时,也会发生同样的情况。当我使用-p来转储数据库时,没有INCLUDED=1, macro被定义为应该的样子,但是使用INCLUDED=1,空的inner_macro被定义。这在Make的两个版本中是一致的。这提示我,当条件为假时,Make以不同的方式解析Makefile,并认为macro定义中的else属于ifndef。其他条件类型的行为完全相同。

如果我删除inner_macro的两个定义,问题就解决了。

我阅读了info make conditional syntaxinfo make multi-line(以前的defining)的手册页,但我没有发现任何警告,我仍然认为我没有做错什么。

  1. 我的结论正确吗?
  2. 这是一个bug在Make,还是我调用未定义的行为?
  3. 我应该如何在Gnu Make中实现包括守卫?

这是一个bug。到萨凡纳去报告。

在未接受的ifdef/ifndef条件中跟踪嵌套的define/endf有问题。如果你不使用嵌套的define/endf,那么它可以工作;例如(显然您可能无法在您的环境中这样做):

ifndef INCLUDED
INCLUDED = 1
$(info Including)
define macro
ifneq ($(1),)
inner_macro = macro content...
else
inner_macro =
endif
endef
endif

相关内容

  • 没有找到相关文章

最新更新