1

假设一个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 呢?

4

3 回答 3

4

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

Makefile : foo.files
于 2011-01-23T13:03:13.340 回答
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。)

于 2011-01-23T09:01:45.100 回答
0

因此,我在mad-scientist.net上找到了有关高级自动依赖生成的答案。基本上,可以通过 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.3并假设和的存在b-1.2.3

于 2011-01-23T10:21:32.117 回答