Best Way to Distribute Functions that Use nimbleExternalCall in R Packages

25 views
Skip to first unread message

joec...@googlemail.com

unread,
Jul 8, 2026, 3:09:27 PM (5 days ago) Jul 8
to nimble-users
Dear list,

I am currently writing an R package that, as part of implementation, extends some of NIMBLE's functionality with a set of custom distributions.  A couple of the functions added require linkage to C++ code.

My question is a conceptual one.

How is the best way to package these functions in a portable way during development?  I've currently investigated two options but both have some significant drawbacks:

*Option 1*:

I put the "myCustomFunc.cpp" and "myCustomFunc.h" files in the /inst/nimble_custom folder of the package so that they survive the installation process.  I then add some code to the .onLoad function that firstly compiles the source files to create a .o file in a temporary session directory (as the installation path will most likely not have write permissions for most users) and then makes a new global object that is the result of the nimbleExternalCall function using the header file location and newly create .o file as inputs.

The downside to this approach is that the source files need to be compiled every time the package namespace is loaded which could result in a significant load time if I start to write lots of external functions.  It also has the downside that the external function wrapper is not available when the package is being built and so you get loads of warnings from each call of the nimbleFunction that uses your external function saying something like "myCustomFunc appears to be an R function and so must be defined as a nimble function in order to compile this function".  I have suppress these warnings to pass a CRAN check.

*Option 2*

I put the "myCustomFunc.cpp" and "myCustomFunc.h" files the src subfolder of my package.  These functions then get compiled during the normal building of the package and can be exposed through the dll/so object.  This feels like the best way to go as I'm not fighting R's normal packaging routines but I just can't get it to work.  The nimbleExternalCall can only take .o files as inputs (as far as I can see) and not use .dll/.so files.  The .o intermediate products are all deleted upon installation.

I've tried implementing some kludges like adding a target onto the makevars files that copies the myCustomFunc.o file to /inst/nimble_custom but that opens up a whole host of other problems: not least of which it causes my package to fail the CRAN checker because there is compiled code in a place it shouldn't be.

I was wondering if anyone here had had experience of extended nimble functionality with packages that use the nimbleExternalCall interface.  How did you do it and keep your package passing the checker?

Many thanks in advance for people's time:

All the best,

Joe
Reply all
Reply to author
Forward
0 new messages