Thursday, 31 March 2011

More Making Make Make Sense

One of the  most annoying things in the observable universe is the tendency of make when given makefiles written by cadet level engineers to silently "not do" things.

The canonical way of provoking this behaviour is lists of things that you produce with one or more $(wildcard) which you then use later on -- a typical "gather-and-work" operation.

Problem; what happens if your wildcard operations don't find anything? Because (say) a previous stage named them something different to what was expected. If you're lucky, you'll get a message saying that "cp myoutputs/" is expecting a second argument.

If you're unlucky (like I've just been) this'll happen inside a makefile invoked inside a makefile which is inside a chroot which is making a YUM repo so that stuff can be installed in a filetree which can be packed into a virtual machine image.... and the actual outcome is that after thirty hours of building junk there's something missing from your fresh VM. It's worked all the way down the build of course, because the makefile has no constraint saying that there has to be something in that list.

Wouldn't it be lovely if the makefile did some sanity checking about these things?

Here's how we can do this in a nice handy functional-style way.

sanity_not_empty_list = $(if $($1),@true, @echo "";echo "";echo "EMPTY LIST: $1"; echo ""; echo ""; false )

MOOCOWS := some stuff

   $(call sanity_not_empty_list,MOOCOWS)
   $(call sanity_not_empty_list,MOOCOWS2)

Moocows are, of course, named for the extinct species of Old Earth. Test cases are always best named for those extinct species; partially because there's so many of them.

When the "moocows" target is attempted, the second sanity check will halt with a big banner error message. Brilliantly, it tells you which variable isn't set, which is a damn sight more useful than an error telling you cp doesn't have enough args. And it's WAY better than something simply ignoring your missing files.

No comments:

Post a Comment