假设目标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?
答案 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.3
和b-1.2.3
。