在 GNU Make 中,函数调用的输出被视为单独的一行,由 shell 执行

In GNU Make, output of function call is being treated as a separate line to be executed by the shell

我在 GNU Make 文件中定义了以下函数:

define comma-seperated
    $(shell printf '$(foreach name,$(1),$(name),)' | head -c -1)
end

你会像这样使用它:

names := John Paul George Ringo
.PHONY: test
test:
   @echo Hey $(call comma-sepperated, "$(names)")

但输出为:

Hey
"John,Paul,George,Ringo"

并产生错误:

/bin/sh: John,Paul,George,Ringo: command not found
make: *** [Makefile: test] Error 127

为什么函数调用的输出被移到单独的一行,为什么 shell 试图将其作为命令执行?

正如我所说,我无法重现这一点。此外,您的 makefile 在逗号后添加了空格,而您的示例输出没有这些,所以有些东西明显不同。请尽量确保您的问题使用准确的示例代码并显示准确的输出。

但是,define 变量允许包含换行符,如果包含换行符,这些换行符将被保留并解释为它在其中扩展的任何配方中的换行符。例如,您可以在define,包括多行,然后在规则中使用它,它将按预期工作。 所以,我怀疑在你的真实版本中,扩展中有一个初始换行符。

我看不出有什么好的理由为此使用如此复杂的方法:调用、shell、printf、head 等的难以理解的组合。它更简单在 make 中完成所有这些。

这是一种方法:

EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
COMMA := ,

comma-separated = $(subst $(SPACE),$(COMMA),$(strip $(1)))

names := John Paul George Ringo
.PHONY: test
test:
        @echo Hey $(call comma-separated,$(names))