Makefile:依赖评估的顺序

发布于 2024-10-13 19:52:22 字数 437 浏览 11 评论 0原文

假设目标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)/" < $< > $@

很明显< code>foo.files 依赖于 foo.files.template,但是如何确保在生成 foo.files 后评估 FOO_FILES?

Assume a target foo.tar, that depends on a list of files foo.files, e.g.

FOO_FILES := $(shell cat foo.files)

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

Now suppose that foo.files need to be generated e.g.:

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

It is clear that foo.files depends on foo.files.template, but how can one make sure that FOO_FILES is evaluated after foo.files is generated?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

剧终人散尽 2024-10-20 19:52:22

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

Makefile : foo.files

Your original rules are correct. Because updating foo.files causes the value of FOO_FILES to become outdated you just need to make sure your Makefile is re-evaluated by gnu make when foo.files has been updated by making your Makefile depend on foo.files:

Makefile : foo.files
誰ツ都不明白 2024-10-20 19:52:22

因此,我在 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)/" < 
lt; > $@

# -- 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 < 
lt;`" > $@

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

.PHONY: clean

似乎做了正确的事。


...为了完整起见:

foo.files.template 是:

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

并假设存在 a-1.2.3b-1.2.3.

So, I found an answer reading about Advanced Auto-Dependency Generation over at mad-scientist.net. Basically, it is possible to re-evaluate a makefile by way of a GNU/Make feature. When there is a rule to generate an included makefile, the entire makefile will be re-read after the generation of the included file. Thus --

# -*- 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)/" < 
lt; > $@

# -- 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 < 
lt;`" > $@

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

.PHONY: clean

-- seems to do the right thing.


... and just for completeness:

foo.files.template is:

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

and assume the presence of a-1.2.3 and b-1.2.3.

舞袖。长 2024-10-20 19:52:22

这不可能一次性完成; 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 无关,也会递归。)

It can't be done in one pass; Make determines which targets must be rebuilt before it actually executes any rule, and in this case the full list of targets doesn't exist until one of the rules is executed.

This should do it:

FOO_FILES := $(shell cat foo.files)

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

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

EDIT:
As the OP points out, this will not work as written; I left out a prerequisite:

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

Note that this will recurse even if foo.files has not changed, which is not strictly necessary; it is possible to correct this, but not elegantly. (For comparison, the selected solution, which I admit is cleaner than mine, recurses even if the target has nothing to do with foo.tar.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文