Makefile中的"ifeq"条件语法

18

由于条件指令ifeq经常用于比较从变量扩展的单词,这些单词通常包含空格,因此我们可能希望并且事实上需要让Make去除任何前导尾随空格。

事实上,您可能持有相反的观点,即Make应保留ifeq条件中的所有参数,因为用户可能将这些空格作为"测试"的一部分,并打算让这些空格在评估此ifeq指令时扮演决定性因素,是true还是false

我无法决定哪个观点更正确。

事实上,我不是唯一一个这样想的人!

Make本身也无法决定哪个观点是正确的。因此,它可能会或可能不会删除前导尾随空格。

事实上,有时它只会删除前导空格

令人欣慰的是,Make有时会仅删除尾随空格

当然,要检查的情况太多了,因此我只会“做”其中的一些。



一个Makefile(版本1)如下:

ifeq ( a, a)
all::
    echo 'true'
else
all::
    echo 'false'
endif



执行时,我得到:

$ make -r
echo 'false'
false



一个 Makefile(版本 2)是:

ifeq (a ,a )
all::
    echo 'true'
else
all::
    echo 'false'
endif



执行时,我得到:

$ make -r
echo 'false'
false



一个makefile(版本3)是:

ifeq ( a , a )
all::
    echo 'true'
else
all::
    echo 'false'
endif



执行后,我得到:

$ make -r
echo 'false'
false



一个 makefile(版本 4)是:

ifeq (a , a)
all::
    echo 'true'
else
all::
    echo 'false'
endif



执行时,我得到:

$ make -r
echo 'true'
true



一个Makefile(版本5),是:

ifeq (a, a)
all::
    echo 'true'
else
all::
    echo 'false'
endif



执行时我得到:

$ make -r
echo 'true'
true



综上所述,仅仅列举了一些案例:

# Both, have only leading whitespace.
ifeq( a, a)    as: false.

# Both, have only trailing whitespace.
ifeq(a ,a )    as: false.

# Both, have trailing AND trailing whitespace.
ifeq( a , a )  as: false.

# Left-hand-size has only trailing, and right-hand-size has only leading whitepsace.
ifeq(a , a)    as: true.

# Left-hand-size has NO whitespace at-all, and right-hand-size has only leading whitepsace.
ifeq(a, a)     as: true.

所以,Make使用这种方法来评估ifeq条件指令的真实性,这绝对会使它变得:

  • 不那么一致。
  • 不易于维护。
  • 更难调试。
  • 容易出错。
  • 最后,非常“有趣”!

我们同意吗?

1个回答

12

请阅读此文档

逗号和未匹配的括号或大括号不能直接出现在参数文本中;作为写入的第一个参数的文本中,前导空格也是不允许的。这些字符可以通过变量替换放入参数值中。首先定义变量commaspace,它们的值是隔离的逗号和空格字符,然后在需要这些字符的位置处用这些变量进行替换,像这样:

comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
# bar is now ‘a,b,c’.
你有疑问时,也应当使用strip函数。
以下是一个Makefile的示例:
empty:=
space:= $(empty) $(empty)

x := $(space)a$(space)
y := $(space)a$(space)

ifeq ($(x),$(y))
all::
        @echo 'regular: true'
else
all::
        @echo 'regular: false'
endif

ifeq ($(strip $(x)),$(strip $(y)))
all::
        @echo 'strip:   true'
else
all::
        @echo 'strip:   false'
endif

结果如下:

1:

x = $(space)a
y = $(space)a
regular: true
strip:   true

2:

x = a$(space)
y = a$(space)
regular: true
strip:   true

3:

x = $(space)a$(space)
y = $(space)a$(space)
regular: true
strip:   true

4:

x = a$(space)
y = $(space)a
regular: false
strip:   true

4:

x = a
y = $(space)a
regular: false
strip:   true

在函数$(func arg)的第一个arg中,您不能输入空格(WS),但没有任何规定ifeq (arg arg)中的arg不能包含空格。实际上,示例表明我们可以这样做。但是,您指出的是对的,变量扩展产生的空格(不是字面输入的)总是重要的!谢谢 - Ji Cha
@JiCha 你说得对。文档中没有提到条件指令参数中的空格问题。我们必须考虑它们的行为类似于函数。 - jmlemetayer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接