【问题标题】:"ifeq" conditional syntax in makefilemakefile 中的“ifeq”条件语法
【发布时间】:2023-03-07 20:29:01
【问题描述】:

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

事实上,您可能有相反的看法,即 Make 应该逐字保留 ifeq 条件的所有参数,因为用户可能已经将这些空格作为“测试”的一部分,目的是让这些空格在评估此 ifeq 指令时,作为 truefalse 发挥决定性作用。

我无法确定,其中哪一个是更多正确的。

事实上,我并不孤单!

让自己无法决定,哪一个是正确的。因此,它可能会或可能不会去除 leadingtrailing 空格。

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

并不令人失望,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 条件指令的真实性 的这种方法肯定会变成:

  • 不太一致。
  • 不易维护。
  • 更难调试。
  • 容易出错。
  • 终于有很多“乐趣”了!

我们同意吗?

【问题讨论】:

    标签: makefile conditional gnu-make


    【解决方案1】:

    你应该阅读this:

    逗号和不匹配的括号或大括号不能出现在所写参数的文本中;前导空格不能出现在第一个参数的文本中。这些字符可以通过变量替换放入参数值中。首先定义变量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不能包含WS。事实上,这些例子证明我们可以。但是,您正确地指出,WS 是由变量扩展产生的(不是按字面输入)always 很重要!谢谢
    • @JiCha 你是对的。该文档没有说明条件指令参数中的空格。我们必须考虑到它们的行为类似于函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    相关资源
    最近更新 更多