"ifeq" makefile 中的条件语法
"ifeq" conditional syntax in makefile
由于条件指令ifeq
经常用于比较从变量展开的词,其中通常包含白色-space,我们可能想要并且实际上需要,让 Make 去除任何 leading 或 trailing white-space.
事实上,您可能有相反的观点,即 Make 应该逐字保留 ifeq 条件的所有参数,因为用户可能已经将那些 whitespace 作为 [=193= 的一部分],目的是让那些白人space在评估这个ifeq
指令时发挥决定性因素,作为true或false.
分不清哪一个更正确
其实我并不孤单!
让自己无法决定,哪个是正确的。因此,它可能会或可能不会删除 leading 或 trailing whitespace.
事实上,有时它会仅去除前导白色space.
不令人失望,Make 有时会 仅去除尾随的白色space.
当然,要检查的案例太多了,所以我会"do"只列出其中的几个。
一个生成文件(版本 1)是:
ifeq ( a, a)
all::
echo 'true'
else
all::
echo 'false'
endif
执行,我得到:
$ make -r
echo 'false'
false
一个生成文件(版本 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
条件指令的 真实性 的这种方法肯定会把它变成:
- 不太一致。
- 不易维护。
- 更难调试。
- 容易出错。
- 最后,很多"fun"!
我们同意吗?
你应该阅读 this:
Commas and unmatched parentheses or braces cannot appear in the text of an argument as written; leading spaces cannot appear in the text of the first argument as written. These characters can be put into the argument value by variable substitution. First define variables comma
and space
whose values are isolated comma and space characters, then substitute these variables where such characters are wanted, like this:
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
由于条件指令ifeq
经常用于比较从变量展开的词,其中通常包含白色-space,我们可能想要并且实际上需要,让 Make 去除任何 leading 或 trailing white-space.
事实上,您可能有相反的观点,即 Make 应该逐字保留 ifeq 条件的所有参数,因为用户可能已经将那些 whitespace 作为 [=193= 的一部分],目的是让那些白人space在评估这个ifeq
指令时发挥决定性因素,作为true或false.
分不清哪一个更正确
其实我并不孤单!
让自己无法决定,哪个是正确的。因此,它可能会或可能不会删除 leading 或 trailing whitespace.
事实上,有时它会仅去除前导白色space.
不令人失望,Make 有时会 仅去除尾随的白色space.
当然,要检查的案例太多了,所以我会"do"只列出其中的几个。
一个生成文件(版本 1)是:
ifeq ( a, a)
all::
echo 'true'
else
all::
echo 'false'
endif
执行,我得到:
$ make -r
echo 'false'
false
一个生成文件(版本 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
条件指令的 真实性 的这种方法肯定会把它变成:
- 不太一致。
- 不易维护。
- 更难调试。
- 容易出错。
- 最后,很多"fun"!
我们同意吗?
你应该阅读 this:
Commas and unmatched parentheses or braces cannot appear in the text of an argument as written; leading spaces cannot appear in the text of the first argument as written. These characters can be put into the argument value by variable substitution. First define variables
comma
andspace
whose values are isolated comma and space characters, then substitute these variables where such characters are wanted, like this:
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