[Rcpp-devel] RFC -- Function for making modules ala inline

Christian Gunning xian at unm.edu
Fri Mar 18 12:16:13 CET 2011


Dear all,

Nothing earth-shattering here, but I think this could provide a nice
addition to the "rapid prototype" family.  I'm not sure if/where it
might live, and would appreciate any comments/suggestions to those
ends.


Attached is tested code -- a module-creation function that's mostly a subset
of cxxfunction.  It takes the name of the module as defined in the
source file's RCPP_MODULE(modname)  (could probably grep for this),
and the name of
a *file* containing the Module code.  Just like cxxfunction, it
compiles the code and loads the library.  It then loads/attaches/retrieves the
module from the library and returns a new Module object.

This function still uses 2 private functions from inline:
inline:::addLineNumbers and inline:::compileCode.  Since this is
Rcpp-specific, it seems like it would fit best in Rcpp, except for
it's (circular) dependency on inline.
Does this provide added utility and, if so, where should it live?
Perhaps as an additional plugin to inline, ala RcppModule?  Before I
bother inline, it would be great to know if anyone else finds this
useful.

thanks,
Christian
--
A man, a plan, a cat, a ham, a yak, a yam, a hat, a canal – Panama!
-------------- next part --------------
modfunction <- function ( modname, file_, plugin = "Rcpp", 
    includes = "", settings = getPlugin(plugin), ..., verbose = FALSE) 
{
    ## tempfile
    f <- basename(tempfile())
    settings_includes <- if (is.null(settings$includes)) 
                                ""
                        else paste(settings$includes, collapse = "\n")
    src <- paste(readLines(file_), collapse='\n')
    ## code
    code <- sprintf("// includes from the plugin\n%s\n\n// user includes\n%s\n\n %s",
        settings_includes, paste(includes, collapse = "\n"), src)
    if (!is.null(env <- settings$env)) {
        do.call(Sys.setenv, env)
        if (isTRUE(verbose)) {
            cat(" >> setting environment variables: \n")
            writeLines(sprintf("%s = %s", names(env), env))
        }
    }
    LinkingTo <- settings$LinkingTo
    if (!is.null(LinkingTo)) {
        paths <- .find.package(LinkingTo, quiet = TRUE)
        if (length(paths)) {
            flag <- paste(paste("-I\"", paths, "/include\"", sep=""), 
                collapse = " ")
            Sys.setenv(CLINK_CPPFLAGS = flag)
            if (isTRUE(verbose)) {
                cat(sprintf("\n >> LinkingTo : %s\n", paste(LinkingTo, 
                  collapse = ", ")))
                cat("CLINK_CPPFLAGS = ", flag, "\n\n")
            }
        }
    }
    if (isTRUE(verbose)) {
        writeLines(" >> Program source :\n")
        writeLines(inline:::addLineNumbers(code))
    }
    language <- "C++"
    libLFile <- inline:::compileCode(f, code, language = language, verbose = verbose)
    dyn.load(libLFile)
    retmod <- Module(modname, PACKAGE=f)
    return(retmod)
}  ## end function

if (FALSE) {
    ## not run -- finalizer from cxxfunction, needed?  where to unlink libLFile? 
    cleanup <- function(env) {
        if (f %in% names(getLoadedDLLs()))
            dyn.unload(libLFile)
        unlink(libLFile)
    }
    reg.finalizer(environment(), cleanup, onexit = TRUE)
}


More information about the Rcpp-devel mailing list