如何在Makefile中正确清理?

时间:2011-02-24 05:16:00

标签: makefile find

对于小型C / C ++项目,我习惯于编写干净的目标,如下所示:

clean:
    $(RM) *.o *~

对于稍微大一点的项目,当在子目录中调度源时,比如src1src2,我会写

clean:
    $(RM) src1/*.o src1/*~ src2/*.o src2/*~

随着更多的子目录,它很快变得混乱......所以我意识到我可以像这样使用find命令:

clean:
    find . -name "*.o" -exec $(RM) {} \;
    find . -name "*~"  -exec $(RM) {} \;

但是我看到人们经常将findxargs结合使用,而不是使用-exec,我想知道为什么它似乎工作得很好......

您使用什么以及为什么?

我知道对于大型项目或者为了更好的兼容性,我应该使用cmake或autotools,但我喜欢简单的Makefile用于小项目。

2 个答案:

答案 0 :(得分:3)

我习惯的'find'版本(GNU find)也支持'-delete'标志。我可能会这样做:

clean:
    find . -name '*.o' -delete

因为它有效,简单而且干净。

如果要删除多个模式,我通常会重复命令:

clean:
    rm -f a.out
    find . -name '*.o' -delete
    find . -name '*~' -delete

答案 1 :(得分:1)

因为exec每个文件都会删除一个子流程。另一方面,xargs将它们分批。

实际上是区别:

rm src1/a.o
rm src1/b.o
rm src2/c.o

rm src1/a.o src1/b.o src2/c.o

除非你有一个很多的文件,否则它可能不会那么重要,但是值得知道这个用例。

但我不使用这些方法的 。我让每个目录负责构建自己(以及它的下级目录),在那里有一个Makefile。然后,从顶级make,我有类似的东西:

all:
    for i in module1 module2 \
    do \
        cd $i \
        $(MAKE) all \
        cd .. \
    done

clean目标的相同交易。我假设清理对每个子目录都是相同的操作。

通过这样做,相关的行动是本地化的。如果我有一个目录.o文件实际上是我要链接的第三方对象(所以我没有源代码),我确保clean不会删除它们makefile文件。你所拥有的解决方案会使它们软化,引起很多焦虑和咬牙切齿: - )