我希望(GNU)make
在变量发生变化时重建。我怎样才能做到这一点?
例如,
$ make project
[...]
$ make project
make: `project' is up to date.
...喜欢它,但我更喜欢
$ make project IMPORTANTVARIABLE=foobar
make: `project' is up to date.
重建部分或全部project
。
答案 0 :(得分:7)
Make并非旨在引用可变内容,但Reinier的方法向我们展示了变通方法。不幸的是,使用变量值作为文件名既不安全又容易出错。希望Unix工具可以帮助我们正确编码值。所以
IMPORTANTVARIABLE = a trouble
# GUARD is a function which calculates md5 sum for its
# argument variable name. Note, that both cut and md5sum are
# members of coreutils package so they should be available on
# nearly all systems.
GUARD = $(1)_GUARD_$(shell echo $($(1)) | md5sum | cut -d ' ' -f 1)
foo: bar $(call GUARD,IMPORTANTVARIABLE)
@echo "Rebuilding foo with $(IMPORTANTVARIABLE)"
@touch $@
$(call GUARD,IMPORTANTVARIABLE):
rm -rf IMPORTANTVARIABLE*
touch $@
在这里,您实际上将目标依赖于一个名为$(NAME) GUARD $(VALUEMD5)的特殊文件,该文件可以安全引用并且与变量的值具有(几乎)一对一的对应关系。请注意,'call'和'shell'是GNU Make扩展。
答案 1 :(得分:6)
您可以使用空文件来记录变量的最后一个值:
someTarget: IMPORTANTVARIABLE.$(IMPORTANTVARIABLE)
@echo Remaking $@ because IMPORTANTVARIABLE has changed
touch $@
IMPORTANTVARIABLE.$(IMPORTANTVARIABLE):
@rm -f IMPORTANTVARIABLE.*
touch $@
在make
运行后,目录中将出现一个空文件,其名称以IMPORTANTVARIABLE.
开头,并附加了变量的值。这基本上包含有关变量IMPORTANTVARIABLE
的最后一个值的信息。
您可以使用此方法添加更多变量,并使用模式规则使其更复杂 - 但此示例为您提供了它的要点。
答案 2 :(得分:1)
您可能希望使用ifdef
或ifeq
,具体取决于最终目标。有关示例,请参阅手册here。
答案 3 :(得分:0)
我可能会迟到一个答案,但这是使用Make conditional syntax进行此类依赖的另一种方式(适用于GNU Make 4.1,GNU bash,Windows版本4.3.48(1)上的Ubuntu上的Bash) - 发布(x86_64-pc-linux-gnu)):
1 ifneq ($(shell cat config.sig 2>/dev/null),prefix $(CONFIG))
2 .PHONY: config.sig
3 config.sig:
4 @(echo 'prefix $(CONFIG)' >config.sig &)
5 endif
在上面的示例中,我们通过自签名目标跟踪$(CONFIG)
变量,将其值降低到签名文件,该目标是在签名文件' s记录值与$(CONFIG)
变量的记录值不同。请注意第1行和第4行的前缀:当签名文件尚不存在时,需要区分大小写。
当然,消费者目标指定config.sig
作为先决条件。