我正在尝试在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=1
和make
命令来获取所描述的行为。
当我清除环境并禁用内置规则和变量时,会发生同样的情况: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\ syntax
和info make multi-line
(以前为defining
),但我发现没有任何警告,我仍然认为我没有做错任何事。
答案 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