GNU Make 配方中可能有变量吗?
像这样的事情不起作用:
%_t.mkd : %.mkd
REV=$$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ )
echo $${REV}
有没有什么方法可以让它发挥作用?
如您所见,我想要提取文件更改的修订版本,然后在完整配方中使用它。不幸的是,我无法使用它,svn:keywords
因为我需要相关文档之外的修订号。
答案1
这不起作用,因为该make
工具会为每行配方启动一个新的 shell 进程。而且 shell 变量(甚至是“导出的”环境变量)不可能“向上”传播;只要 shell 进程退出,它们就会消失。
\
传统方法是使用Makefile加入配方行:foo: bar baz line1; \ line2; \ line3
(请注意,命令必须使用
;
或分隔&&
,因为反斜杠也会传递给执行相同行连接的 shell。)也可以看看
info make "Splitting Lines"
和info make "Splitting Recipe Lines"
在 GNU Make 手册中。另一种方法是
make
使用指令告诉整个配方始终使用一个 shell 进程.ONESHELL
:.ONESHELL: foo: bar baz line1 line2 line3
(请注意,虽然
.ONESHELL
POSIX 建议使用,并非所有的 make 版本都支持它;例如,BSD make 只有一个命令行标志。但这不应该是个问题。)
答案2
谢谢https://stackoverflow.com/questions/6519234/cant-assign-variable-inside-recipe
这是改变配方中变量的解决方案:
recipe: $(eval variablename=whatever)
答案3
考虑到@user3645902 所提到的,以下是主要问题的解决方案:
recipe:
@$(eval REV=`svn info $<|grep 'Last Changed Rev'|cut -f4 -d`)
@echo $(REV)
答案4
在这种情况下,设置 undef Makefile 函数参数的这种方式$(1)
有效:
# usage:
# install-api-node:
# $(call install-img,linux_user)
define install-img
APPUSR=$(eval APPUSR=`echo appusr`)
APPUSR=$(or $(1),$(APPUSR))
@echo example usage : docker run -it -d --restart=always \
-v $$(pwd):/opt/project-source-dir \
-v $$HOME/.aws:/home/$(APPUSR)/.aws \
--name my-container my-image ;
endef