ifndef在Gnu中包含guard在嵌套条件

时间:2015-08-13 17:54:58

标签: makefile gnu-make include-guards

我正在尝试在Gnu Make中实现include guards。在这个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都是一致的。这告诉我,当条件为false时,Make以不同方式解析Makefile并认为else内的macro定义属于ifndef。其他条件类型表现完全相同。

如果删除inner_macro的两个定义,则问题就会消失。

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

  1. 我的结论是否正确?
  2. 这是Make中的错误,还是我调用未定义的行为?
  3. 我应该如何在Gnu Make中实施包含警卫?

1 个答案:

答案 0 :(得分:1)

这是一个错误。在Savannah上报告。

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

ifndef INCLUDED
INCLUDED = 1
$(info Including)

define macro
ifneq ($(1),)
inner_macro = macro content...
else
inner_macro =
endif
endef

endif