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

时间:2011-09-06 18:06:51

标签: gnu-make

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

感谢this SO answer我已经了解了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函数的用途?

3 个答案:

答案 0 :(得分:22)

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

话虽如此,eq遗失的事实是一个令人讨厌的事,尽管是一个小事。通常,您可以从filterfindstring获得所需内容,而filter通常允许您搜索整个字符串列表,以便在第二个示例中进行匹配。

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

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

您遗憾地将其用作$(call eq, ... , ... )

答案 1 :(得分:7)

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

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

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

答案 2 :(得分:4)

根据您的上下文,考虑使用GMSL(GNU Make Standard Library),它是make include文件中的函数集合“......提供列表和字符串操作,整数算术,关联数组,堆栈和调试设施。“见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 ...)语法而不是反引号来更好地处理换行符。