【问题标题】:Makefile: dependencies on directory content when creating a tar fileMakefile:创建 tar 文件时对目录内容的依赖
【发布时间】:2011-06-07 20:00:43
【问题描述】:

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

# Makefile v0

tar:
    tar -cf tarfile.tar dir

.PHONY: tar

成为:

# 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 中的文件列表吗?如果是这样,最简单的方法是什么?

【问题讨论】:

    标签: dependencies directory makefile tar


    【解决方案1】:

    这就是我将如何使用它。

    .PHONY: .FORCE
    .FORCE:
    
    dirstamp: .FORCE
            hxdirstamp subdir/ >$@.tmp; \
            cmp -s $@ $@.tmp || mv $@.tmp $@; \
            rm -f $@.tmp;
    
    my.tar: dirstamp
            tar -cf $@ subdir/;
    

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

    【讨论】:

    • 不错。根据这个答案,一位同事想出了一个针对dirstamp 目标的优化配方:[ ! -e $@ -o "$(find subdir/ -newer $@ -print -quit)" ] &amp;&amp; touch $@
    【解决方案2】:

    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 好一点,但你明白了。)

    【讨论】:

    • 为什么你认为这比Makefile v2 更好?更改src/a后如何解决失败?另请注意,我故意没有将查找结果限制为type f(或! -type d),以支持从dir的子目录添加/删除文件。
    • 没错,它与 Makefile v1 非常相似。事实上,与我上面的建议相比,我更喜欢 v1 两线。 V2 简直坏掉了。在 v2 中,您没有告诉 make 执行 dir/a 的配方将需要运行 tarfile.tar 的配方。它非常脆弱,并且在 -jn 下对于 n 的某些值会静默失败(您还需要将 find 表达式上的 $ 加倍:$$(find...))。
    猜你喜欢
    • 1970-01-01
    • 2011-08-05
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2012-12-26
    • 2016-10-21
    相关资源
    最近更新 更多