make语法是换行符分隔的,但$(shell ...)用空格替换换行符。那么什么是最不丑的方式
$(eval $(shell program-that-emits-makefile-fragment))
不能按照人们喜欢的方式运作。
答案 0 :(得分:13)
这可能会对你的想法有所帮助:
makefile_fragment:
program-that-emits-makefile-fragment > $@
include makefile_fragment
这够了吗?如果需要,还可以使用其他技巧,例如让规则在程序生成的内容周围添加上下文,或者通过sed将输出管道化为一行,然后用反斜杠解析出来。
答案 1 :(得分:5)
已经向GNU make维护者报告了这个问题:
http://savannah.gnu.org/bugs/?28230
以下评论结束:
正如菲利普所说,这是预期/记录的行为 我建议使用“include”而不是eval;让你的脚本写出一个文件,然后包含该文件。
已添加:有一种解决方法!这是一个示例GNUmakefile(用制表符替换8个空格;是的,在define newline
之后有两个空行):
define newline
endef
$(eval $(subst #,$(newline),$(shell { echo 'war:'; echo ' echo "not love?"'; echo ' echo "Give peace a chance!"'; } | tr '\n' '#')))
更一般地说,那是$(eval $(subst #,$(newline),$(shell myscript | tr '\n' '#')))
您必须选择一个不会出现在脚本输出中的字符; #
似乎是一个很好的候选人。
答案 2 :(得分:0)
这是通过劫持%替换字符来实现的,所以我们不需要依赖于未出现在myscript输出中的char。
define nl
enddef
$(foreach line, $(shell myscript | sed -e 's/%/\\%/' -e 's/$$/%/'), \
$(eval $(patsubst %, $(line), $(nl))))