Skip to content

Commit a825e48

Browse files
committed
add cleanupCacheDir option to sourceCpp
1 parent 85fc4c2 commit a825e48

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

R/Attributes.R

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ sourceCpp <- function(file = "",
2424
embeddedR = TRUE,
2525
rebuild = FALSE,
2626
cacheDir = tempdir(),
27+
cleanupCacheDir = FALSE,
2728
showOutput = verbose,
2829
verbose = getOption("verbose"),
2930
dryRun = FALSE) {
@@ -32,8 +33,8 @@ sourceCpp <- function(file = "",
3233
# (since cached dynlibs can now perist across sessions we need to be
3334
# sure to invalidate them when R or Rcpp versions change)
3435
cacheDir <- path.expand(cacheDir)
35-
cacheDir <- normalizePath(cacheDir, winslash = "/", mustWork = FALSE)
3636
cacheDir <- .sourceCppPlatformCacheDir(cacheDir)
37+
cacheDir <- normalizePath(cacheDir)
3738

3839
# resolve code into a file if necessary. also track the working
3940
# directory to source the R embedded code chunk within
@@ -197,6 +198,10 @@ sourceCpp <- function(file = "",
197198
setwd(rWorkingDir) # will be reset by previous on.exit handler
198199
source(file=srcConn, echo=TRUE)
199200
}
201+
202+
# cleanup the cache dir if requested
203+
if (cleanupCacheDir)
204+
cleanupSourceCppCache(cacheDir, context$cppSourcePath, context$buildDirectory)
200205

201206
# return (invisibly) a list containing exported functions and modules
202207
invisible(list(functions = context$exportedFunctions,
@@ -205,6 +210,27 @@ sourceCpp <- function(file = "",
205210
buildDirectory = context$buildDirectory))
206211
}
207212

213+
214+
# Cleanup a directory used as the cache for a sourceCpp compilation. This will
215+
# remove all files from the cache directory that aren't a result of the
216+
# compilation that yielded the passed buildDirectory.
217+
cleanupSourceCppCache <- function(cacheDir, cppSourcePath, buildDirectory) {
218+
# normalize cpp source path and build directory
219+
cppSourcePath <- normalizePath(cppSourcePath)
220+
buildDirectory <- normalizePath(buildDirectory)
221+
222+
# determine the parent dir that was used for the compilation then collect all the
223+
# *.cpp files and subdirectories therein
224+
cacheFiles <- list.files(cacheDir, pattern = glob2rx("*.cpp"), recursive = FALSE, full.names = TRUE)
225+
cacheFiles <- c(cacheFiles, list.dirs(cacheDir, recursive = FALSE, full.names = TRUE))
226+
cacheFiles <- normalizePath(cacheFiles)
227+
228+
# determine the list of tiles that were not yielded by the passed sourceCpp
229+
# result and remove them
230+
oldCacheFiles <- cacheFiles[!cacheFiles %in% c(cppSourcePath, buildDirectory)]
231+
unlink(oldCacheFiles, recursive = TRUE)
232+
}
233+
208234
# Define a single C++ function
209235
cppFunction <- function(code,
210236
depends = character(),
@@ -1063,10 +1089,8 @@ sourceCppFunction <- function(func, isVoid, dll, symbol) {
10631089
.sourceCppPlatformCacheDir <- function(cacheDir) {
10641090

10651091
dir <- file.path(cacheDir,
1066-
paste("sourceCpp",
1092+
paste(R.version$platform,
10671093
utils::packageVersion("Rcpp"),
1068-
R.version$platform,
1069-
R.version$`svn rev`,
10701094
sep = "-"))
10711095
if (!dir.exists(dir))
10721096
dir.create(dir, recursive = TRUE)

man/sourceCpp.Rd

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and RCPP_MODULE declarations. A shared library is then built and its exported fu
99
}
1010
\usage{
1111
sourceCpp(file = "", code = NULL, env = globalenv(),
12-
embeddedR = TRUE, rebuild = FALSE, cacheDir = tempdir(),
12+
embeddedR = TRUE, rebuild = FALSE,
13+
cacheDir = tempdir(), cleanupCacheDir = FALSE,
1314
showOutput = verbose, verbose = getOption("verbose"),
1415
dryRun = FALSE)
1516
}
@@ -31,6 +32,9 @@ sourceCpp(file = "", code = NULL, env = globalenv(),
3132
}
3233
\item{cacheDir}{
3334
Directory to use for caching shared libraries. If the underlying file or code passed to \code{sourceCpp} has not changed since the last invocation then a cached version of the shared library is used. The default value of \code{tempdir()} results in the cache being valid only for the current R session. Pass an alternate directory to preserve the cache across R sessions.
35+
}
36+
\item{cleanupCacheDir}{
37+
Cleanup all files in the cacheDir that were not a result of this compilation. Note that this will cleanup the cache from all other calls to sourceCpp with the same cacheDir. This option should therefore only be specified by callers that provide a unique cacheDir per scope (e.g. chunk labels in a weaved document).
3438
}
3539
\item{showOutput}{
3640
\code{TRUE} to print \code{R CMD SHLIB} output to the console.
@@ -74,7 +78,7 @@ fibonacci(10)
7478
*/
7579
}
7680
77-
Multiple R code chunks can be included in a C++ file. R code is sourced after the C++ compliation is completed so all functions and modules will be available to the R code.
81+
Multiple R code chunks can be included in a C++ file. R code is sourced after the C++ compilation is completed so all functions and modules will be available to the R code.
7882
}
7983
8084
\value{

0 commit comments

Comments
 (0)