diff --git a/.gitignore b/.gitignore
index b674588e27e55b7c7690d835b67f04c65df94d1f..1f770b886f2475de2769dbe22e778ff3f47781bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,9 +24,10 @@
 /com.oracle.truffle.r.native/include/*.h
 /com.oracle.truffle.r.native/include/R_ext/*.h
 /com.oracle.truffle.r.native/include/linked
-/com.oracle.truffle.r.test.native/packages/*/lib/*
+/com.oracle.truffle.r.test.native/packages/copy_recommended
 /com.oracle.truffle.r.test/rpackages/testrlibs_user
 /com.oracle.truffle.r.test.native/urand/lib/liburand.so
+/tmptest/
 /com.oracle.truffle.r.release/lib/
 /com.oracle.truffle.r.release/library/
 /DEPARSE_ERROR
diff --git a/com.oracle.truffle.r.test.native/Makefile b/com.oracle.truffle.r.test.native/Makefile
index 37c62d9a92a3bb060854303ab453afc9647cdf88..d996da3e45a82598ff2e6d117305549b4308e679 100644
--- a/com.oracle.truffle.r.test.native/Makefile
+++ b/com.oracle.truffle.r.test.native/Makefile
@@ -24,6 +24,8 @@
 .PHONY: all clean
 
 export TOPDIR = $(CURDIR)
+# all output goes into the com.oracle.truffle.r.test project for packaging into a single distribution
+export MX_OUTPUT_DIR = $(abspath $(TOPDIR)/../mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test)
 OSNAME := $(shell uname)
 
 all:
diff --git a/com.oracle.truffle.r.test.native/packages/Makefile b/com.oracle.truffle.r.test.native/packages/Makefile
index 7b14f9a4fb9e5f580b46fa3938a0d3d051343979..0d7198f4e6166dcff57aaac31a7d6e274b82865e 100644
--- a/com.oracle.truffle.r.test.native/packages/Makefile
+++ b/com.oracle.truffle.r.test.native/packages/Makefile
@@ -21,21 +21,38 @@
 # questions.
 #
 
-.PHONY: all clean make_subdirs clean_subdirs
+.PHONY: all clean make_subdirs clean_subdirs clean_recommended
 
-SUBDIRS = testrffi vanilla
+SUBDIRS = testrffi vanilla tests4
+NATIVE_PROJECT = $(subst test.native,native,$(TOPDIR))
+R_VERSION := $(notdir $(wildcard $(NATIVE_PROJECT)/gnur/R-*))
+GNUR_HOME := $(NATIVE_PROJECT)/gnur/$(R_VERSION)
+GNUR_RECOMMENDED := $(wildcard $(GNUR_HOME)/src/library/Recommended/*.tgz)
 
-all: make_subdirs
+all: make_subdirs copy_recommended
 
 make_subdirs:
 	for dir in $(SUBDIRS); do \
 		$(MAKE) PACKAGE=$$dir -C $$dir || exit 1; \
 	done
 
-clean: clean_subdirs
+copy_recommended:
+	cp $(GNUR_RECOMMENDED) $(MX_OUTPUT_DIR)/packages
+	touch copy_recommended
+
+clean: clean_subdirs clean_recommended
 
 clean_subdirs:
 	for dir in $(SUBDIRS); do \
 		$(MAKE) PACKAGE=$$dir -C $$dir clean || exit 1; \
 	done
-	
+
+clean_recommended:
+	for f in $(notdir $(GNUR_RECOMMENDED)); do \
+		rm -f $(MX_OUTPUT_DIR)/packages/$$f; \
+	done
+	rm -f copy_recommended
+
+
+
+	
\ No newline at end of file
diff --git a/com.oracle.truffle.r.test.native/packages/package.mk b/com.oracle.truffle.r.test.native/packages/package.mk
index 27379351e2103080b21be98a43d4da93ed2d54fc..7e2419698919aafd2bcca3202873cd37b32171cd 100644
--- a/com.oracle.truffle.r.test.native/packages/package.mk
+++ b/com.oracle.truffle.r.test.native/packages/package.mk
@@ -23,17 +23,19 @@
 
 # This "builds" a test package, resulting in a tar file,
 # which is then loaded by the unit tests in TestRPackages.
+# To facilitate location relative to the mx "output" directory
+# of this project, the tar file is created in that location
 
 .PHONY: all
 
 PKG_FILES = $(shell find $(PACKAGE)/ -type f -name '*')
 
-PKG_TAR = lib/$(PACKAGE).tar
+PKG_TAR = $(MX_OUTPUT_DIR)/packages/$(PACKAGE).tar
 
 all: $(PKG_TAR)
 
 $(PKG_TAR): $(PKG_FILES)
-	mkdir -p lib
+	mkdir -p $(MX_OUTPUT_DIR)/packages
 	tar cf $(PKG_TAR) $(PACKAGE)
 
 clean:
diff --git a/com.oracle.truffle.r.test.native/packages/tests4/lib/tests4.tar b/com.oracle.truffle.r.test.native/packages/tests4/lib/tests4.tar
deleted file mode 100644
index 914271602ff2cbf7c620962cffc565d300fc4d8b..0000000000000000000000000000000000000000
Binary files a/com.oracle.truffle.r.test.native/packages/tests4/lib/tests4.tar and /dev/null differ
diff --git a/com.oracle.truffle.r.test.native/urand/Makefile b/com.oracle.truffle.r.test.native/urand/Makefile
index c6cd2ef26ca74924c02dab4eaff90dd0fa6d6c93..4519d34abf19a342121daf7ed7673d170db1d509 100644
--- a/com.oracle.truffle.r.test.native/urand/Makefile
+++ b/com.oracle.truffle.r.test.native/urand/Makefile
@@ -33,7 +33,7 @@ endif
 
 .PHONY: all clean
 
-OBJ = lib
+OBJ = $(MX_OUTPUT_DIR)/urand
 SRC = src
 C_SOURCES := $(wildcard $(SRC)/*.c)
 # Since this library is loaded explicitly we keep a consistent
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index e185832122485adabd8797a831ef1d48c34afe26..dcf0ea8a9bd8449ab531661607b7bc83540c0908 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -1,5 +1,5 @@
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation1.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation1.R") }
 An object of class "Person"
 Slot "name":
 [1] "Hadley"
@@ -9,44 +9,44 @@ Slot "age":
 
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation10.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation10.R") }
 Error in validObject(hadley) :
   invalid class “Person” object: Age is length 10.  Should be 1
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation2.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation2.R") }
 Error in validObject(.Object) :
   invalid class “Person” object: invalid object for slot "age" in class "Person": got class "character", should be or extend class "numeric"
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation3.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation3.R") }
 Error in initialize(value, ...) :
   invalid name for slot of class “Person”: sex
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation4.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation4.R") }
 numeric(0)
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation5.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation5.R") }
 numeric(0)
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation6.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation6.R") }
 [1] NA
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation7.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation7.R") }
 Error in validObject(.Object) :
   invalid class “Person” object: Age is length 0.  Should be 1
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation8.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation8.R") }
 Error in validObject(.Object) :
   invalid class “Person” object: Age is length 10.  Should be 1
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/allocation9.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/allocation9.R") }
 An object of class "Person"
 Slot "name":
 [1] "Hadley"
@@ -56,7 +56,7 @@ Slot "age":
 
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/methods1.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/methods1.R") }
 Function: sides (package .GlobalEnv)
 object="Polygon"
 object="Square"
@@ -72,7 +72,7 @@ description       class        mode        text      opened    can read
       "yes"
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/methods2.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/methods2.R") }
 Function: sides (package .GlobalEnv)
 object="Polygon"
 
@@ -86,12 +86,12 @@ description       class        mode        text      opened    can read
       "yes"
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/methods3.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/methods3.R") }
 Error in .valueClassTest(ans, "numeric", "sides") :
   invalid value from generic function ‘sides’, class “character”, expected “numeric”
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/methods4.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/methods4.R") }
 Note: method with signature ‘A2#A1’ chosen for function ‘foo’,
  target signature ‘A2#A2’.
  "A1#A2" would also be valid
@@ -99,13 +99,13 @@ Note: method with signature ‘A2#A1’ chosen for function ‘foo’,
 [1] "2-1"
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/methods5.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/methods5.R") }
 [1] "Looking for rust"
 character(0)
 [1] "Checking seat belts"
 
 ##com.oracle.truffle.r.test.S4.TestS4.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/R/slot_access1.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/S4/R/slot_access1.R") }
        name         age
 "character"   "numeric"
 
@@ -56604,7 +56604,7 @@ Error in foo(1, 2, 3) : unused arguments (2, 3)
 [1] TRUE
 
 ##com.oracle.truffle.r.test.functions.TestS3Dispatch.runRSourceTests
-#{ source("com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/S3/R/argMatching.R") }
+#{ source("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/functions/S3/R/argMatching.R") }
 dispatch
 g.c args:
 [[1]]
@@ -56890,32 +56890,32 @@ Error in tryCatchList(expr, classes, parentenv, handlers) : fred
 [1] "Hello"
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadBin
-#{ readBin(file("com.oracle.truffle.r.test/library.base.conn/wb1", "rb"), 3) }
+#{ readBin(file("tmptest/com.oracle.truffle.r.test.library.base.conn/wb1", "rb"), 3) }
 numeric(0)
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadBin
-#{ writeBin("abc", file("com.oracle.truffle.r.test/library.base.conn/wb1", open="wb")) }
+#{ writeBin("abc", file("tmptest/com.oracle.truffle.r.test.library.base.conn/wb1", open="wb")) }
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadChar
-#{ readChar(file("com.oracle.truffle.r.test/library.base.conn/wc1"), 3) }
+#{ readChar(file("tmptest/com.oracle.truffle.r.test.library.base.conn/wc1"), 3) }
 [1] "abc"
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadChar
-#{ writeChar("abc", file("com.oracle.truffle.r.test/library.base.conn/wc1")) }
+#{ writeChar("abc", file("tmptest/com.oracle.truffle.r.test.library.base.conn/wc1")) }
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadLines
-#{ con <- file("com.oracle.truffle.r.test/library.base.conn/wl2"); readLines(con, 2) }
+#{ con <- file("tmptest/com.oracle.truffle.r.test.library.base.conn/wl2"); readLines(con, 2) }
 [1] "line1" "line2"
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadLines
-#{ con <- file("com.oracle.truffle.r.test/library.base.conn/wl2"); writeLines(c("line1", "line2"), con) }
+#{ con <- file("tmptest/com.oracle.truffle.r.test.library.base.conn/wl2"); writeLines(c("line1", "line2"), con) }
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadLines
-#{ readLines(file("com.oracle.truffle.r.test/library.base.conn/wl1"), 2) }
+#{ readLines(file("tmptest/com.oracle.truffle.r.test.library.base.conn/wl1"), 2) }
 [1] "line1" "line2"
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testFileWriteReadLines
-#{ writeLines(c("line1", "line2"), file("com.oracle.truffle.r.test/library.base.conn/wl1")) }
+#{ writeLines(c("line1", "line2"), file("tmptest/com.oracle.truffle.r.test.library.base.conn/wl1")) }
 
 ##com.oracle.truffle.r.test.library.base.TestConnections.testPushBackTextConnection
 #{ con<-textConnection(c("a","b","c","d")); pushBack("G", con); clearPushBack(con); pushBackLength(con) }
@@ -111769,13 +111769,13 @@ Error: unexpected '*' in:
 [1] TRUE
 
 ##com.oracle.truffle.r.test.rffi.TestUserRNG.testUserRNG
-#{ dyn.load("com.oracle.truffle.r.test.native/urand/lib/liburand.so"); RNGkind("user"); print(RNGkind()); set.seed(4567); runif(10) }
+#{ dyn.load("mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test/urand/liburand.so"); RNGkind("user"); print(RNGkind()); set.seed(4567); runif(10) }
 [1] "user-supplied" "Inversion"
  [1] 0.45336386 0.38848030 0.94576608 0.11726267 0.21542351 0.08672997
  [7] 0.35201276 0.16919220 0.93579263 0.26084486
 
 ##com.oracle.truffle.r.test.rpackages.TestRFFIPackage.testLoadTestRFFIDotC
-#{ library("testrffi", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r1 <- rffi.dotCModifiedArguments(c(0,1,2,3)); r1 }
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r1 <- rffi.dotCModifiedArguments(c(0,1,2,3)); r1 }
 [[1]]
 [1] 4
 
@@ -111790,7 +111790,7 @@ Error: unexpected '*' in:
 
 
 ##com.oracle.truffle.r.test.rpackages.TestRFFIPackage.testLoadTestRFFIExternal
-#{ library("testrffi", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r1 <- rffi.dotExternalAccessArgs(1L, 3, c(1,2,3), c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi"); r1 }
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r1 <- rffi.dotExternalAccessArgs(1L, 3, c(1,2,3), c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi"); r1 }
 [[1]]
 [[1]][[1]]
 NULL
@@ -111849,7 +111849,7 @@ NULL
 
 
 ##com.oracle.truffle.r.test.rpackages.TestRFFIPackage.testLoadTestRFFIExternalWithNames
-#{ library("testrffi", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r1 <- rffi.dotExternalAccessArgs(x=1L, 3, c(1,2,3), y=c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi"); r1 }
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r1 <- rffi.dotExternalAccessArgs(x=1L, 3, c(1,2,3), y=c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi"); r1 }
 [[1]]
 [[1]][[1]]
 x
@@ -111908,11 +111908,11 @@ NULL
 
 
 ##com.oracle.truffle.r.test.rpackages.TestRFFIPackage.testLoadTestRFFIManyArgs
-#{ library("testrffi", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r1 <- rffi.invoke12(); detach("package:testrffi"); r1 }
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r1 <- rffi.invoke12(); detach("package:testrffi"); r1 }
 [1] 12
 
 ##com.oracle.truffle.r.test.rpackages.TestRFFIPackage.testLoadTestRFFISimple
-#{ library("testrffi", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); c3 <- c(1L,2L,3L); r1 <- rffi.iterate_iarray(c3); r2 <- rffi.iterate_iptr(c3); detach("package:testrffi"); list(r1, r2) }
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); c3 <- c(1L,2L,3L); r1 <- rffi.iterate_iarray(c3); r2 <- rffi.iterate_iptr(c3); detach("package:testrffi"); list(r1, r2) }
 [[1]]
 [1] 1 2 3
 
@@ -111921,7 +111921,7 @@ NULL
 
 
 ##com.oracle.truffle.r.test.rpackages.TestRFFIPackage.testLoadTestRFFISimple
-#{ library("testrffi", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r1 <- rffi.addInt(2L, 3L); r2 <- rffi.addDouble(2, 3); r3 <- rffi.populateIntVector(5); r4 <- rffi.populateLogicalVector(5); detach("package:testrffi"); list(r1, r2, r3, r4) }
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r1 <- rffi.addInt(2L, 3L); r2 <- rffi.addDouble(2, 3); r3 <- rffi.populateIntVector(5); r4 <- rffi.populateLogicalVector(5); detach("package:testrffi"); list(r1, r2, r3, r4) }
 [[1]]
 [1] 5
 
@@ -111936,7 +111936,7 @@ NULL
 
 
 ##com.oracle.truffle.r.test.rpackages.TestRFFIPackage.testLoadTestRFFISimple
-#{ library("testrffi", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r1 <- rffi.mkStringFromChar(); r2 <- rffi.mkStringFromBytes(); r3 <- rffi.null(); r4 <-rffi.isRString(character(0)); detach("package:testrffi"); list(r1, r2, r3, r4) }
+#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r1 <- rffi.mkStringFromChar(); r2 <- rffi.mkStringFromBytes(); r3 <- rffi.null(); r4 <-rffi.isRString(character(0)); detach("package:testrffi"); list(r1, r2, r3, r4) }
 [[1]]
 [1] "hello"
 
@@ -111951,58 +111951,58 @@ NULL
 
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(KernSmooth, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:KernSmooth"); }
+#{ library(KernSmooth, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:KernSmooth"); }
 KernSmooth 2.23 loaded
 Copyright M. P. Wand 1997-2009
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(MASS, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:MASS"); }
+#{ library(MASS, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:MASS"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(Matrix, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:Matrix"); }
+#{ library(Matrix, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:Matrix"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(boot, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:boot"); }
+#{ library(boot, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:boot"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(class, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:class"); }
+#{ library(class, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:class"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(cluster, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:cluster"); }
+#{ library(cluster, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:cluster"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(codetools, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:codetools"); }
+#{ library(codetools, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:codetools"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(foreign, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:foreign"); }
+#{ library(foreign, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:foreign"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(lattice, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:lattice"); }
+#{ library(lattice, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:lattice"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(nlme, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:nlme"); }
+#{ library(nlme, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:nlme"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(nnet, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:nnet"); }
+#{ library(nnet, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:nnet"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(rpart, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:rpart"); }
+#{ library(rpart, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:rpart"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(spatial, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:spatial"); }
+#{ library(spatial, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:spatial"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestRecommendedPackages.testLoad
-#{ library(survival, lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:survival"); }
+#{ library(survival, lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:survival"); }
 
 ##com.oracle.truffle.r.test.rpackages.TestS4TestPackage.testS4Execute
-#{ library("tests4", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r<-print(tests4:::inspect.vehicle(new("Car"), new("Inspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
+#{ library("tests4", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r<-print(tests4:::inspect.vehicle(new("Car"), new("Inspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
 Looking for rust
 Checking seat belts
 NULL
 NULL
 
 ##com.oracle.truffle.r.test.rpackages.TestS4TestPackage.testS4Execute
-#{ library("tests4", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r<-print(tests4:::inspect.vehicle(new("Car"), new("StateInspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
+#{ library("tests4", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r<-print(tests4:::inspect.vehicle(new("Car"), new("StateInspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
 Looking for rust
 Checking seat belts
 Checking insurance
@@ -112010,32 +112010,32 @@ NULL
 NULL
 
 ##com.oracle.truffle.r.test.rpackages.TestS4TestPackage.testS4Execute
-#{ library("tests4", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r<-print(tests4:::inspect.vehicle(new("Truck"), new("Inspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
+#{ library("tests4", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r<-print(tests4:::inspect.vehicle(new("Truck"), new("Inspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
 Looking for rust
 Checking cargo attachments
 NULL
 NULL
 
 ##com.oracle.truffle.r.test.rpackages.TestS4TestPackage.testS4Execute
-#{ library("tests4", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r<-print(tests4:::inspect.vehicle(new("Truck"), new("StateInspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
+#{ library("tests4", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r<-print(tests4:::inspect.vehicle(new("Truck"), new("StateInspector"))); detach("package:tests4"); unloadNamespace("tests4"); r }
 Looking for rust
 Checking cargo attachments
 NULL
 NULL
 
 ##com.oracle.truffle.r.test.rpackages.TestS4TestPackage.testS4Load
-#{ library("tests4", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); detach("package:tests4"); unloadNamespace("tests4") }
+#{ library("tests4", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); detach("package:tests4"); unloadNamespace("tests4") }
 
 ##com.oracle.truffle.r.test.rpackages.TestVanillaPackage.testLoadVanilla
-#{ library("vanilla", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r <- vanilla(); detach("package:vanilla"); r }
+#{ library("vanilla", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r <- vanilla(); detach("package:vanilla"); r }
 [1] "A vanilla R package"
 [1] "A vanilla R package"
 
 ##com.oracle.truffle.r.test.rpackages.TestVanillaPackage.testQualifiedReplacement
-#{ library("vanilla", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r<-42; vanilla::foo(r)<-7; detach("package:vanilla"); r }
+#{ library("vanilla", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r<-42; vanilla::foo(r)<-7; detach("package:vanilla"); r }
 [1] 7
 
 ##com.oracle.truffle.r.test.rpackages.TestVanillaPackage.testSimpleFunction
-#{ library("vanilla", lib.loc = "com.oracle.truffle.r.test/rpackages/testrlibs_user"); r <- functionTest(c(1,2,3,4,5,6),8:10); detach("package:vanilla"); r }
+#{ library("vanilla", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); r <- functionTest(c(1,2,3,4,5,6),8:10); detach("package:vanilla"); r }
 [1]  2  3  4  5  6  7  8  9 10
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
index 0ef85e3daf33d49f8864955d7cec01fff4c301fa..db059857d111a57d1d97c709fca740139e5461fa 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java
@@ -128,8 +128,12 @@ public class TestBase {
         private static final String EXPECTED = "expected=";
         private static final String GEN_FASTR = "gen-fastr=";
         private static final String GEN_DIFFS = "gen-diff=";
-        private static final String KEEP_TRAILING_WHITESPACEG = "keep-trailing-whitespace";
+        private static final String KEEP_TRAILING_WHITESPACE = "keep-trailing-whitespace";
         private static final String TEST_METHODS = "test-methods=";
+        /**
+         * The dir where 'mx' puts the output from building this project.
+         */
+        private static final String TEST_PROJECT_OUTPUT_DIR = "test-project-output-dir=";
 
         private final String arg;
 
