在GNU makefile中,如果输入变量等于两个值中的一个,我想将输出变量设置为一个值(假设为“true”),如果输入变量不等于另一个值(“false”)
感谢this SO answer我已经了解了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
函数的用途?
答案 0 :(得分:22)
关于GNUmake条件的奇怪之处在于make中没有布尔类型 - 一切都是字符串。所以条件都使用空字符串表示'false',所有非空字符串表示'true'。
话虽如此,eq
遗失的事实是一个令人讨厌的事,尽管是一个小事。通常,您可以从filter
或findstring
获得所需内容,而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 ...)语法而不是反引号来更好地处理换行符。