[Rd] how to add a target to the Make that R CMD check uses for running tests?

Tony Plate tplate at acm.org
Thu Apr 9 18:18:37 CEST 2009

I'd like to have some additional 'make' targets for tests that are run in <pkg>/tests by "R CMD check" (to do things like run tests with different pre-processing and post-processing, generate test summaries, etc.)

Is there a good way to do this?  At the moment I make 'make' jump through hoops, and it works, but I'd like to find a better way.

A method I used initially was to change the default goal by assigning .DEFAULT_GOAL in tests/Makefile.  This works nicely with GNU make version 3.81, which is standard in Ubuntu Linux.  However, the Rtools set of programs for Windows (as of R 2.6.2) includes GNU make version 3.79, which does not appear to recognize .DEFAULT_GOAL.  Additionally, version 2.6.2 (2008-02-08) of "R Installation and Administration" specifically says that GNU make version 3.81 does not work to compile R under Windows. Furthermore, Mac OS X version 10.4 (Tiger) includes GNU make version 3.80, which also does not appear to recognize the .DEFAULT_GOAL special variable.  So, that method appears to not be portable (though things might have changed since I last investigated a year ago.)

After searching around and various experiments, I came up with the following ugly hack where I include the following code in tests/Makefile:

# Use 'force targets' to effectively create another target, by calling
# make recursively with the target 'all-Rt'.  See here for 'force targets':
# http://www.gnu.org/software/automake/manual/make/Force-Targets.html
# Based on code at
# http://www.gnu.org/software/automake/manual/make/Overriding-Makefiles.html
# but with more levels of protection to avoid calling make with
# the target 'all-Rt' more than once, because this makefile is
# read many times.  Condition on DONEFORCE being not defined
# to avoid infinite recursion.
ifeq ($(strip $(DONEFORCE)),)
%: force
	@(if [ ! -f forceonce ] ; then \
	$(MAKE) -f $(R_SHARE_DIR)/make/$(RSHAREMAKEFILE) $(makevars) -f $(MAINTESTMAKE) DONEFORCE=TRUE all-Rt ; \
	fi )
	@touch forceonce

force: ;

This code causes 'make' to be called just once with the target 'all-Rt', using appropriate settings for RSHAREMAKEFILE (either 'tests.mk' or 'wintests.mk') and MAINTESTMAKE (either 'Makefile' or 'Makefile.win') (There are set in other parts of the Makefile).

The above code runs as intended under Linux, Windows, and Mac OS X, at least on the installations I've tested.

However this technique is ugly.  There must be a better way.  Any suggestions? (I guess I could probably get rid of the 'forceonce' protection pretty easily, but the $(DONEFORCE) protection seems harder to get rid of, and I'd like to think there must be an easier way of adding a target anyway.)

-- Tony Plate

More information about the R-devel mailing list