A CRAN-ready R package template that integrates the simplicity of CMake with the power of Rcpp, enabling platform-independent linkage to external C/C++ libraries such as OpenCL, OpenGL, and others.
This template streamlines the development of high-performance R packages that rely on native code, without manual environment configuration.
- ✅ Platform-independent configuration and linkage with CMake
- ✅ Built
tar.gzdoes not have any binaries - everything is compiled at package installation. - ✅ No manual
Makefileor environment variable setup required - ✅ Clean separation of public/private headers in C++
- ✅ Simple Rcpp integration — no need to link Rcpp to the external libraries
- ✅ Example: GPU-accelerated distance matrix using OpenCL
cmake-rcpp-template
│ # Package metadata files
| # configure and configure.win handle the installation
|
├── src
│ │ # *.cpp define the Rcpp wrapper functions
│ │
│ └── backend
│ │ # A standard CMake project
| |
| ├── include
│ | | # public headers; should not include external
| | └── # library headers; otherwise Rcpp needs to link too.
| |
| ├── src
| | | # *.cpp define the actual implementation of functionality
| | |
| | └── internal
| | | # Some internal header files that may
| | └── # include external library headers.
| |
| └── lib
| └── # Some external library headers.
|
├── R
| └── # Caller scripts for the Rcpp functions and other R functions
|
├── man
| └── # Documentation goes here
|
└── inst
| # The library features the possibility to load external
└── # resources from this folder.
📝 Note: Public headers (backend/include) define C/C++ interfaces compatible with Rcpp; they should not include external library headers as Rcpp does not link against them. Private headers (backend/src/internal) manage actual implementation details, allowing clean abstraction.
The src/backend directory is a standalone CMake project. It builds a shared library that is automatically linked to the R package.
-
Extend linkage easily in
CMakeLists.txtfor OpenCL, OpenGL, etc. -
CMake handles all platform-dependent paths and setup.
The inst/ directory contains runtime resources (e.g., .cl kernels). During installation, files from src/backend/kernels are copied into inst/kernels using the configure and configure.win scripts.
# Accessed in R via:
system.file("kernels", package = "CMakeRcppTemplate")These paths are injected into the shared library at runtime using the .onLoad hook (see R/CMakeRcppTemplate.R), enabling dynamic loading of external resources like OpenCL kernels or OpenGL shaders.
This template uses manual SEXP wrappers for each Rcpp function (instead of [[Rcpp::export]]) to avoid platform-specific issues:
On some systems,
enterRNGScopeerrors to be undefined inRcppExports.oeven though it was not used inRcppExports.cppwhen using auto-generated bindings viacompileAttributes().
However, for simplicity, you may choose to use [[Rcpp::export]] if you're willing to trade off some portability.
📌 Important:
-
Add
import(Rcpp)to the top of yourNAMESPACEfile to avoid errors like:Rcpp_precious_remove not provided by package Rcpp. -
Manually written R wrappers for
SEXPfunctions should defensively check input types, since auto-type checks are not generated without[[Rcpp::export]].
Your package may export:
SEXP-wrapper functions viaRcpp- High-level R functions that internally call C/C++ via
Rcpp - High-level R functions that are independent of the C/C++ backend
This template includes an example GPU-based distance matrix computation via OpenCL. No changes are required to Rcpp code when adding new backend libraries — just update the CMake configuration.
- Clone this repository (use
--recursiveoption in order to get the OpenCL headers aswell!) - Modify the
src/backend/CMake code andsrc/*.cppRcpp- andSEXP-bindings - Add new R functions in the
R/directory calling yourSEXP-binding functions - Document functions via
Rmarkdowninman - Adjust the section
copying kernelsinconfigureandconfigure.winaccording to your external resources. - Build and install using
devtools::install()orR CMD INSTALL
Contributions, suggestions, and issues are welcome! Feel free to open a pull request or issue.
MIT License. See LICENSE for details.
⚠️ Author's Note: This project was created while I was affiliated with IAP-GmbH Intelligent Analytics Projects.