patternjavagitMinor
Coverage processing on multiple Java projects with gmake
Viewed 0 times
projectswithgmakejavamultipleprocessingcoverage
Problem
As part of my data collection, I have to run multiple kinds of coverage processing on multiple Java projects. Below is my main
Some clarification about the intended purpose of this project. I am doing an analysis on a large number of projects from github. My method of action is to clone each project, run multiple tests on them. Before running any project, I do a git clean to make sure that the artifacts of previous tests are not present in the project directories. The
Makefile intented only for gmake. Portability is not a requirement for me (for this project), but DRY and following make best practices are. Please comment on my code, and if there is any way to make this better..PHONY: checkout all clobber clean $(checkout.all)
.SECONDARY: $(addprefix projects/,$(names))
root:=$(CURDIR)
names=$(shell cat etc/projects.txt)
checkout.all=$(addprefix checkout-,$(names))
clean.all=$(addprefix clean-,$(names))
testgen.types=original randoop tpalus
all:
@echo use 'make -'
@echo projects = $(names)
@echo types = $(testgen.types)
checkout: $(checkout.all)
@echo $@ done.
checkout-%: projects/%/pom.xml
@echo $@ done.
projects build: ; mkdir -p $@
projects/%/pom.xml: | projects build
cd projects && $(root)/bin/checkout $*
touch $@
clean: $(clean.all)
@echo $@ done.
clean-%: | projects/%/pom.xml
cd projects/$* && git clean -xfd && git reset --hard
@echo $@ done.
clobber-%:
cd projects && rm -rf $*
#-----------------------------------------------------------------
root:=$(CURDIR)
define testgen =
$1 : $(addprefix $(1)-,$(names))
@echo $(@) done.
$1-% : projects/%/.$(1).done
@echo $(@) done.
%/.$1.done : | %/pom.xml
echo $(MAKE) -C $(*) root=$(root) $(1)
endef
$(foreach var,$(testgen.types),$(eval $(call testgen,$(var))))Some clarification about the intended purpose of this project. I am doing an analysis on a large number of projects from github. My method of action is to clone each project, run multiple tests on them. Before running any project, I do a git clean to make sure that the artifacts of previous tests are not present in the project directories. The
types of tests and projects names vary frequently, and hence I have kept them outside the main Makefile.Solution
.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/$* && git clean -xfd && git reset --hardThis 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/$* && git clean -xnd to check whether there's anything you still need to clean.clobber-%:
cd projects && 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.Code Snippets
.PHONY: checkout all clobber clean $(checkout.all)names=$(shell cat etc/projects.txt)projects build: ; mkdir -p $@cd projects/$* && git clean -xfd && git reset --hardclobber-%:
cd projects && rm -rf $*Context
StackExchange Code Review Q#23246, answer score: 5
Revisions (0)
No revisions yet.