如何使用 if/or/and 函数检查变量是否等于两个值之一
在 GNU makefile 中,如果输入变量等于两个值之一,我想将输出变量设置为一个值(假设为“true”),如果不等于则设置为另一个值(“false”)。
感谢这个答案我已经了解了and
和 or
函数,不久之后我找到了 if
函数。这些功能似乎在我的make版本中可用,所以我想使用它们。我想写这样的东西:
TEST_INPUT = `hostname`
TEST_OUTPUT = $(if $(or $(eq $(TEST_INPUT),hal9000),
$(eq $(TEST_INPUT),pipboy)),true,false)
不幸的是我不能,因为我找不到预期的 eq 函数的任何明显形式。我能够使用 filter
函数
TRUE_HOSTS = hal9000 pipboy
TEST_OUTPUT = $(if $(filter $(TEST_INPUT),$(TRUE_HOSTS)),true,false)
或 subst
函数实现我想要的目标:
TEST_OUTPUT = $(if $(and $(subst hal9000,,$(TEST_INPUT)),
$(subst pipboy,,$(TEST_INPUT))),
false,true)
但对我来说,这不是一个美观且可读的代码。是否有更接近第一个示例的解决方案(使用不存在的 eq 函数的解决方案)?也许我根本不明白 if
、and
和 or
函数的用途?
In a GNU makefile, I would like to set an output variable to one value (let's say "true") if an input variable is equal to one of two values and to another value ("false") when it is not.
Thanks to this SO answer I've learned about the and
and the or
functions and soon after that I have found the if
function. These functions seem to be available in my version of make, so I would like to use them. I would like to write something like that:
TEST_INPUT = `hostname`
TEST_OUTPUT = $(if $(or $(eq $(TEST_INPUT),hal9000),
$(eq $(TEST_INPUT),pipboy)),true,false)
Unfortunately I can't, because I couldn't find any obvious form of the expected eq
function. I am able to achieve what I want using the filter
function:
TRUE_HOSTS = hal9000 pipboy
TEST_OUTPUT = $(if $(filter $(TEST_INPUT),$(TRUE_HOSTS)),true,false)
or the subst
function:
TEST_OUTPUT = $(if $(and $(subst hal9000,,$(TEST_INPUT)),
$(subst pipboy,,$(TEST_INPUT))),
false,true)
but for me it isn't a nice looking nor readable code. Are there solutions closer to the first example (the one using not existing eq
function)? Maybe I don't catch the purpose of the if
, and
and or
functions at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
GNUmake 条件的奇怪之处在于 make 中没有布尔类型——一切都是字符串。因此,所有条件都将空字符串视为“false”,并将所有非空字符串(包括
false
和0
等字符串)视为“true”。话虽这么说,缺少
eq
确实是一件小事,但也是一件令人烦恼的事情。一般来说,您可以从filter
或findstring
获得您想要的内容,并且filter
通常允许您搜索整个字符串列表以匹配您的内容第二个例子。如果您确实需要它,您可以定义自己的 eq 函数:
不幸的是您必须将其用作
$(call eq,
...,
...)
The thing that is odd about GNUmake conditionals is that there is no boolean type in make -- everything is a string. So the conditionals all work with the empty string for 'false' and all non-empty strings (including strings like
false
and0
) as being 'true'.That being said, the fact that
eq
is missing is an annoyonace albeit a minor one. Generally you can get what you want fromfilter
orfindstring
, andfilter
often allows you to search a whole list of strings to match as in your second example.If you really need it, you can define your own eq function:
Which you unfortunately have to use as
$(call eq,
...,
...)
克里斯·多德(Chris Dodd)的答案很好,但有一个极端的情况,它提供了错误的结果。如果被比较的两个变量都是空(即 false),那么它将返回 false。改进的版本是:
首先检查两个参数是否非空,如果是,则使用之前的技术来比较它们。否则返回 1,表示这些值相等,因为它们都是空的。
Chris Dodd's answer is good, but there is a corner case for which it provides an incorrect result. If both of the variables being compared are empty (i.e. false) then it will return false. An improved version would be:
This first checks to see either of the arguments are non-empty, and if so uses the previous technique to compare them. Otherwise it returns 1, to indicate that the values are equal as they are both empty.
根据您的上下文,考虑使用 GMSL(GNU Make 标准库),它是 make 包含文件中的函数集合“...提供列表和字符串操作、整数算术、关联数组、堆栈和调试工具。 ”请参阅 http://gmsl.sourceforge.net/
它还有一个“字符串等于”函数 seq作为许多其他有用的操纵器:
此外,使用 $(shell ...) 语法而不是反引号以更好地处理换行符。
Depending on your context, consider using the GMSL (GNU Make Standard Library), which is a collection of functions in a make include file "...that provide list and string manipulation, integer arithmetic, associative arrays, stacks, and debugging facilities." See http://gmsl.sourceforge.net/
It has a "string equal" function, seq, as well as a number of other useful manipulators:
Also, use the $(shell ...) syntax instead of backticks for better handling of newlines.