GNU Make:shell cat 文件生成没有换行符的内容

GNU Make: shell cat file yields contents without newlines

生成文件:

.PHONY: all
SHELL:=/usr/bin/env bash
all:
    $(eval x=$(shell cat file))
    @echo "$x"

文件:

foo 
bar

输出:

foo bar

如何在不丢失换行符的情况下将文件内容放入 make 变量?

您不能使用 shell 执行此操作,如 its documentation 中所述。

如果您有足够新的 GNU make 版本,您可以使用 the file function

Make 将换行符从 shell 输出转换为空格(参见 here):

The shell function performs the same function that backquotes (‘`’) perform in most shells: it does command expansion. This means that it takes as an argument a shell command and evaluates to the output of the command. The only processing make does on the result is to convert each newline (or carriage-return / newline pair) to a single space. If there is a trailing (carriage-return and) newline it will simply be removed.

因此,您不能直接从 $(shell) 命令中保留空格。也就是说,make does 允许使用 define 的多行变量——但要注意,尝试使用此类变量是有问题的。考虑:

define x
    foo
    bar
endef

all:
     @echo "$x"

Make 扩展了 $x,你最终得到:

all:
    @echo "    foo
    bar"

(换行符被认为是配方行的结尾……)。

根据您的需要,您可以使用 bash 变量来解决此问题:

all:
    @x=$$(cat file); \
    echo $$x

或者可能将您的输出存储在一个文件中,并在必要时引用它。

all:
    eval (cat file >> output.txt)
    cat output.txt

(是的,最后一个写的很复杂,但我不确定你想做什么,这允许你的命令的输出在配方行中保持不变)。

如果确保文件内容不包含任何二进制数据,并且您愿意在每次访问变量时进行额外的处理,那么您可以:

foo:=$(shell cat file | tr '\n' '')

all:
    @echo "$(shell echo "$(foo)" | tr '' '\n')"

请注意,您不能使用空值 [=11=],我怀疑这可能意味着我的 Make 副本中存在缓冲区溢出错误。