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

Dar*_*zak 16 gnu-make

在GNU makefile中,如果输入变量等于两个值中的一个,我想将输出变量设置为一个值(假设为"true"),如果输入变量不等于另一个值("false").

感谢这个SO答案,我已经了解了这些andor功能,不久之后我就找到了这个if功能.这些函数似乎在我的make版本中可用,所以我想使用它们.我想写这样的东西:

TEST_INPUT = `hostname`
TEST_OUTPUT = $(if $(or $(eq $(TEST_INPUT),hal9000),
                        $(eq $(TEST_INPUT),pipboy)),true,false)
Run Code Online (Sandbox Code Playgroud)

不幸的是我不能,因为我找不到任何明显形式的预期eq功能.我能够使用该filter功能实现我想要的:

TRUE_HOSTS = hal9000 pipboy
TEST_OUTPUT = $(if $(filter $(TEST_INPUT),$(TRUE_HOSTS)),true,false)
Run Code Online (Sandbox Code Playgroud)

subst功能:

TEST_OUTPUT = $(if $(and $(subst hal9000,,$(TEST_INPUT)),
                         $(subst pipboy,,$(TEST_INPUT))),
                   false,true)
Run Code Online (Sandbox Code Playgroud)

但对我来说,它不是一个漂亮的外观也不是可读的代码.是否有更接近第一个示例的解决方案(使用不存在eq函数的解决方案)?也许我没有达到目的if,and而且or功能完全没有?

Chr*_*odd 22

关于GNUmake条件的奇怪之处在于make中没有布尔类型 - 一切都是字符串.所以条件都使用空字符串表示'false',所有非空字符串表示'true'.

话虽这么说,但eq缺少的事实是一个令人讨厌的事,尽管是一个小事.一般来说,你可以让你从想要的东西filterfindstringfilter经常允许你搜索字符串的整个列表,以符合在你的第二个例子.

如果你真的需要它,你可以定义自己的eq函数:

eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1)))
Run Code Online (Sandbox Code Playgroud)

你不幸不得不为使用$(call eq,... ,...)


N. *_*avy 7

克里斯·多德的答案很好,但是有一个角落的情况,它提供的结果不正确.如果要比较的两个变量都是空的(即假),那么它将返回false.改进版将是:

eq = $(if $(or $(1),$(2)),$(and $(findstring $(1),$(2)),\
                                $(findstring $(2),$(1))),1)
Run Code Online (Sandbox Code Playgroud)

首先检查是否有任何参数非空,如果是,则使用先前的技术来比较它们.否则返回1,表示值相等,因为它们都是空的.

  • 或者你可以避免这种情况`eq = $(和$(findstring x $(1),x $(2)),$(findstring x $(2),x $(1)))`. (4认同)

sim*_*ser 6

根据您的上下文,考虑使用 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)
Run Code Online (Sandbox Code Playgroud)

此外,使用 $(shell ...) 语法而不是反引号以更好地处理换行符。