Shell命令有时需要很长时间才能运行,因此您可能不希望VAR = $(shell slow-cmd)
(使用=
,每次引用变量时都会运行slow-cmd)。使用VAR := $(shell slow-cmd)
可能很有用,但如果您正在构建一个不需要扩展变量的目标,那么您将再次调用slow-cmd
。在下面的makefile(使用gnu-make)中,您可以获得所需的行为:定义V2值的shell命令永远不会被多次调用,对于目标foo
,它根本不会被调用。但这是一个令人发指的污垢。是否有更合理的方法来确保变量仅在需要时定义,但从未评估过多次?
V1 = $(shell echo evaluating V1 > /dev/tty; echo V1 VALUE)
all: foo bar V2
@echo $(V1) $@
@echo $(V2) $@
foo:
@echo $(V1) $@
bar: V2
@echo $(V1) $@
@echo $(V2) $@
V2:
$(eval V2 := $(shell echo evaluating V2 > /dev/tty; echo V2 VALUE))
.PHONY: all foo bar
答案 0 :(得分:5)
如果没有技巧,就没有办法做到这一点,但是有一种比你正在使用更清洁的方式(也许)。您可以使用:
V1 = $(eval V1 := $$(shell some-comand))$(V1)
有关详细信息的详细信息和解释,请参阅this page。
答案 1 :(得分:0)
特定于目标的延迟变量是一个选项:
host> cat Makefile
foo: VFOO = $(shell echo "VFOO" >> log.txt; echo "VFOO")
foo:
@echo '$(VFOO)' > $@
bar: VBAR = $(shell echo "VBAR" >> log.txt; echo "VBAR")
bar:
@echo '$(VBAR)' > $@
host> make foo
host> cat log.txt
VFOO
host> make foo
make: 'foo' is up to date.
host> cat log.txt
VFOO
host> make bar
host> cat log.txt
VFOO
VBAR
host> make bar
make: 'bar' is up to date.
host> cat log.txt
VFOO
VBAR