<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/1-easy-package-registration/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://dirk.eddelbuettel.com/blog/2017/03/29#001_easy_package_registration"> Thinking inside the box </a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Welcome to the first actual post in the <span><em>R</em><sup>4</sup></span> series, following the <a target="_blank" rel="nofollow" href="http://dirk.eddelbuettel.com/blog/2017/03/27#000_introducing_r4">short announcement</a> earlier this week.</p>
<h3>Context</h3>
<p>Last month, Brian Ripley <a target="_blank" rel="nofollow" href="https://stat.ethz.ch/pipermail/r-devel/2017-February/073755.html">announced on r-devel</a> that registration of routines would now be tested for by <code>R CMD check</code> in r-devel (which by next month will become R 3.4.0). A NOTE will be issued now, this will presumably turn into a WARNING at some point. <em>Writing R Extensions</em> has <a target="_blank" rel="nofollow" href="https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Registering-native-routines">an updated introduction</a>) of the topic.</p>
<p>Package registration has long been available, and applies to all <em>native</em> (i.e. &quot;compiled&quot;) function via the <code>.C()</code>, <code>.Call()</code>, <code>.Fortran()</code> or <code>.External()</code> interfaces. If you use any of those — and <code>.Call()</code> may be the only truly relevant one here — then is of interest to you.</p>
<p>Brian Ripley and Kurt Hornik also added a new helper function: <code>tools::package_native_routine_registration_skeleton()</code>. It parses the R code of your package and collects all native function entrypoints in order to autogenerate the registration. It is available in R-devel now, will be in R 3.4.0 and makes adding such registration <em>truly trivial</em>.</p>
<p>But as of today, it requires that you have R-devel. Once R 3.4.0 is out, you can call the helper directly.</p>
<p>As for R-devel, there have always been at least two ways to use it: build it locally (which we may cover in another <span><em>R</em><sup>4</sup></span> installment), or using Docker. Here will focus on the latter by relying on the <a target="_blank" rel="nofollow" href="https://hub.docker.com/u/rocker/">Rocker</a> project by <a target="_blank" rel="nofollow" href="http://www.carlboettiger.info/">Carl</a> and myself.</p>
<h3>Use the Rocker drd Image</h3>
<p>We assume you can run Docker on your system. How to add it on Windows, macOS or Linux is beyond our scope here today, but also covered extensively elsewhere. So we assume you can execute <code>docker</code> and <em>e.g.</em> bring in the ‘daily r-devel’ image drd from our <a target="_blank" rel="nofollow" href="https://hub.docker.com/u/rocker/">Rocker</a> project via</p>
<div>
<pre><code><span>~</span>$ <span>docker</span> pull rocker/drd</code></pre>
</div>
<p>With that, we can use R-devel to create the registration file very easily in a single call (which is a long command-line we have broken up with one line-break for the display below).</p>
<p>The following is real-life example when I needed to add registration to the <a target="_blank" rel="nofollow" href="https://github.com/eddelbuettel/rcpptoml">RcppTOML</a> package for <a target="_blank" rel="nofollow" href="http://dirk.eddelbuettel.com/blog/2017/03/26#rcpptoml_0.1.2">this week’s update</a>:</p>
<div>
<pre><code><span>~/git</span>/<span>rcpptoml</span>(master)$ <span>docker</span> run --rm -ti -v <span>$(</span><span>pwd</span><span>)</span>:/mnt rocker/drd <span>\ </span> <span>## line break</span>
             <span>RD</span> --slave -e <span>'tools::package_native_routine_registration_skeleton(&quot;/mnt&quot;)'</span>
<span>#include &lt;R.h></span>
<span>#include &lt;Rinternals.h></span>
<span>#include &lt;stdlib.h> // for NULL</span>
<span>#include &lt;R_ext/Rdynload.h></span>

<span>/*</span> FIXME: 
   <span>Check</span> these declarations against the C/Fortran source code.
<span>*/</span>

