比较 Makefile 中的文件大小

Compare file sizes in Makefile

我想在 Makefile 的规则范围内比较两个文件的大小。 在我的规则中,我将 PDF 转换为 PNG,如下所示:

.pdf.png:
    @convert $< -resize 800x800 -quality 85% $@

由于一些 PNG 并不比它们的 PDF 父级小很多,但质量很差,我想在转换过程后删除这些 PNG。 我的第一个想法是在上面的规则中添加类似这样的内容:

COMP = "`wc -c <$<` / `wc -c <$@`"|bc
if [ $COMP -lt 2 ]; then \
    rm $@; \
fi

第一行给出了旧 PDF 文件与新 PNG 文件的压缩系数。也就是说,"bad compression" 给出 0 或 1 的值应该导致删除新生成的 PNG 文件。 不幸的是,我在编写 Makefile 方面并没有真正的经验,特别是在管道命令方面。 所以,我的问题是,我不知道如何使用第二个代码片段第一行的结果并在 if 语句中使用它来将它与另一个值进行比较。 任何提示将不胜感激:-)

配方的每一行都在不同的 shell 中执行。因此,您只能在食谱的一行中使用 shell 变量。但您也可以使用续行符 (\) 以获得更好的可读性:

var=`some-shell-command`; \
echo "$$var"

相当于:

var=`some-shell-command`; echo "$$var"

记得在需要时转义 make 扩展 ($$)。在您的情况下,食谱可以是:

%.png: %.png
    @convert $< -resize 800x800 -quality 85% $@; \
    i=`stat -c%s $<`; \
    o=`stat -c%s $@`; \
    $$(( o > 2*i )) && rm -f $@ || true

好的。我现在明白了。我采用了 Renaud Pacalet 的方法来满足我的需要。对于那些感兴趣的人,我的规则如下:

.pdf.png:
    @convert $< -resize 800x800 -quality 85% $@
    @echo converted $<
    @COMP=$$((`stat -c%s "$<"`/`stat -c%s "$@"`)); [ $$COMP -lt 2 ] && echo "bad compression: remove $@" && rm $@ || true

这会调整输入图像的大小,如果整数比率为 input/output < 2,则再次删除输出文件(比率为 0 或 1 我认为压缩不好)。