Dear Dirk,
I have now written a patch which incorporates your answer to
Hadley in the Rcpp-package manual. I am attaching the complete
*Rnw file. The diff is below.
Please let me know your preferred channel for me to submit future
patch suggestions.
Kind regards,
+glenn
########## begin diff output ##################
233,244d232
<
< \subsubsection{\proglang{C++} development workflow}
< \proglang{R}'s package framework elegantly supports rapid
prototyping and experimental code development. One suggested
workflow tests changes to \proglange{C++} code via
< <<echo=FALSE>>=
< $ R CMD INSTALL mypkg && r -lmypkg -e 'someFunctionToTickle(3.14)'
< @
<
< The second command calls 'r' (littler), not 'R'. Littler is an
alternative front end to GNU R for '#!' (hashbang) scripting. It
has fast start-up times and gives a guaranteed clean slate. The -l
option calls 'library(mypkg)' before executing the \proglang{R}
expression. Littler is available via most Linux distribution's
package management systems. The project homepage is
\href{http://code.google.com/p/littler/.}
<
< Alternately, rapid prototyping can be conducted using the
inline package and \Sexpr{cxxfunction}.
<
<
########## end diff output ##################
-------- Original Message --------
Subject: Re: [Rcpp-devel] devtools load_all() and modules
Date: Tue, 20 Mar 2012 12:38:37 -0500
From: Dirk Eddelbuettel <[email protected]>
To: Hadley Wickham <[email protected]>
CC: [email protected]
On 20 March 2012 at 12:22, Hadley Wickham wrote:
|> For usage beyond what we document and test, you're on your own. If you want
|> to explore usage with devtools and other means, go for it.
|>
|> But I will be unlikely to have time to work this out for you, unfortunately.
|
| Let me flip this around on you - when you're developing a package that
| uses Rcpp, could you outline your workflow? After modifying your R
| and C++ code, what sequence of steps do you take so that you can try
| out the code in an R session? It would be really useful to hear what
| workflow that you (and others) find most helpful.
Sure, very valid question. I tend to do two things:
a) at times experiment/try/play with the inline package and cxxfunction
b) much more often, work with a package where, for force of habit, my
typical workflow often is
$ R CMD INSTALL mypkg&& r -lmypkg -e 'someFunctionToTickle(3.14)'
which does a 'library(mypkg)' for me (which is how r resolves the -l
arguments) and then executes the R expression
as I never got really happy with any of the unloading attempts. Littler's r
starts very quickly and gives me a guaranteed clean slate, so I tend to work
from there.
Dirk
--
"Outside of a dog, a book is a man's best friend. Inside of a dog, it is too
dark to read." -- Groucho Marx
_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
\documentclass[10pt]{article}
%\VignetteIndexEntry{Rcpp-package}
\usepackage{vmargin}
\setmargrb{0.75in}{0.75in}{0.75in}{0.75in}
\usepackage{color,alltt}
\usepackage[authoryear,round,longnamesfirst]{natbib}
\usepackage[colorlinks]{hyperref}
\definecolor{link}{rgb}{0,0,0.3} %% next few lines courtesy of
RJournal.sty
\hypersetup{
colorlinks,%
citecolor=link,%
filecolor=link,%
linkcolor=link,%
urlcolor=link
}
\newcommand{\proglang}[1]{\textsf{#1}}
\newcommand{\pkg}[1]{{\fontseries{b}\selectfont #1}}
%% defined as a stop-gap measure til interaction with highlight is sorted out
\newcommand{\hlboxlessthan}{ \hlnormalsizeboxlessthan}
\newcommand{\hlboxgreaterthan}{\hlnormalsizeboxgreaterthan}
\newcommand{\hlboxopenbrace}{ \hlnormalsizeboxopenbrace}
\newcommand{\hlboxclosebrace}{ \hlnormalsizeboxclosebrace}
\newcommand{\hlboxbacktick}{ \hlnormalsizeboxbacktick}
\newcommand{\hlboxunderscore}{ \hlnormalsizeboxunderscore}
<<echo=FALSE,print=FALSE>>=
prettyVersion <- packageDescription("Rcpp")$Version
prettyDate <- format(Sys.Date(), "%B %e, %Y")
@
\author{Dirk Eddelbuettel \and Romain Fran\c{c}ois}
\title{Writing a package that uses \pkg{Rcpp} }
\date{\pkg{Rcpp} version \Sexpr{prettyVersion} as of \Sexpr{prettyDate}}
<<echo=FALSE>>=
require( Rcpp )
link <- function( f, package, text = f, root =
"http://finzi.psych.upenn.edu/R/library/" ){
h <- if( missing(package) ) {
as.character( help( f ) )
} else {
as.character( help( f, package = paste( package, sep = "" ) ) )
}
if( ! length(h) ){
sprintf( "\\\\textbf{%s}", f )
} else {
rx <- "^.*/([^/]*?)/help/(.*?)$"
package <- sub( rx, "\\1", h, perl = TRUE )
page <- sub( rx, "\\2", h, perl = TRUE )
sprintf( "\\\\href{%s%s/html/%s.html}{\\\\texttt{%s}}", root,
package, page, text )
}
}
linkS4class <- function( cl, package, text = cl, root =
"http://finzi.psych.upenn.edu/R/library/" ){
link( sprintf("%s-class", cl), package, text, root )
}
@
\begin{document}
\maketitle
\abstract{
\noindent This document provides a short overview of how to use
\pkg{Rcpp}~\citep{CRAN:Rcpp,JSS:Rcpp} when writing an \proglang{R} package.
It
shows how usage of the function \Sexpr{link("Rcpp.package.skeleton")}
which creates a complete and self-sufficient example package using
\pkg{Rcpp}. All components of the directory tree created by
\Sexpr{link("Rcpp.package.skeleton")} are discussed in detail. This
document thereby complements the \textsl{Writing R Extensions}
manual~\citep{R:Extensions} which is the authoritative source on how to extend
\proglang{R} in general.
}
\section{Introduction}
\pkg{Rcpp}~\citep{CRAN:Rcpp,JSS:Rcpp} is an extension package for \proglang{R}
which
offers an easy-to-use yet featureful interface between \proglang{C++} and
\proglang{R}. However, it is somewhat different from a traditional
\proglang{R} package because its key component is a \proglang{C++} library. A
client package that wants to make use of the \pkg{Rcpp} features must link
against the library provided by \pkg{Rcpp}.
It should be noted that \proglang{R} has only limited support for
\proglang{C(++)}-level dependencies between packages~\citep{R:Extensions}. The
\texttt{LinkingTo} declaration in the package \texttt{DESCRIPTION} file
allows the client package to retrieve the headers of the target package (here
\pkg{Rcpp}), but support for linking against a library is not provided by
\proglang{R} and has to be added manually.
This document follows the steps of the \Sexpr{link("Rcpp.package.skeleton")}
function to illustrate a recommended way of using \pkg{Rcpp} from a client
package. We illustrate this using a simple \proglang{C++} function
which will be called by an \proglang{R} function.
We strongly encourage the reader to become familiar with the material in the
\textsl{Writing R Extensions} manual~\citep{R:Extensions}, as well as with other
documents on \proglang{R} package creation such as \cite{Leisch:2008:Tutorial}.
Given
a basic understanding of how to create \proglang{R} package, the present
document aims to provide the additional information on how to use \pkg{Rcpp}
in such add-on packages.
\section{Using \texttt{Rcpp.package.skeleton}}
\subsection{Overview}
\pkg{Rcpp} provides a function \Sexpr{link("Rcpp.package.skeleton")}, modeled
after the base \proglang{R} function \Sexpr{link("package.skeleton")}, which
facilitates creation of a skeleton package using \pkg{Rcpp}.
\Sexpr{link("Rcpp.package.skeleton")} has a number of arguments documented on
its help page (and similar to those of \Sexpr{link("package.skeleton")}). The
main argument is the first one which provides the name of the package one
aims to create by invoking the function. An illustration of a call using an
argument \texttt{mypackage} is provided below.
<<echo=FALSE>>=
here <- getwd()
gendir <- tempfile()
dir.create( gendir )
setwd( gendir )
Rcpp.package.skeleton( "mypackage" )
dir.create( tlib <- tempfile() )
system( sprintf( 'R CMD INSTALL --library="%s" mypackage ', tlib ) )
require( "mypackage", lib.loc = tlib )
@
% <<>>=
% Rcpp.package.skeleton( "mypackage" )
% writeLines( system( "tree" , intern = TRUE ) )
% @
\begin{Hchunk}
\begin{Hinput}
\ttfamily\noindent
\hlprompt{\usebox{\hlboxgreaterthan}{\
}}\hlfunctioncall{Rcpp.package.skeleton}\hlkeyword{(}{\
}\hlstring{"mypackage"}{\ }\hlkeyword{)}\mbox{}
\normalfont
\end{Hinput}
\begin{Hinput}
\ttfamily\noindent
\hlprompt{\usebox{\hlboxgreaterthan}{\
}}\hlfunctioncall{writeLines}\hlkeyword{(}{\
}\hlfunctioncall{system}\hlkeyword{(}{\ }\hlstring{"tree"}\hlkeyword{,}{\
}\hlargument{intern}{\ }\hlargument{=}{\ }\hlnumber{TRUE}{\ }\hlkeyword{)}{\
}\hlkeyword{)}\mbox{}
\normalfont
\end{Hinput}
\begin{Houtput}
\ttfamily\noindent
.\hspace*{\fill}\\
\hlstd{}\usebox{\hlboxbacktick}--{\ }mypackage\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|--{\ }DESCRIPTION\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|--{\ }NAMESPACE\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|--{\ }R\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|{\ }{\ }{\ }\usebox{\hlboxbacktick}--{\
}rcpp\usebox{\hlboxunderscore}hello\usebox{\hlboxunderscore}world.R\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|--{\ }Read-and-delete-me\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|--{\ }man\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|{\ }{\ }{\ }|--{\
}mypackage-package.Rd\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }|{\ }{\ }{\ }\usebox{\hlboxbacktick}--{\
}rcpp\usebox{\hlboxunderscore}hello\usebox{\hlboxunderscore}world.Rd\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }\usebox{\hlboxbacktick}--{\ }src\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }{\ }{\ }{\ }{\ }|--{\ }Makevars\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }{\ }{\ }{\ }{\ }|--{\ }Makevars.win\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }{\ }{\ }{\ }{\ }|--{\
}rcpp\usebox{\hlboxunderscore}hello\usebox{\hlboxunderscore}world.cpp\hspace*{\fill}\\
\hlstd{}{\ }{\ }{\ }{\ }{\ }{\ }{\ }{\ }\usebox{\hlboxbacktick}--{\
}rcpp\usebox{\hlboxunderscore}hello\usebox{\hlboxunderscore}world.h\hspace*{\fill}\\
\hlstd{}\hspace*{\fill}\\
\hlstd{}4{\ }directories,{\ }10{\ }files\hspace*{\fill}\\
\hlstd{}\mbox{}
\normalfont
\end{Houtput}
\end{Hchunk}
Using \Sexpr{link("Rcpp.package.skeleton")} is by far the simplest approach
as it fulfills two roles. It creates the complete set of files needed for a
package, and it also includes the different components needed for using
\pkg{Rcpp} that we discuss in the following sections.
\subsection{\proglang{R} code}
The skeleton contains an example \proglang{R} function
\texttt{rcpp\_hello\_world} that uses the \Sexpr{link(".Call")} interface to
invoke the \proglang{C++} function \texttt{rcpp\_hello\_world} from the
package \texttt{mypackage}.
<<echo=FALSE,results=tex>>=
highlight(
file.path( gendir, "mypackage", "R", "rcpp_hello_world.R" ),
renderer = renderer_latex( doc = FALSE )
)
@
\pkg{Rcpp} uses the \Sexpr{link(".Call")} calling convention as it allows
transport of actual \proglang{R} objects back and forth between the
\proglang{R} side and the \proglang{C++} side. \proglang{R} objects
(\texttt{SEXP}) can be conveniently manipulated using the \pkg{Rcpp} API.
Note that in this example, no arguments were passed from \proglang{R} down to
the \proglang{C++} layer. Doing so is straightforward (and one of the key
features of \pkg{Rcpp}) but not central to our discussion of the package
creation mechanics.
\subsection{\proglang{C++} code}
The \proglang{C++} function is declared in the \texttt{rcpp\_hello\_world.h}
header file:
<<echo=FALSE,results=tex>>=
external_highlight(
file.path( gendir, "mypackage", "src", "rcpp_hello_world.h" ),
type = "LATEX",
doc = FALSE
)
@
The header includes the \texttt{Rcpp.h} file, which is the only file that
needs to be included to use \pkg{Rcpp}. The function is then implemented in
the \texttt{rcpp\_hello\_world.cpp} file
<<echo=FALSE,results=tex>>=
external_highlight(
file.path( gendir, "mypackage", "src", "rcpp_hello_world.cpp" ),
type = "LATEX",
doc = FALSE
)
@
The function creates an \proglang{R} list that contains a
\Sexpr{link("character")} vector and a \Sexpr{link("numeric")} vector using
\pkg{Rcpp}
classes. At the \proglang{R} level, we will therefore receive a list of
length two containing these two vectors:
<<>>=
rcpp_hello_world( )
@
\subsubsection{\proglang{C++} development workflow}
\proglang{R}'s package framework elegantly supports rapid prototyping and
experimental code development. One suggested workflow tests changes to
\proglange{C++} code via
<<echo=FALSE>>=
$ R CMD INSTALL mypkg && r -lmypkg -e 'someFunctionToTickle(3.14)'
@
The second command calls 'r' (littler), not 'R'. Littler is an alternative
front end to GNU R for '#!' (hashbang) scripting. It has fast start-up times
and gives a guaranteed clean slate. The -l option calls 'library(mypkg)' before
executing the \proglang{R} expression. Littler is available via most Linux
distribution's package management systems. The project homepage is
\href{http://code.google.com/p/littler/.}
Alternately, rapid prototyping can be conducted using the inline package and
\Sexpr{cxxfunction}.
\subsection{\texttt{DESCRIPTION}}
The skeleton generates an appropriate \texttt{DESCRIPTION} file, using
both \texttt{Depends:} and \texttt{LinkingTo} for \pkg{Rcpp}:
<<echo=FALSE,results=tex>>=
local({
tf <- sprintf( "%s.make", tempfile() )
file.copy( file.path( gendir, "mypackage", "DESCRIPTION" ), tf )
external_highlight( tf, type = "LATEX", doc = FALSE )
unlink( tf )
})
@
\Sexpr{link("Rcpp.package.skeleton")} adds the three last lines to the
\texttt{DESCRIPTION} file generated by \Sexpr{link("package.skeleton")}.
The \texttt{Depends} declaration indicates \proglang{R}-level dependency
between the client package and \pkg{Rcpp}. The \texttt{LinkingTo} declaration
indicates that the client package needs to use header files exposed by
\pkg{Rcpp}.
\subsection{\texttt{Makevars} and \texttt{Makevars.win}}
Unfortunately, the \texttt{LinkingTo} declaration in itself is not
enough to link to the user \proglang{C++} library of \pkg{Rcpp}. Until more
explicit support for libraries is added to \proglang{R}, we need to manually
add the \pkg{Rcpp} library to the \texttt{PKG\_LIBS} variable in the
\texttt{Makevars} and \texttt{Makevars.win} files. \pkg{Rcpp} provides the
unexported function \texttt{Rcpp:::LdFlags()} to ease the process:
<<echo=FALSE,results=tex>>=
local({
tf <- sprintf( "%s.make", tempfile() )
file.copy( file.path( gendir, "mypackage", "src", "Makevars" ), tf )
external_highlight( tf, type = "LATEX", doc = FALSE )
unlink( tf )
})
@
The \texttt{Makevars.win} is the equivalent, targeting windows.
<<echo=FALSE,results=tex>>=
local({
tf <- sprintf( "%s.make", tempfile() )
file.copy( file.path( gendir, "mypackage", "src", "Makevars.win" ), tf )
external_highlight( tf, type = "LATEX", doc = FALSE )
unlink( tf )
})
@
\subsection{\texttt{NAMESPACE}}
The \Sexpr{link("Rcpp.package.skeleton")} function also creates a file
\texttt{NAMESPACE}.
<<echo=FALSE,results=tex>>=
local({
tf <- sprintf( "%s.make", tempfile() )
file.copy( file.path( gendir, "mypackage", "NAMESPACE" ), tf )
external_highlight( tf, type = "LATEX", doc = FALSE )
unlink( tf )
})
@
This file serves two purposes. First, it ensure that the dynamic library
contained in the package we are creating via
\Sexpr{link("Rcpp.package.skeleton")} will be loaded and thereby made
available to the newly created \proglang{R} package. Second, it declares
which functions should be globally visible from the namespace of this
package. As a reasonable default, we export all functions.
\subsection{Help files}
Also created is a directory \texttt{man} containing two help files. One is
for the package itself, the other for the (single) \proglang{R} function
being provided and exported.
The \textsl{Writing R Extensions} manual~\citep{R:Extensions} provides the
complete
documentation on how to create suitable content for help files.
\subsubsection{\texttt{mypackage-package.Rd}}
The help file \texttt{mypackage-package.Rd} can be used to describe
the new package.
<<echo=FALSE,results=tex>>=
local({
tf <- sprintf( "%s.make", tempfile() )
file.copy( file.path( gendir, "mypackage", "man",
"mypackage-package.Rd" ), tf )
external_highlight( tf, type = "LATEX", doc = FALSE )
unlink( tf )
})
@
\subsubsection{\texttt{rcpp\_hello\_world.Rd}}
The help file \texttt{rcpp\_hello\_world.Rd} serves as documentation for the
example \proglang{R} function.
<<echo=FALSE,results=tex>>=
local({
tf <- sprintf( "%s.make", tempfile() )
file.copy( file.path( gendir, "mypackage", "man", "rcpp_hello_world.Rd"
), tf )
external_highlight( tf, type = "LATEX", doc = FALSE )
unlink( tf )
})
@
\section{Further examples}
The canonical example of a package that uses \pkg{Rcpp} is the
\pkg{RcppExamples} \citep{CRAN:RcppExamples} package. \pkg{RcppExamples}
contains various examples of using \pkg{Rcpp} using both the extended
(``new'') API and the older (``classic'') API. Hence, the \pkg{RcppExamples}
package is provided as a template for employing \pkg{Rcpp} in packages.
Other CRAN packages using the \pkg{Rcpp} package are \pkg{RcppArmadillo}
\citep{CRAN:RcppArmadillo}, \pkg{highlight} \citep{CRAN:highlight},
and \pkg{minqa} \citep{CRAN:minqa} all of which follow precisely the guidelines
of this document. Several other packages follow older (but still supported
and appropriate) instructions. They can serve examples on how to get data to
and from \proglang{C++} routines, but should not be considered templates for
how to connect to \pkg{Rcpp}. The full list of packages using \pkg{Rcpp} can
be found at the \href{http://CRAN.R-project.org/package=Rcpp}{CRAN page} of
\pkg{Rcpp}.
\section{Other compilers}
Less experienced \proglang{R} users on the Windows platform frequently ask
about using \pkg{Rcpp} with the Visual Studio toolchain. That is simply not
possible as \proglang{R} is built with the \pkg{gcc} compiler. Different
compilers have different linking conventions. These conventions are
particularly hairy when it comes to using \proglang{C++}. In short, it is
not possible to simply drop sources (or header files) from \pkg{Rcpp} into a
\proglang{C++} project built with Visual Studio, and this note makes no
attempt at claiming otherwise.
\pkg{Rcpp} is fully usable on Windows provided the standard Windows
toolchain for \proglang{R} is used. See the \textsl{Writing R Extensions}
manual~\citep{R:Extensions} for details.
\section{Summary}
This document described how to use the \pkg{Rcpp} package for \proglang{R}
and \proglang{C++} integration when writing an \proglang{R} extension
package. The use of the \Sexpr{link("Rcpp.package.skeleton")} was shown in
detail, and references to further examples were provided.
\bibliographystyle{plainnat}
\bibliography{Rcpp}
\end{document}
_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel