ifndef include guard in Gnu Make 嵌套条件中断
ifndef include guard in Gnu Make breaks on nested conditional
我正在尝试在 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 的两个版本中都是一致的。这暗示我,当条件为假时,Make 以不同的方式解析 Makefile,并认为 macro
定义中的 else
属于 ifndef
。其他条件类型的行为完全相同。
如果我删除 inner_macro
的两个定义,问题就会消失。
我阅读了手册页 info make conditional\ syntax
and info make multi-line
(以前的 defining
),但我没有发现任何警告,我仍然认为我没有做错任何事。
- 我的结论正确吗?
- 这是 Make 中的错误,还是我调用了未定义的行为?
- 我应该如何在 Gnu Make 中实现 include guards?
这是一个错误。在 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
我正在尝试在 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 的两个版本中都是一致的。这暗示我,当条件为假时,Make 以不同的方式解析 Makefile,并认为 macro
定义中的 else
属于 ifndef
。其他条件类型的行为完全相同。
如果我删除 inner_macro
的两个定义,问题就会消失。
我阅读了手册页 info make conditional\ syntax
and info make multi-line
(以前的 defining
),但我没有发现任何警告,我仍然认为我没有做错任何事。
- 我的结论正确吗?
- 这是 Make 中的错误,还是我调用了未定义的行为?
- 我应该如何在 Gnu Make 中实现 include guards?
这是一个错误。在 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