##' Prepare Package
##'
##' This function prepares the package such that all the C / C++ source files
##' are concatenated into one file (for each source). This decreases
##' compilation time, and produces a tarball that can be used for submission
##' to CRAN.
##'
##' @param build Build the package with \code{R CMD build}?
##' @param check Check the package with \code{R CMD check}?
##' @param install Install the package with \code{R CMD INSTALL}? Only
##' done if \code{build} is \code{TRUE} as well.
##' @param copy.tarball If \code{build && copy.tarball}, we copy the tarball
##' generated by \code{R CMD build} to the \code{"dist"} folder.
prepare_package <- function(build=TRUE, check=TRUE, install=FALSE, copy.tarball=TRUE) {
owd <- getwd()
on.exit( setwd(owd) )
cat("Copying files to build directory...\n")
## check for necessary package files
files <- list.files()
stopifnot("DESCRIPTION" %in% files)
## get the package name from the DESCRIPTION file
DESCRIPTION <- as.list( read.dcf("DESCRIPTION")[1, ] )
pkg_name <- DESCRIPTION$Package
pkg_version <- DESCRIPTION$Version
## copy the files to a 'build' directory
buildDir <- file.path( tempdir(), pkg_name )
if( file.exists(buildDir) ) {
unlink(shQuote(buildDir), recursive=TRUE)
}
dir.create(buildDir, showWarnings=FALSE)
system( paste("cp -r .", buildDir) )
## in the build directory, 'cat' all the src files together
## have a separate file for .c, .cpp files
src_files <- list.files( full.names=TRUE, paste( sep='',
buildDir, "/src"
) )
## but don't concatenate init.c; copy it separately
src_files <- grep("init.c", src_files, value=TRUE, fixed=TRUE, invert=TRUE)
## regex: the regex to match for picking up files
## ext: the file extension to use on the outputted file
concatenate_src <- function(regex, ext) {
files <- grep( regex, src_files, value=TRUE )
final <- paste( sep='', buildDir, "/src/", pkg_name, "_", gsub("\\.", "", ext), ext )
system( paste("touch", final) )
files <- files[ files != final ]
files <- files[ !(files %in% grep("RcppExports", files, value=TRUE)) ]
for( file in files ) {
system( paste("cat", shQuote(file), ">>", shQuote(final)) )
system( paste("echo '' >>", shQuote(final) ) ) ## adds a newline just in case
system( paste("rm", file) )
}
}
cat("Concatenating source files...\n")
concatenate_src("c$", ".c")
concatenate_src("cpp$", ".cpp")
## remove all the .o, .so, .dll files
for( file in grep("o$|so$|dll$", list.files( full.names=TRUE, file.path( buildDir, "src" ) ), value=TRUE ) ) {
file.remove(file)
}
setwd( normalizePath( file.path( buildDir, "../" ) ) )
if (build) {
cat("Building...\n\n")
system( paste("R CMD build", gsub(".*/", "", buildDir)) )
cat("Copying package tarball to 'dist' directory...\n")
rx <- paste0("^", pkg_name, "_", pkg_version)
pkg <- grep(rx, list.files(), value=TRUE)
to <- file.path(owd, "dist", pkg)
if (copy.tarball) file.copy(pkg, to, overwrite=TRUE)
cat("Done!\n\n")
}
## check the package
if (check) {
cat("Running R CMD check...\n\n")
system( paste("R CMD check --as-cran", paste(sep='', pkg_name, "_", pkg_version, ".tar.gz")))
unlink( paste0(pkg_name, ".Rcheck"), recursive=TRUE )
}
## install the package
if (build && install) {
cat("Installing package...\n\n")
system( paste("R CMD INSTALL --preclean --no-multiarch", paste(sep='', pkg_name, "_", pkg_version, ".tar.gz")))
cat("Done!\n")
}
## remove the build dir
if (build) {
unlink(buildDir, recursive=TRUE)
unlink( paste0(pkg_name, "_", pkg_version, ".tar.gz") )
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.