@@ -163,8 +167,10 @@ public class TestBase {
                             genExpectedQuiet = true;
                         } else if (directive.equals(CHECK_EXPECTED)) {
                             checkExpected = true;
-                        } else if (directive.equals(KEEP_TRAILING_WHITESPACEG)) {
+                        } else if (directive.equals(KEEP_TRAILING_WHITESPACE)) {
                             keepTrailingWhiteSpace = true;
+                        } else if (directive.startsWith(TEST_PROJECT_OUTPUT_DIR)) {
+                            testProjectOutputDir = Paths.get(directive.replace(TEST_PROJECT_OUTPUT_DIR, ""));
                         } else if (directive.equals(TEST_METHODS)) {
                             testMethodsPattern = directive.replace(TEST_METHODS, "");
                         } else {
@@ -348,6 +354,8 @@ public class TestBase {
      */
     private static boolean keepTrailingWhiteSpace;
 
+    private static Path testProjectOutputDir;
+
     protected static final String ERROR = "Error";
     protected static final String WARNING = "Warning message";
 
@@ -419,14 +427,50 @@ public class TestBase {
 
     private static Path cwd;
 
+    private static Path getCwd() {
+        if (cwd == null) {
+            cwd = Paths.get(System.getProperty("user.dir"));
+        }
+        return cwd;
+    }
+
+    public static void setTestProjectOutputDir(String path) {
+        testProjectOutputDir = Paths.get(path);
+    }
+
+    private static final String TEST_OUTPUT = "tmptest";
+
     /**
-     * Return a path that is relative to the cwd when running tests.
+     * Return a path that is relative to the 'cwd/testoutput' when running tests.
      */
     public static Path relativize(Path path) {
-        if (cwd == null) {
-            cwd = Paths.get(System.getProperty("user.dir"));
+        return getCwd().relativize(path);
+    }
+
+    /**
+     * Creates a directory with suffix {@code name} in the {@code testoutput} directory and returns
+     * a relative path to it.
+     */
+    public static Path createTestDir(String name) {
+        Path dir = Paths.get(getCwd().toString(), TEST_OUTPUT, name);
+        if (!dir.toFile().exists()) {
+            if (!dir.toFile().mkdirs()) {
+                throw new AssertionError();
+            }
         }
-        return cwd.relativize(path);
+        return relativize(dir);
+    }
+
+    private static final String TEST_PROJECT = "com.oracle.truffle.r.test";
+
+    /**
+     * Returns a path to {@code baseName}, assumed to be nested in {@link #testProjectOutputDir}.
+     * The path is return relativized to the cwd.
+     */
+    public static Path getProjectFile(Path baseName) {
+        Path baseNamePath = Paths.get(TEST_PROJECT.replace('.', '/'), baseName.toString());
+        Path result = relativize(testProjectOutputDir.resolve(baseNamePath));
+        return result;
     }
 
     private static void microTestFailed() {
@@ -444,18 +488,25 @@ public class TestBase {
         if (explicitTestContext != null) {
             return explicitTestContext;
         }
-        // We want the stack trace as if the JUnit test failed
+        // We want the stack trace as if the JUnit test failed.
         RuntimeException ex = new RuntimeException();
         // The first method not in TestBase is the culprit
         StackTraceElement culprit = null;
-        for (StackTraceElement se : ex.getStackTrace()) {
-            if (!se.getClassName().endsWith("TestBase")) {
-                culprit = se;
-                break;
+        try {
+            // N.B. This may not always be available (AOT).
+            StackTraceElement[] stackTrace = ex.getStackTrace();
+            for (int i = 0; i < stackTrace.length; i++) {
+                StackTraceElement se = stackTrace[i];
+                if (!se.getClassName().endsWith("TestBase")) {
+                    culprit = se;
+                    break;
+                }
             }
+            String context = String.format("%s:%d (%s)", culprit.getClassName(), culprit.getLineNumber(), culprit.getMethodName());
+            return context;
+        } catch (NullPointerException npe) {
+            return "no context available";
         }
-        String context = String.format("%s:%d (%s)", culprit.getClassName(), culprit.getLineNumber(), culprit.getMethodName());
-        return context;
     }
 
     private void evalAndCompare(String[] inputs, TestTrait... traits) {
@@ -740,6 +791,7 @@ public class TestBase {
             // unit test mode
             String expected = expectedOutputManager.getOutput(input);
             if (expected == null) {
+                System.out.println("lookup failed");
                 // get the expected output dynamically (but do not update the file)
                 expectedOutputManager.createRSession();
                 expected = genTestResult(input);
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestRBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestRBase.java
index bb429d6d972b0c9271939389be68c0cfc1f28298..c3e3ee014015f9dca26c83386d2265b0c686bd61 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestRBase.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestRBase.java
@@ -33,22 +33,18 @@ import java.nio.file.Paths;
 import org.junit.Assert;
 import org.junit.Test;
 
-import com.oracle.truffle.r.runtime.REnvVars;
-
-/*
- *  Base class for all Java test suites (in the sense of JUnit Java files)
- *  that want to run R tests stored in the file system as R sources.
- *  It is expected that R test source files will be stored in the R sub-directory
- *  of a directory stored in com.oracle.truffle.r.test/src/com/oracle/truffle/r/test
+/**
+ * Base class for all Java test suites (in the sense of JUnit Java files) that want to run R tests
+ * stored in the file system as R sources. It is expected that R test source files will be stored in
+ * the R sub-directory of the {@code com.oracle.truffle.r.test} project.
  *
- *  The first line of the file may contain some configuration information (as an R comment).
- *  At this point, two keywords are recognized - ContainsError and ContansWarning. Including
- *  any of them on in the first line will cause appropriate execution method to be chosen
- *  (if both are present then ContainsError has precedence).
+ * The first line of the file may contain some configuration information (as an R comment). At this
+ * point, two keywords are recognized - ContainsError and ContansWarning. Including any of them on
+ * in the first line will cause appropriate execution method to be chosen (if both are present then
+ * ContainsError has precedence).
  *
- *  The R files are sourced, so any test results have to be explicitly printed.
+ * The R files are sourced, so any test results have to be explicitly printed.
  */
-
 public class TestRBase extends TestBase {
 
     /*
@@ -64,7 +60,7 @@ public class TestRBase extends TestBase {
         if (testDirName == null) {
             return;
         }
-        Path testDirPath = Paths.get(REnvVars.rHome(), "com.oracle.truffle.r.test", "src", "com", "oracle", "truffle", "r", "test", testDirName, "R");
+        Path testDirPath = TestBase.getProjectFile(Paths.get(testDirName, "R"));
         if (!Files.exists(testDirPath) || !Files.isDirectory(testDirPath)) {
             return;
         }
@@ -91,7 +87,7 @@ public class TestRBase extends TestBase {
                     }
                 }
                 bf.close();
-                String testFilePath = TestBase.relativize(testDirPath.resolve(files[i].getName())).toString();
+                String testFilePath = testDirPath.resolve(files[i].getName()).toString();
                 if (testTrait == null) {
                     assertEval(TestBase.template("{ source(\"%0\") }", new String[]{testFilePath}));
                 } else {
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java
index 6a7c81b9e40036a03dbe67653413d32b6151409a..44d7c993ac79f7d9a55a043d9ebb02831a218789 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java
@@ -23,13 +23,10 @@
 package com.oracle.truffle.r.test.library.base;
 
 import java.nio.file.Path;
-import java.nio.file.Paths;
-
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import com.oracle.truffle.r.runtime.REnvVars;
 import com.oracle.truffle.r.test.TestBase;
 
 public class TestConnections extends TestBase {
@@ -37,11 +34,7 @@ public class TestConnections extends TestBase {
         private final Path testDirPath;
 
         TestDir() {
-            Path rpackages = Paths.get(REnvVars.rHome(), "com.oracle.truffle.r.test");
-            testDirPath = TestBase.relativize(rpackages.resolve("library.base.conn"));
-            if (!testDirPath.toFile().exists()) {
-                testDirPath.toFile().mkdir();
-            }
+            testDirPath = TestBase.createTestDir("com.oracle.truffle.r.test.library.base.conn");
         }
 
         String[] subDir(String p) {
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestUserRNG.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestUserRNG.java
index 9714a5f6b110de1242259ca185d3e5eaf80ae94b..69478306f2cc8f90512767bcbc6d94814db2472d 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestUserRNG.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestUserRNG.java
@@ -27,7 +27,6 @@ import java.nio.file.Paths;
 
 import org.junit.Test;
 
-import com.oracle.truffle.r.runtime.REnvVars;
 import com.oracle.truffle.r.runtime.ffi.UserRngRFFI;
 import com.oracle.truffle.r.test.TestBase;
 
@@ -39,9 +38,7 @@ import com.oracle.truffle.r.test.TestBase;
 public class TestUserRNG extends TestBase {
     @Test
     public void testUserRNG() {
-        Path cwd = Paths.get(System.getProperty("user.dir"));
-        Path libPath = Paths.get(REnvVars.rHome(), "com.oracle.truffle.r.test.native/urand/lib/liburand.so");
-        Path relLibPath = cwd.relativize(libPath);
-        assertEval(TestBase.template("{ dyn.load(\"%0\"); RNGkind(\"user\"); print(RNGkind()); set.seed(4567); runif(10) }", new String[]{relLibPath.toString()}));
+        Path libPath = TestBase.getProjectFile(Paths.get("urand", "liburand.so"));
+        assertEval(TestBase.template("{ dyn.load(\"%0\"); RNGkind(\"user\"); print(RNGkind()); set.seed(4567); runif(10) }", new String[]{libPath.toString()}));
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java
index 5469875ee7b6f7771da19fc64c1106d9ca86e171..c3cf409168134d839ab1496851d83d4038a118bb 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRPackages.java
@@ -137,7 +137,7 @@ public abstract class TestRPackages extends TestBase {
 
     private static Path installDir() {
         if (installDir == null) {
-            installDir = TestBase.relativize(Paths.get(REnvVars.rHome(), "com.oracle.truffle.r.test", "rpackages", "testrlibs_user"));
+            installDir = TestBase.createTestDir("com.oracle.truffle.r.test.rpackages");
         }
         return installDir;
     }
@@ -162,12 +162,13 @@ public abstract class TestRPackages extends TestBase {
      */
     protected static class Resolver {
         Path getPath(String p) {
-            return testNativePath().resolve(p).resolve("lib").resolve(p + ".tar");
+            return testNativePath().resolve(p + ".tar");
         }
     }
 
     private static Path testNativePath() {
-        return Paths.get(REnvVars.rHome(), "com.oracle.truffle.r.test.native", "packages");
+        Path p = TestBase.getProjectFile(Paths.get("packages"));
+        return p;
     }
 
     private static PackagePaths getPackagePaths(String pkg, Path path) {
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRecommendedPackages.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRecommendedPackages.java
index a08a9b4baa782de96a497b3cc6c839c520041e58..60867da35540fa40476d156553fea020c5b1c806 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRecommendedPackages.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rpackages/TestRecommendedPackages.java
@@ -29,30 +29,28 @@ import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import com.oracle.truffle.r.runtime.REnvVars;
-import com.oracle.truffle.r.runtime.RVersionNumber;
 import com.oracle.truffle.r.test.TestBase;
 
 /**
  * Test the installation of the "recommended" packages that come with GnuR. N.B. There are no
  * specific tests beyond install/load as that is handled separately in the package testing
  * framework. We are primarily concerned with detecting installation regressions.
+ *
+ * N.B. The package 'tgz' files have been copied to the com.oracle.truffle.r.test project output
+ * directory by the com.oracle.truffle.r.test.native Makefile. to allow them to be packaged into a
+ * distribution and avoid any dependency on source paths.
  */
 public class TestRecommendedPackages extends TestRPackages {
     private static final String[] OK_PACKAGES = new String[]{"MASS", "boot", "class", "cluster", "codetools", "lattice", "nnet", "spatial", "survival", "KernSmooth", "Matrix", "foreign", "nlme",
                     "rpart"};
     @SuppressWarnings("unused") private static final String[] PROBLEM_PACKAGES = new String[]{};
 
-    private static Path getRecommendedPath() {
-        return Paths.get(REnvVars.rHome(), "com.oracle.truffle.r.native", "gnur", RVersionNumber.R_HYPHEN_FULL, "src", "library", "Recommended");
-    }
-
     @BeforeClass
     public static void setupInstallMyTestPackages() {
         setupInstallTestPackages(OK_PACKAGES, new Resolver() {
             @Override
             Path getPath(String p) {
-                return getRecommendedPath().resolve(p + ".tgz");
+                return TestBase.getProjectFile(Paths.get("packages")).resolve(p + ".tgz");
             }
         });
     }
diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py
index 8074ee6919bc30c0c2a6499bbdea0096ec2fde85..b2e9ba5d6d42e72e6ff5499f4991dc1210881a03 100644
--- a/mx.fastr/mx_fastr.py
+++ b/mx.fastr/mx_fastr.py
@@ -303,6 +303,9 @@ def _junit_r_harness(args, vmArgs, jdk, junitArgs):
 #        runlistener_arg = add_arg_separator()
 #        runlistener_arg = 'test-methods=' + args.test_methods
 
+    runlistener_arg = add_arg_separator()
+    runlistener_arg += 'test-project-output-dir=' + mx.project('com.oracle.truffle.r.test').output_dir()
+
     # use a custom junit.RunListener
     runlistener = 'com.oracle.truffle.r.test.TestBase$RunListener'
     if len(runlistener_arg) > 0:
@@ -409,10 +412,6 @@ def testgen(args):
         except subprocess.CalledProcessError:
             mx.abort('RVersionNumber.main failed')
 
-    # clean the test project to invoke the test analyzer AP
-    testOnly = ['--projects', 'com.oracle.truffle.r.test']
-    mx.clean(['--no-dist', ] + testOnly)
-    mx.build(testOnly)
     # now just invoke junit with the appropriate options
     mx.log("generating expected output for packages: ")
     for pkg in args.tests.split(','):