从Makefile变量中删除项目?

99

我有一个Makefile,其中包含几个其他Makefile,这些Makefile又都向一个变量添加,如下所示:

VAR := Something SomethingElse
VAR += SomeOtherThing

(...)
现在我希望从变量VAR中删除SomethingElse。我应该用什么替换(...)来实现这个目标?
我正在使用GNU Make,GNU Make特定的解决方案也可以。
3个回答

135

如果你正在使用GNU Make,你可以使用filter-out文本函数.

OTHERVAR := $(filter-out SomethingElse,$(VAR))

你确定我必须使用=而不是:=吗? - Bjarke Freund-Hansen
1
在我举例的情况下,两者都正确吗?如果我使用 = ,我会收到一个 makefile 错误,指出 VAR 最终引用自身而导致无限递归。(VAR = $(filter-out SomethingElse,$(VAR))) - Bjarke Freund-Hansen
这就是为什么我在我的示例中没有放置 VAR =。如果您需要重置 VAR,您可能需要简单扩展。 - Mat
4
总的来说,这取决于用途。但在我的例子中,正确的答案应该是:VAR := $(filter-out SomethingElse,$(VAR))(使用 := 而不是 =)。谢谢。 :) - Bjarke Freund-Hansen
16
注意:此语法也可用于多个项目。例如:VAR := $(filter-out A B C,$(VAR)) - checksum
3
对于其他人的注意事项。filter-out仅适用于以空格分隔的单词。如果您需要从未分隔的字符串中删除某些内容,则可以使用subst代替filter-out。例如:$(subst -world,,hello-world)将给出结果hello - Jacob

10

除了上面的正确答案:

VAR = bla1 bla2 bla3 bla4 bla5

TMPVAR := $(VAR)
VAR = $(filter-out bla3, $(TMPVAR))

all:
    @echo "VAR is: $(VAR)"

输出:
VAR 为:bla1 bla2 bla4 bla5

请注意,当执行 filter-out 命令时,这将打破所有“递归”,但在您的情况下可能并不重要。


这不是预期行为吗?首先您正常定义VAR,然后立即设置TMPVAR以在此时扩展VAR。然后您正常重置VAR以引用TMPVAR的过滤版本。在所有目标中使用VAR并因此扩展它。我不明白这如何破坏递归或以任何方式成为问题行为? - Bjarke Freund-Hansen
1
我可能表达不够清晰。想象一下有 BLA1 = bla1,然后是 VAR = $(BLA1) bla2 bla3 bla4 bla5 而不是上面的 VAR 定义。在 filter-out 之后执行 BLA1 += bla1111 将不会对 VAR 的值产生影响,因为它已经失去了对 $(BLA1) 值的引用。 - Andreas Mikael Bank

0

由于我也遇到了类似的情况,我想要添加一个新的答案。在我的情况下,变量字符串中也有逗号,并且我想要删除逗号和最后一个单词:

VAR = "bla1, bla2"

在这种情况下,过滤器不起作用(即使在之前的答案中没有引号时也是如此)。
我的解决方案是使用subst
VAR = "bla1, bla2"

TTT = , bla2
TMPVAR := $(VAR)
SUBST = $(subst $(TTT),, $(TMPVAR))
FILT = $(filter-out $(TTT), $(TMPVAR))

subst:
    @echo "subst : $(SUBST)"

filter:
    @echo "filter-out : $(FILT)"

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