Makefile:创建 tar 文件时对目录内容的依赖

发布于 2024-10-12 02:24:00 字数 1087 浏览 7 评论 0原文

在我与 .PHONY 目标的战斗中,我重写了:

# Makefile v0

tar:
    tar -cf tarfile.tar dir

.PHONY: tar

to be:

# Makefile v1

tar: tarfile.tar

tarfile.tar: $(shell find dir)
    tar -cf $@ dir

.PHONY: tar

这似乎适用于一个玩具示例。

但是,我可以看到这可能会做错误的事情,具体取决于评估 $(shell find dir) 的时间。如果有一些规则会在解析 Makefile 后在 dir 中创建或删除文件,则这可能会被破坏。


更新

根据@user562374的回答,我似乎有更好的解决方案,但考虑这种情况:

# Makefile v2

tar: tarfile.tar

tarfile.tar: dir/.dirstamp
    tar --create --exclude $< --file $@ $(<D)

dir/.dirstamp: .FORCE
    [ ! -e $@ -o "$(find $(@D) -newer $@ -print -quit)" ] && touch $@

dir/a: src/a
    cp $< $@

.FORCE:
.PHONY: .FORCE tar

现在假设src/a已更改。由于 tarfile.tardir/a 之间不存在依赖关系(不是直接也不是间接),因此可能会评估 tarfile.tar: 目标在 dir/a: 之前,因此 tarfile.tar 不会是最新的。


所以,我的问题是:处理此类案件的最佳做法是什么?我必须单独维护 dir 中的文件列表吗?如果是这样,最简单的方法是什么?

In my battle against .PHONY targets I re-wrote:

# Makefile v0

tar:
    tar -cf tarfile.tar dir

.PHONY: tar

to be:

# Makefile v1

tar: tarfile.tar

tarfile.tar: $(shell find dir)
    tar -cf $@ dir

.PHONY: tar

Which seems to work for a toy example.

However, I can see that this might do the wrong thing, depending on the time when $(shell find dir) is evaluated. If there is some rule that will create or delete files in dir after the Makefile is parsed, this might break.


Update

Based on @user562374's answer, I seem to have a better solution, but consider this case:

# Makefile v2

tar: tarfile.tar

tarfile.tar: dir/.dirstamp
    tar --create --exclude 
lt; --file $@ $(<D)

dir/.dirstamp: .FORCE
    [ ! -e $@ -o "$(find $(@D) -newer $@ -print -quit)" ] && touch $@

dir/a: src/a
    cp 
lt; $@

.FORCE:
.PHONY: .FORCE tar

Now suppose src/a has been changed. Since there is no dependency between tarfile.tar and dir/a (not direct nor indirect), the tarfile.tar: target might be evaluated before dir/a:, and thus tarfile.tar will not be up-to-date.


So, my questions are: What is the best practice of dealing with such cases? Must I maintain the list of files in dir separately? If so what is the easiest way of doing it?

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

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

发布评论

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

评论(2

看轻我的陪伴 2024-10-19 02:24:00

我就是这样使用它的。

.PHONY: .FORCE
.FORCE:

dirstamp: .FORCE
        hxdirstamp subdir/ >[email protected]; \
        cmp -s $@ [email protected] || mv [email protected] $@; \
        rm -f [email protected];

my.tar: dirstamp
        tar -cf $@ subdir/;

您还可以使用 ls -Rl 代替 dirstamping,但请注意,它会受到区域设置、权限和大小更改的影响(所有这些,如果只是 make 依赖项,都将被忽略) )。

That is how I would use it.

.PHONY: .FORCE
.FORCE:

dirstamp: .FORCE
        hxdirstamp subdir/ >[email protected]; \
        cmp -s $@ [email protected] || mv [email protected] $@; \
        rm -f [email protected];

my.tar: dirstamp
        tar -cf $@ subdir/;

You can also use ls -Rl instead for dirstamping, but be aware that it is subject to influence from the locale, permission and size changes (all of which, were it just a make dependency, would be ignored).

剧终人散尽 2024-10-19 02:24:00

dir/ 包含比它更新的文件时,为什么不将 tarfile.tar 标记为 .PHONY 呢?

$(if $(shell find dir -type f -newer file.tar),$(eval .PHONY: file.tar))
file.tar: ; tar cvf $@ dir/

(也许 !-type d 会比 -type f 好一点,但你明白了。)

Why not just mark tarfile.tar as .PHONY when dir/ contains files newer than it?

$(if $(shell find dir -type f -newer file.tar),$(eval .PHONY: file.tar))
file.tar: ; tar cvf $@ dir/

(Maybe ! -type d would be a tad better than -type f, but you get the idea.)

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