nob*_*bar 0 comments makefile gnu-make
在GNU make中,附加到变量赋值的尾随注释会阻止后续比较(via 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)\"
Run Code Online (Sandbox Code Playgroud)
这是输出......
$ make
RESULT=" a c"
A="a"
B="b "
C="c"
Run Code Online (Sandbox Code Playgroud)
正如您从显示的值中看到的那样RESULT,ifeq受到分配中存在的注释的影响B.回应变量B,表明问题不是评论,而是介入空间.
显而易见的解决方案是在比较之前明确剥离空白,如此...
ifeq "$(strip $(B))" "b"
RESULT += b
endif
Run Code Online (Sandbox Code Playgroud)
然而,这似乎容易出错.由于strip除非/直到使用评论,否则不需要操作,你可以省略strip并且所有内容最初都能正常工作 - 所以你很可能不会总是记得添加strip.稍后,如果有人在设置变量时添加注释,则Makefile将不再按预期工作.
注意:如本问题所示,存在一个密切相关的问题,即使没有注释,尾随空格也会破坏字符串比较.
问题:有没有更简单的方法来处理这个问题?
这不是GNU Make特有的; 更确切地说,make是由POSIX定义这样的工作方式:
string1 = [string2]名为string1的宏被定义为具有string2的值,其中string2被定义为所有字符(如果有)
<equals-sign>,直到注释字符(#)或未转义<newline>.<blank>紧接在之前或之后的任何字符<equals-sign>都应被忽略.
这可以解释为允许您使用尾随空格清楚地创建变量的功能:
FOO = stuff # this macro has two trailing spaces
BAR = something else# and this one has none
Run Code Online (Sandbox Code Playgroud)
虽然通常可能会更清楚地重新组织你使用的地方,$(FOO)而不是依赖它有模糊的空白.
处理这个问题的最好方法可能就是避免它:有一个约定,你不要对变量定义行放置注释(除非偶尔使有意的空白显式).而不是写这个:
A = a # list of apples
B = b # list of bananas
C = c # list of carrots
Run Code Online (Sandbox Code Playgroud)
写这个:
# list of apples
A = a
# list of bananas
B = b
# list of carrots
C = c
Run Code Online (Sandbox Code Playgroud)
这往往是GNU项目中的风格(例如参见本页底部),但我不记得是否在任何地方记录了这一点.
顺便说一句,在检查空格时,您可能希望echo更多地在命令中引用变量:
rule:
@echo 'RESULT="$(RESULT)"'
Run Code Online (Sandbox Code Playgroud)
在您的echo RESULT=\"$(RESULT)\"版本中,$(RESULT)未引用shell,因此标签和多个空格被误导地显示为单个空格.