如何使用 if/or/and 函数检查变量是否等于两个值之一

发布于 2024-12-03 00:14:53 字数 1025 浏览 2 评论 0原文

在 GNU makefile 中,如果输入变量等于两个值之一,我想将输出变量设置为一个值(假设为“true”),如果不等于则设置为另一个值(“false”)。

感谢这个答案我已经了解了andor 函数,不久之后我找到了 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 函数的解决方案)?也许我根本不明白 ifandor 函数的用途?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傾旎 2024-12-10 00:14:53

GNUmake 条件的奇怪之处在于 make 中没有布尔类型——一切都是字符串。因此,所有条件都将空字符串视为“false”,并将所有非空字符串(包括 false0 等字符串)视为“true”。

话虽这么说,缺少 eq 确实是一件小事,但也是一件令人烦恼的事情。一般来说,您可以从 filterfindstring 获得您想要的内容,并且 filter 通常允许您搜索整个字符串列表以匹配您的内容第二个例子。

如果您确实需要它,您可以定义自己的 eq 函数:

eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))

不幸的是您必须将其用作 $(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 and 0) 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 from filter or findstring, and filter 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:

eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))

Which you unfortunately have to use as $(call eq,...,...)

萌梦深 2024-12-10 00:14:53

克里斯·多德(Chris Dodd)的答案很好,但有一个极端的情况,它提供了错误的结果。如果被比较的两个变量都是空(即 false),那么它将返回 false。改进的版本是:

eq = $(if $(or $(1),$(2)),$(and $(findstring $(1),$(2)),\
                                $(findstring $(2),$(1))),1)

首先检查两个参数是否非空,如果是,则使用之前的技术来比较它们。否则返回 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:

eq = $(if $(or $(1),$(2)),$(and $(findstring $(1),$(2)),\
                                $(findstring $(2),$(1))),1)

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.

把人绕傻吧 2024-12-10 00:14:53

根据您的上下文,考虑使用 GMSL(GNU Make 标准库),它是 make 包含文件中的函数集合“...提供列表和字符串操作、整数算术、关联数组、堆栈和调试工具。 ”请参阅 http://gmsl.sourceforge.net/

它还有一个“字符串等于”函数 seq作为许多其他有用的操纵器:

    TEST_INPUT = $(shell hostname -s)
    TEST_OUTPUT = $(if $(or $(call seq,$(TEST_INPUT),hal9000),
                            $(call seq,$(TEST_INPUT),pipboy)),true,false)

此外,使用 $(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:

    TEST_INPUT = $(shell hostname -s)
    TEST_OUTPUT = $(if $(or $(call seq,$(TEST_INPUT),hal9000),
                            $(call seq,$(TEST_INPUT),pipboy)),true,false)

Also, use the $(shell ...) syntax instead of backticks for better handling of newlines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文