来自docs:
$(filter PATTERN...,TEXT)
返回TEXT中做匹配any的所有以空格分隔的单词 PATTERN字样,删除不匹配的任何字词。该 模式是使用%
编写的,就像使用的模式一样patsubst
以上功能。
$(filter-out PATTERN...,TEXT)
返回TEXT中不匹配的所有以空格分隔的单词 任何PATTERN单词,删除做匹配一个或的单词 更多。这与filter
函数完全相反。
“ 空白 - 分隔的单词”是什么意思?
嗯,我们认为我们知道。至少,当假设一个“正常”的语言环境时。
因此,对于“C”(“POSIX”)区域设置we have:
“空间”
定义要归类为空白字符的字符。
在POSIX语言环境中,至少应包括<space>
,<form-feed>
,<newline>
,<carriage-return>
,<tab>
和<vertical-tab>
。
现在,一个makefile,如下所示:
define foo
a
b
endef
all :
echo '$(filter a b,$(foo))'
正在运行,我得到:
echo ''
让我们试试filter-out
案例:
define foo
a
b
endef
all :
-echo '$(filter-out a b,$(foo))'
正在运行,我得到:
echo 'a
/bin/sh: 1: Syntax error: Unterminated quoted string
makefile:8: recipe for target 'all' failed
make: [all] Error 2 (ignored)
b'
/bin/sh: 1: Syntax error: Unterminated quoted string
makefile:8: recipe for target 'all' failed
make: [all] Error 2 (ignored)
所以,显然Make在这里没有正确处理合法的white-space
(换行符)。
右?
答案 0 :(得分:1)
问题是您需要转义foo
变量中的换行符或将其值传递到适当的位置。
与在makefile中编写任何embeded shell脚本一样,您需要转义每一个新行。 $(foo)
只会复制粘贴来自foo
多行变量的内容。因此,对于给定的foo
值,下面的配方将引发语法错误:
test1:
echo '$(foo)'
类似的事情适用于您的filter-out
示例。我不确定为什么filter
函数没有语法错误。
第一个解决方案。如上所述,转义换行符是其中一个解决方案:
define foo
a\
b
endef
test1:
echo '$(foo)'
好处是您无需更改all
食谱。
第二个解决方案。在大多数情况下,您可能不想更改/编辑/解析多行变量。然后,您将需要使用shell
函数,该函数将直接调用shell命令,而不是将脚本粘贴到makefile内容中,然后解析它。我们的测试配方将如下所示:
define foo
a
b
endef
test2:
echo $(shell echo '$(foo)')
请注意,shell
function将输出换行符转换为单个空格。