I would like to compare the sizes of two files within the scope of a rule in my Makefile. In my rule, I'm converting PDFs to PNGs like this:
.pdf.png:
@convert $< -resize 800x800 -quality 85% $@
Since some of the PNGs are not significantly smaller than their PDF parent but have pretty bad quality, I would like to delete those PNGs after the conversion process. My first idea was to add something like this to the above rule:
COMP = "`wc -c <$<` / `wc -c <$@`"|bc
if [ $COMP -lt 2 ]; then \
rm $@; \
fi
The first line gives me the compression factor of the old PDF file vs the new PNG file. That is, "bad compression" giving a value of 0 or 1 should result in deleting the freshly generated PNG file. Unfortunately, I'm not really experienced in writing Makefiles and, specifically, in piping commands. So, my problem is, I don't know how to use the result of the first line of the second code snippet and use it in the if statement to compare it with another value. Any hints would be highly appreciated :-)
Each line of a recipe is executed in a different shell. So, you can use shell variables only in a single line of your recipe. But you can also use line-continuation (\
) for better readability:
var=`some-shell-command`; \
echo "$$var"
is equivalent to:
var=`some-shell-command`; echo "$$var"
Remember to escape the make expansion ($$
) when needed. In your case, a recipe could be:
%.png: %.png
@convert $< -resize 800x800 -quality 85% $@; \
i=`stat -c%s $<`; \
o=`stat -c%s $@`; \
$$(( o > 2*i )) && rm -f $@ || true