变量赋值后的尾随注释颠覆比较

时间:2012-03-31 07:06:09

标签: comments makefile gnu-make

在GNU make中,附加到变量赋值的尾随注释会阻止后续比较(通过ifeq)正常工作。

这是Makefile ......

  A = a
  B = b ## trailing comment
  C = c

  RESULT :=

ifeq "$(A)" "a"
  RESULT += a
endif

ifeq "$(B)" "b"
  RESULT += b
endif

ifeq "$(C)" "c"
  RESULT += c
endif

rule:
    @echo RESULT=\"$(RESULT)\"
    @echo A=\"$(A)\"
    @echo B=\"$(B)\"
    @echo C=\"$(C)\"

这是输出......

$ make
RESULT=" a c"
A="a"
B="b "
C="c"

正如您从RESULT的显示值中看到的那样,ifeq受到B分配中评论的影响。回应变量B,表明问题不是评论,而是介入空间

显而易见的解决方案是在比较之前明确地strip空格,如此......

ifeq "$(strip $(B))" "b"
  RESULT += b
endif

然而,这似乎容易出错。由于除非/直到使用评论,否则不需要strip操作,您可以省略strip并且所有内容最初都会正常工作 - 因此您很可能不会总是记得添加strip。稍后,如果有人在设置变量时添加注释,则Makefile将不再按预期工作。

注意:正如this question所示,存在一个密切相关的问题,即使没有注释,尾随空格也会破坏字符串比较。

问题:是否有更强的傻瓜式方式来处理此问题?

3 个答案:

答案 0 :(得分:5)

这不是GNU Make特有的;相反,makedefined by POSIX to work this way

  

string1 = [string2]

     

名为 string1 的宏被定义为具有 string2 的值,其中 string2 被定义为所有字符,如果有的话,在<equals-sign>,最多为评论字符(#)或未转义的<newline>。 <{1}}之前或之后的任何<blank>个字符都将被忽略。

这可以解释为一个允许您使用尾随空格清晰创建变量的功能:

<equals-sign>

虽然通常可能会更清楚地重新组织你使用FOO = stuff # this macro has two trailing spaces BAR = something else# and this one has none 的地方,而不是依赖它有模糊的空格。

处理此问题的最佳方法可能就是避免它:有一个约定对变量定义行放置注释(除非偶尔使有意的空白显式)。而不是写这个:

$(FOO)

写下这个:

A = a # list of apples
B = b # list of bananas
C = c # list of carrots

这往往是GNU项目中的风格(例如参见the bottom of this page),但我不记得是否记录在任何地方。

顺便说一句,在检查空格时,您可能希望在# list of apples A = a # list of bananas B = b # list of carrots C = c 命令中引用变量:

echo

rule: @echo 'RESULT="$(RESULT)"' 版本中,echo RESULT=\"$(RESULT)\"未引用shell,因此标签和多个空格被误导性地显示为单个空格。

答案 1 :(得分:0)

以下是我的一些原创想法:

  • 制定政策始终使用strip ifeq
    • 不使用strip将是一个罕见的例外,需要在评论中进行解释。
  • 不要在Makefile中手动设置配置变量
    • 查找或创建其他工具来执行此操作。
    • 也许POSIX shell就足够了(虽然我认为shell变量的细微差别可能比make的差别更小。)
    • 我怀疑GNU build system(Autoconf / Automake /等)解决了这个问题,但我的感觉是,这对于大多数用途来说都是过度的。
  • 使用某种“lint”工具来发现这些问题
    • 我不知道是否存在任何此类工具。
  • 修改GNU make以解决此问题。
    • 最好尽量减少对现有Makefile的影响。
    • 修改make语言,以便默认情况下删除尾随空格
  • 使用更现代的构建工具而不是GNU make

答案 2 :(得分:0)

丑陋,但也许更加万无一失。任何在将来编辑此内容的人都可能至少会注意到你或许会故意让它变得丑陋。

A = $(strip a )##
B = $(strip b )## trailing comment
C = $(strip c )##