Makefile:依赖评估的顺序

时间:2011-01-23 06:58:11

标签: makefile dependencies gnu-make file-generation

假设目标foo.tar取决于文件列表foo.files,例如

FOO_FILES := $(shell cat foo.files)

foo.tar: foo.files $(FOO_FILES)
    tar -cf foo $(FOO_FILES)

现在假设需要生成foo.files,例如:

foo.files: foo.files.template
    sed -e "s/@{VERSION}/$(VERSION)/" < $< > $@

很明显,foo.files取决于foo.files.template,但如何确保在生成 foo.files之后评估FOO_FILES?

3 个答案:

答案 0 :(得分:4)

您的原始规则是正确的。因为更新foo.files会导致FOO_FILES的值变得过时,所以只需要确保通过使makefile依赖于foo.files来更新foo.files时gnu make重新评估你的Makefile:

Makefile : foo.files

答案 1 :(得分:0)

不能一次完成; Make确定在实际执行任何规则之前必须重建哪些目标,在这种情况下,在执行其中一个规则之前,目标的完整列表不存在。

这应该这样做:

FOO_FILES := $(shell cat foo.files)

foo.tar: foo.files
    $(MAKE) foo-tarball

.PHONY: foo-tarball
foo-tarball: $(FOO_FILES)
    tar -cf foo $^

修改:
正如OP指出的那样,这不会像书面那样有效;我遗漏了一个先决条件:

foo.tar: foo.files $(FOO_FILES)
    ...

请注意,即使foo.files没有改变,这也会递归,这不是绝对必要的;有可能纠正这一点,但不是优雅的。 (为了比较,我承认选择的解决方案比我的更清晰,即使目标与foo.tar无关,也会提升。)

答案 2 :(得分:0)

所以,我在 mad-scientist.net 上找到了关于Advanced Auto-Dependency Generation的答案。基本上,可以通过GNU / Make功能重新评估makefile。当存在生成包含的makefile的规则时,将在生成包含文件之后重新读取整个makefile。因此 -

# -*- mode: make -*-
VERSION := 1.2.3

foo.tar: foo.files $(FOO_FILES)
    tar cf $@ $(FOO_FILES)

clean:
    rm -f foo.files foo_files.mk foo.tar

foo.files: foo.files.template
    sed -e "s/@{VERSION}/$(VERSION)/" < $< > $@

# -- voodoo start here --
# This will ensure that FOO_FILES will be evaluated only
# *after* foo.files is generated.
foo_files.mk: foo.files
    echo "FOO_FILES := `xargs < $<`" > $@

include foo_files.mk
# -- voodoo ends here --

.PHONY: clean

- 似乎做对了。


......只是为了完整性:

foo.files.template是:

a-$(VERSION)
b-$(VERSION)

并假设存在a-1.2.3b-1.2.3