<span>/*</span> .Call calls */
<span>extern</span> SEXP RcppTOML_tomlparseImpl(SEXP, SEXP, SEXP);

<span>static</span> const R_CallMethodDef CallEntries[] = {
    {<span>&quot;RcppTOML_tomlparseImpl&quot;</span>, <span>(DL_FUNC)</span> <span>&amp;RcppTOML_tomlparseImpl</span>, 3},
    {<span>NULL</span>, NULL, 0}
};

<span>void</span> R_init_RcppTOML(DllInfo *dll)
<span>{</span>
    <span>R_registerRoutines</span>(dll, NULL, CallEntries, NULL, NULL);
    <span>R_useDynamicSymbols</span>(dll, FALSE);
<span>}</span>
<span>edd@max</span>:~/git/rcpptoml(master)$ </code></pre>
</div>
<h3>Decompose the Command</h3>
<p>We can understand the <code>docker</code> command invocation above through its components:</p>
<ul>
<li><code>docker run</code> is the basic call to a container</li>
<li><code>--rm -ti</code> does subsequent cleanup (<code>--rm</code>) and gives a terminal (<code>-t</code>) that is interactive (<code>-i</code>)</li>
<li><code>-v $(pwd):/mnt</code> uses the <code>-v a:b</code> options to make local directory <code>a</code> available as <code>b</code> in the container; here <code>$(pwd)</code> calls <em>print working directory</em> to get the local directory which is now mapped to <code>/mnt</code> in the container</li>
<li><code>rocker/drd</code> invokes the ‘drd’ container of the Rocker project</li>
<li><code>RD</code> is a shorthand to the R-devel binary inside the container, and the main reason we use this container</li>
<li><code>-e 'tools::package_native_routine_registration_skeleton(&quot;/mnt&quot;)</code> calls the helper function of R (currently in R-devel only, so we use RD) to compute a possible <code>init.c</code> file based on the current directory — which is <code>/mnt</code> inside the container</li>
</ul>
<p>That it. We get a call to the R function executed inside the Docker container, examining the package in the working directory and creating a registration file for it which is display to the console.</p>
<h3>Copy the Output to <code>src/init.c</code></h3>
<p>We simply copy the output to a file <a target="_blank" rel="nofollow" href="https://github.com/eddelbuettel/rcpptoml/blob/master/src/init.c">src/init.c</a>; I often fold one opening brace one line up.</p>
<h3>Update NAMESPACE</h3>
<p>We also change <a target="_blank" rel="nofollow" href="https://github.com/eddelbuettel/rcpptoml/blob/master/NAMESPACE#L1">one line in NAMESPACE</a> from (for this package) <code>useDynLib(&quot;RcppTOML&quot;)</code> to <code>useDynLib(&quot;RcppTOML&quot;, .registration=TRUE)</code>. Adjust accordingly for other package names.</p>
<h3>That’s it!</h3>
<p>And with that we a have a package which no longer provokes the NOTE as seen by the <a target="_blank" rel="nofollow" href="https://cloud.r-project.org/web/checks/check_results_RcppTOML.html">checks page</a>. Calls to native routines are now safer (less of a chance for name clashing), get called quicker as we skip the symbol search (see the WRE discussion) and best of all this applies to <em>all</em> native routines whether written by hand or written via a generator such as <a target="_blank" rel="nofollow" href="https://cloud.r-project.org/web/packages/Rcpp/vignettes/Rcpp-attributes.pdf">Rcpp Attributes</a>.</p>
<p>So give this a try to get your package up-to-date.</p>
<p>
This post by <a target="_blank" rel="nofollow" href="http://dirk.eddelbuettel.com/">Dirk Eddelbuettel</a> originated on his <a target="_blank" rel="nofollow" href="http://dirk.eddelbuettel.com/blog/">Thinking inside the box</a> blog. Please report excessive re-aggregation in third-party for-profit settings.</p>
<p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://dirk.eddelbuettel.com/blog/2017/03/29#001_easy_package_registration"> Thinking inside the box </a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/wvE2qrnZry4"></a></div>