Coverage processing on multiple Java projects with gmake
.PHONY: checkout all clobber clean $(checkout.all)


There's no clobber target, so I think that will be ignored.



The root variable is unnecessary (CURDIR should be well known by anyone using make), and is even defined twice.



names=$(shell cat etc/projects.txt)


In my experience it's more common to write out the list in the makefile. If this is so long as to clutter up the file, you could create a separate makefile for variables like this and include variables.mk or similar.



projects build: ;  mkdir -p $@


Why not split this into two lines? Also, the -p doesn't make any difference since it's only creating a single directory under the current one.



touch $@


This looks like a hack to get around checkout not updating the modified date properly, or to rebuild a project when make doesn't think it needs to be rebuilt. You might be able to just set the relevant target .PHONY or change it so that rebuilding is only done when necessary.



cd projects/$* &amp;&amp; git clean -xfd &amp;&amp; git reset --hard


This is rather brutal. I'd rather advise to use non-recursive make (based on  Recursive Make Considered Harmful) and enumerate the files to remove to make sure you never remove anything other than generated files. You could have a separate target with cd projects/$* &amp;&amp; git clean -xnd to check whether there's anything you still need to clean.



clobber-%:
  cd projects &amp;&amp; rm -rf $*


This also looks dangerous. You're effectively saying that make clobber-whatever will delete whatever no matter what it is. I can't recall where I heard this advice, but I do believe it's good practice to enumerate the files which makefiles can and should work with, rather than adding general-purpose tactical nuclear missiles.



define testgen =
...
$(foreach var,$(testgen.types),$(eval $(call testgen,$(var))))


There's a lot of indirection going on here, so it's difficult to understand what will actually be run in the end. Are you sure this couldn't be done simpler?



This is a personal preference, but I tend to avoid any echo statements because the make output should make it clear what is actually happening, and comments like this often tend to get out of sync with the rest of the code. On the other hand, you can include special targets to get the value of all/any variables.