功能“过滤器”和“过滤器”不会删除换行符

时间:2015-08-21 08:57:01

标签: makefile gnu-make

来自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(换行符)。

右?

1 个答案:

答案 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将输出换行符转换为单个空格。