Skip to content

Instantly share code, notes, and snippets.

@jjallaire
Created November 3, 2012 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jjallaire/4008371 to your computer and use it in GitHub Desktop.
Save jjallaire/4008371 to your computer and use it in GitHub Desktop.
Setup build environment
# Setup the build environment based on the specified dependencies. Returns an
# opaque object that can be passed to .restoreEnvironment to reverse whatever
# changes that were made
.setupBuildEnvironment <- function(depends) {
# discover dependencies
buildEnv <- list()
linkingToPackages <- c("Rcpp")
for (package in depends) {
# add a LinkingTo for this package
linkingToPackages <- unique(c(linkingToPackages, package))
# see if the package exports a plugin
plugin <- .getInlinePlugin(package)
if (!is.null(plugin)) {
# get the plugin settings
settings <- plugin()
# merge environment variables
pluginEnv <- settings$env
for (name in names(pluginEnv)) {
# if it doesn't exist already just set it
if (is.null(buildEnv[[name]])) {
buildEnv[[name]] <- pluginEnv[[name]]
}
# if it's not identical then append
else if (!identical(buildEnv[[name]],
pluginEnv[[name]])) {
buildEnv[[name]] <- paste(buildEnv[[name]],
pluginEnv[[name]]);
}
else {
# it already exists and it's the same value, this
# likely means it's a flag-type variable so we
# do nothing rather than appending it
}
}
# capture any LinkingTo elements defined by the plugin
linkingToPackages <- unique(c(linkingToPackages,
settings$LinkingTo))
}
}
# if there is no buildEnv from a plugin then use the Rcpp plugin
if (length(buildEnv) == 0) {
buildEnv <- Rcpp:::inlineCxxPlugin()$env
} else {
# we are using a plugin -- confirm that the plugin includes the Rcpp
# PKG_LIBS and if it doesn't then add them
pkgLibs <- buildEnv$PKG_LIBS
rcppLibs <- Rcpp:::RcppLdFlags()
if (is.null(pkgLibs) || !grepl(rcppLibs, pkgLibs, fixed = TRUE))
buildEnv$PKG_LIBS <- paste(pkgLibs, rcppLibs)
}
# set cxxFlags based on the LinkingTo dependencies (and also respect
# any PKG_CXXFLAGS set by the plugin)
pkgCxxFlags <- .buildPkgCxxFlags(linkingToPackages)
buildEnv$PKG_CXXFLAGS <- paste(buildEnv$PKG_CXXFLAGS, pkgCxxFlags)
# add cygwin message muffler
buildEnv$CYGWIN = "nodosfilewarning"
# create restore list
restore <- list()
for (name in names(buildEnv))
restore[[name]] <- Sys.getenv(name, unset = NA)
# set environment variables
do.call(Sys.setenv, buildEnv)
# return restore list
return (restore)
}
.restoreEnvironment <- function(restore) {
# variables to reset
setVars <- restore[!is.na(restore)]
if (length(setVars))
do.call(Sys.setenv, setVars)
# variables to remove
removeVars <- names(restore[is.na(restore)])
if (length(removeVars))
Sys.unsetenv(removeVars)
}
# Get the inline plugin for the specified package (return NULL if none found)
.getInlinePlugin <- function(package) {
tryCatch(get("inlineCxxPlugin", asNamespace(package)),
error = function(e) NULL)
}
# Build PKG_CXXFLAGS by from include directories of LinkingTo packages
.buildPkgCxxFlags <- function(linkingToPackages) {
pkgCxxFlags <- NULL
for (package in linkingToPackages) {
packagePath <- find.package(package, NULL, quiet=TRUE)
pkgCxxFlags <- paste(pkgCxxFlags,
paste0('-I"', packagePath, '/include"'),
collapse=" ")
}
return (pkgCxxFlags)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment