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

时间:2011-01-12 13:06:16

标签: dependencies directory makefile tar

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

2 个答案:

答案 0 :(得分:2)

这就是我如何使用它。

.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依赖项,会被忽略)。

答案 1 :(得分:0)

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

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

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