Makefile gnumake:shell cat文件生成的内容没有换行符
生成文件:Makefile gnumake:shell cat文件生成的内容没有换行符,makefile,gnu-make,Makefile,Gnu Make,生成文件: .PHONY: all SHELL:=/usr/bin/env bash all: $(eval x=$(shell cat file)) @echo "$x" 文件: 输出: foo bar 如何在不丢失换行符的情况下将文件内容放入make变量?如中所述,不能使用shell执行此操作 但是,如果您有足够新的GNU make版本,则可以使用。make将新行从shell输出转换为空格(请参阅): shell函数执行与反引号(“`”)相同的函数 在大多数shell中
.PHONY: all
SHELL:=/usr/bin/env bash
all:
$(eval x=$(shell cat file))
@echo "$x"
文件:
输出:
foo bar
如何在不丢失换行符的情况下将文件内容放入make变量?如中所述,不能使用
shell执行此操作
但是,如果您有足够新的GNU make版本,则可以使用。make将新行从shell
输出转换为空格(请参阅):
shell函数执行与反引号(“`”)相同的函数
在大多数shell中执行:它执行命令扩展。这意味着
将shell命令作为参数,并计算为的输出
命令。对结果进行的唯一处理是转换
每个换行符(或回车/换行符对)到单个空格。如果
有一个尾随(回车和)换行符,它将是简单的
删除
因此,不能直接从$(shell)
命令中保留空格。也就是说,make确实允许使用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' '\1')
all:
@echo "$(shell echo "$(foo)" | tr '\1' '\n')"
请注意,您不能使用null\0
,我怀疑这可能意味着我的Make副本中存在缓冲区溢出错误。您不能。该行为在中有清楚的描述,我们也能够通过配方部分中的“$$()”调用来实现我(旧)版本的make的目的。当然,如果您真正想要的只是在shell中有值,而不是在make变量中,那么您可以只使用shell构造,如$$()
并且根本不使用make函数。有时,你会陷入某种思维方式。作为make变量传递将对submake有用;特别是如果submake无法访问该文件。因此,file命令是完整的解决方案
foo:=$(shell cat file | tr '\n' '\1')
all:
@echo "$(shell echo "$(foo)" | tr '\1' '\n')"