我知道GNU Make中两种变量之间的区别。
我目前正在编写一个构建系统,其中在子目录(例如VERSION)中定义了某些变量。为了简化子目录作者的工作,我不想强迫他们使变量在全局范围内唯一。我也想避免递归。
我的问题是,现在我需要一种方法来提供一些简单的库目标,以在定义目标时扩展这些公共变量。举一个简单的例子:
FOO := Bar
PHONY: $(FOO)
$(FOO):
@echo $(FOO)
FOO := Definitely not Bar
PHONY: test2
test2: Bar
@echo $(FOO)
我需要make test2
的输出为
Bar
Definitely not Bar
我当然可以在第一个规则中使用临时变量强制FOO扩展,但是随后我需要一种可靠地定义新临时变量的方法。有没有办法扩大目标,例如使用eval?
编辑:在示例代码中使FOO的奇怪扩展更加清楚。
答案 0 :(得分:1)
似乎您只是想target-specific variables, 例如
制作文件
.PHONY: Bar test2
Bar: FOO := Bar
Bar:
@echo $(FOO)
test2: FOO := Definitely not Bar
test2: Bar
@echo $(FOO)
运行方式:
$ make test2
Bar
Definitely not Bar
(请注意,.PHONY
和所有特殊目标一样,都以.
开头)
答案 1 :(得分:0)
您可以使用$(eval …)
编写一些功能良好的代码(用于双关语)。您可以编写闭包,并决定什么时候展开。
考虑此变量:
define rule =
PHONY: ${FOO}
${FOO}:
@echo $$@ ${FOO}
endef
这里没什么奇怪的。但是看看将其传递给 eval
会发生什么?FOO := Bar
$(eval ${rule})
我们最好详细看看最后一行。
$(eval ${rule})
${rule}
$$
扩展为$
${FOO}
被Bar
PHONY: Bar
Bar:
@echo $@ Bar
${FOO}
当前值如何烘焙到配方中吗?$(eval)
很好。
FOO := Dead
$(eval ${rule})
FOO := Beef
$(eval ${rule})
避开全局变量而使用局部参数并不是很遥远:
$(call makerule,Dead)
$(call makerule,Beef)
一定是件好事,不是吗?
[AFAICR eval 在 make 3.81中效果不佳,因此请至少使用版本3.82]