考虑一个makefile
多行项目:
define ITEM
line $$ONE
line $$TWO
endef
item:
echo '$(ITEM)' | ... > $@
问题是,随着 ITEM 变得复杂,当我回显该项目时,我面临出现引用错误和其他问题的风险。
我还可以运行导出:
export ITEM
item:
print "%s\n" '$${ITEM}' | ...
但我不确定是否会有同样的错误。
是否有一些 make 函数可以将变量的内容直接注入到 shell 中,就像它被发送到一样/dev/stdin
?
# e.g. something like:
$(info $ITEM) | ...
我知道我可以将值直接写入文件,然后通过 shell 进行处理。但如果能够将其直接写入管道,则会缩短这一过程。
- 这将有一系列的命令,或引入如下要求
sponge
- 这也可能导致我不得不从简单的事情转向
envsubst
更重的事情,例如sed
允许就地修改(以避免安装海绵)
我还了解我可以将值导出到所有子 shell:
- 如果我的扩展包含在递归 make 项目中,或者包含大量导出开销的 make 项目中,则可能会出现问题(例如,在启用
parameter?=vars
时默认为 env 值会引入大量开销).SECONDEXPANSION
- 尤其是,导出过多可能会破坏
zsh
make 的 tab 补全性能,而这是 mac 用户的一项软性要求
但我没有证据证明出口echo "$$ITEM"
或print("%s/\n") "$$ITEM"
会有适当的逃逸。所以我必须测试它。
什么不是“方法”,而是实现这一目标的最佳实践?
如果答案是:使用$(file ..)
,并从那里修改文件,那就这样吧;只是想确保这是最佳的。
复杂变量扩展的常用解决方案是编写外部 shell 文件。或者编写脚本 (perl/python/awk)。或者甚至编写一个特殊的编译工具来生成实际编译所需的内容。并非一切都必须成为 的一部分
makefile
。这里的经验法则是:“如果您在处理变量、美元符号和引号时遇到困难——也许是时候考虑外部脚本了?”
在审查了接受的答案后,我将调整手册中的约定:
在我的例子中,我必须创建中间文件以保持简单
envsubst
(而不是)sed
,它将成为的模拟[email protected]
:下次我很有可能会以同样的方式去做这件事。