makefile:依赖性评估顺序
-
23-10-2019 - |
题
假设目标 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是生成的吗?
解决方案
您的原始规则是正确的。因为更新foo.files会导致foo_files的价值变得过时,因此您只需要确保通过使您的makefile依赖foo.foo.files:
Makefile : foo.files
其他提示
所以,我找到了关于阅读的答案 高级自动依赖性生成 结束 mad-scientist.net. 。基本上,可以通过GNU/MAKE 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
.
它不能在一次通行证中完成;制作确定在实际执行任何规则之前必须重建哪些目标,并且在这种情况下,目标的完整列表直到执行其中一个规则之前才存在。
这应该做到:
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
.)
不隶属于 StackOverflow