如何使$(eval $(shell ...))在GNU make中工作

Bry*_*yan 13 shell makefile

make语法是换行符分隔的,但$(shell ...)用空格替换换行符.那么最不丑的方式是什么

$(eval $(shell program-that-emits-makefile-fragment))

这不像人们想象的那样有效.

Bet*_*eta 13

这可能会对你的想法有所帮助:

makefile_fragment:
  program-that-emits-makefile-fragment > $@

include makefile_fragment
Run Code Online (Sandbox Code Playgroud)

够了吗?如果需要,还可以使用其他技巧,例如让规则在程序生成的内容周围添加上下文,或者通过sed将输出管道化为一行,然后用反斜杠解析出来.

  • +10,如果可以的话.这是一个优雅且相当便携的解决方案. (3认同)

Gil*_*il' 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' '#')))
Run Code Online (Sandbox Code Playgroud)

更一般地说,就是这样 $(eval $(subst #,$(newline),$(shell myscript | tr '\n' '#')))

你必须选择一个不会出现在脚本输出中的字符; #似乎是个好人选.