制定目标取决于变量

时间:2012-07-25 10:36:04

标签: variables makefile

我希望(GNU)make在变量发生变化时重建。我怎样才能做到这一点?

例如,

$ make project
[...]
$ make project
make: `project' is up to date.

...喜欢它,但我更喜欢

$ make project IMPORTANTVARIABLE=foobar
make: `project' is up to date.

重建部分或全部project

4 个答案:

答案 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)

您可能希望使用ifdefifeq,具体取决于最终目标。有关示例,请参阅手册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作为先决条件。