我正在尝试实现include guards在 Gnu Make 中。在此 Makefile 中,第一个包含正常,而第二个则失败并出现错误。
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: *** 缺少分隔符。停止。
,而 Debian Wheezy 下的 Gnu Make 3.81 则显示 Makefile:14: *** 无关的 `endef'。停止。
。在第一次包含时,他们都说:
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 属于 ifndef。其他条件类型的行为完全相同。
如果我删除 inner_macro
的两个定义,问题就会消失。
我阅读了手册页 info make conditional\ syntax
和 info make multi-line
(以前是defining
),但我没有发现任何警告,而且我仍然认为我没有做错任何事。
- 我的结论正确吗?
- 这是 Make 中的错误,还是我调用了未定义的行为?
- 我应该如何在 Gnu Make 中实现包含防护?
最佳答案
这是一个错误。举报 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
关于makefile - ifndef 在 Gnu 中包含防护 在嵌套条件上进行中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31995255/