代码之家  ›  专栏  ›  技术社区  ›  Palec dr. evil

ifndef在Gnu中包含guard在嵌套条件下进行中断

  •  2
  • Palec dr. evil  · 技术社区  · 9 年前

    我正在尝试实施 include guards 在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=1 make 命令以获得所描述的行为。

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

    如果我删除 内部_宏 ,问题消失了。

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

    1. 我的结论正确吗?
    2. 这是Make中的错误,还是我调用了未定义的行为?
    3. 我应该如何在Gnu Make中实现包含守卫?
    1 回复  |  直到 9 年前
        1
  •  2
  •   MadScientist    9 年前

    这是一个bug。报告日期: 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