如何执行make bar时不解析FOOVAR对应的shell命令?
问题解答
首先直接给结论:不可行。因为GNU Make在读取Makefile的阶段就会解析所有的变量赋值(包括你这种目标特定的FOOVAR:=$(shell ...)),不管你最终要执行哪个目标。也就是说,只要Makefile里写了这个赋值语句,只要运行make(哪怕是make bar),prog_to_execute_only_on_foo都会被执行一次。
不过有几种可靠的办法可以解决这个问题,确保只有执行make foo时才会触发那个shell命令:
方法1:将变量赋值移到目标的命令脚本中
把变量的定义放到foo目标的shell命令里,这样只有当实际执行foo的构建步骤时,才会运行那个shell命令:
foo: # 仅在执行foo目标时才会执行这个shell命令并赋值 FOOVAR=`prog_to_execute_only_on_foo`; echo "foo $$FOOVAR" bar: echo "bar"
这里注意要用$$FOOVAR来引用变量,因为Make会把单个$解析成自己的变量引用,双$才会传递给shell。
方法2:利用MAKECMDGOALS做条件判断
MAKECMDGOALS是Make内置的变量,保存了你在命令行指定的目标列表。我们可以用它来判断是否需要定义FOOVAR:
# 只有当命令行目标包含foo时,才解析FOOVAR的shell命令 ifeq ($(findstring foo,$(MAKECMDGOALS)),foo) FOOVAR:=$(shell prog_to_execute_only_on_foo) endif foo: echo "foo $(FOOVAR)" bar: echo "bar"
这样执行make bar时,条件不成立,FOOVAR不会被定义,自然也不会触发shell命令。如果执行make foo或者make foo bar,条件成立,才会执行那个shell命令。
方法3:使用延迟展开变量(谨慎使用)
把:=换成=,让变量延迟展开——也就是只有当变量被实际使用时才会解析shell命令:
foo: FOOVAR=$(shell prog_to_execute_only_on_foo) foo: echo "foo $(FOOVAR)" bar: echo "bar"
这个方法的前提是只有foo目标的命令里会用到FOOVAR,如果其他地方不小心引用了FOOVAR,还是会触发shell命令。相比前两种方法,它的可靠性稍弱,不过在简单场景下也能生效。
内容的提问来源于stack exchange,提问作者Kludge
相关产品推荐
相关产品推荐

