GNU-make 如何检查列表/数组中是否存在元素

16

我在make文件中定义了一个列表,用户需要设置一个环境变量,我需要在这个列表中查找这个变量。使用gnu make是否有办法实现?我想在任何recipe之外,在make开始构建任何目标之前执行此操作。这是一个QA检查,以确保用户将环境变量设置为范围/列表内的值。

在终端上:

setenv ENV_PARAM x

在Makefile中:

PARAMS := a b c

if ${ENV_PARAM} exists in $(PARAMS)
  true
else
  false
endif

@MadScientist的答案是有效的。有没有一种方法可以使用foreach循环包装if块以测试多个参数?

KEYS    := PARAMS FACTORS
PARAMS  := a b c
FACTORS := x y z

foreach v in ($(KEYS)) {
  ifneq ($(filter $(ENV_$(v)),$(v)),)
    $(info $(ENV_$(v)) exists in $(v))
  else
    $(info $(ENV_$(v)) does not exist in $(v))
  endif
}

你提供的例子不够清晰。在makefile中,有两个不同的地方可以使用这样的测试:你可能想在目标的recipe中进行测试,或者你可能想在任何recipe之外,在make开始构建目标之前进行测试。这两种情况的语法非常不同,因此你需要提供更多关于你要实现的具体内容的信息。 - MadScientist
我刚刚编辑了我的问题。 - Wilderness
1个回答

27
您可以使用 filter 函数来实现此操作:
PARAMS := a b c

ifneq ($(filter $(ENV_PARAM),$(PARAMS)),)
    $(info $(ENV_PARAM) exists in $(PARAMS))
else
    $(info $(ENV_PARAM) does not exist in $(PARAMS))
endif

阅读:“如果在PARAMS中搜索ENV_PARAM值的结果不为空,则运行“true”块,否则运行“false”块”。

更新

根据您提供的信息,我们真正无法完全回答您的第二个问题。为了知道最佳方法,我们需要知道当条件为真和假时,您实际上会在if语句内部执行什么操作。您是否要声明更多变量?创建一些规则?还是其他?有许多方法可以完成您想要的操作,最清晰的方法可能因您要执行的操作而异。

然而,一个通用的解决方案将涉及使用define来创建循环的内容,然后使用foreacheval,类似于这样:

KEYS    := PARAMS FACTORS
PARAMS  := a b c
FACTORS := x y z

define LOOPBODY
  ifneq ($$(filter $$(ENV_$(v)),$(v)),)
    $$(info $$(ENV_$(v)) exists in $(v))
  else
    $$(info $$(ENV_$(v)) does not exist in $(v))
  endif
endef

$(foreach v,$(KEYS),$(eval $(LOOPBODY)))

你可能会对我在 GNU make 中有关元编程的一系列文章感兴趣:http://make.mad-scientist.net/category/metaprogramming/


更进一步,有没有办法将这个ifneq块包装在foreach块内?我想为多个参数进行测试。我做了很多搜索,但找不到任何示例显示类似的用法。我已经更新了我的问题,说明了我想要什么。 - Wilderness
你的意思是测试是否存在多个参数中的任何一个吗?你可以将多个单词作为filter的第一个参数,并且它将返回与其中任何一个匹配的结果:$(filter $(P1) $(P2) $(P3),$(PARAMS)) - MadScientist
我有许多参数,希望使用foreach循环来遍历这个列表,而不是为每个参数编写一个ifneq块。一般来说,我遇到了许多情况,希望在for循环中测试某些条件,但无法找到任何指针。这是make的限制吗? - Wilderness
这对我有用。除了 eval 之外,我尝试了所有方法。不过需要注意的是,信息语句需要两个 '$' 符号。我将仔细阅读您的帖子,以更好地理解 'make'。非常感谢您抽出时间来回答我的问题。 - Wilderness
哎呀,你说得对,我漏掉了几个双美元符号,尽管这些是在这个特定的例子中唯一有区别的。这就是我没有测试就打字的下场! - MadScientist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接