Minimal Examples of Using Rust Code in R
Rust is a modern alternative to C and compiled rust code is ABI compatible with C. Many Rust libraries include C API headers so that the compiled rust code can be called from R/C/C++ as if it were C code. This package shows how to do this. The r-rust organization contains several more simple R packages interfacing with cargo crates.
To learn more about using Rust code in R packages, also have a look at the r-rust FAQ and the slides about this project presented at eRum2018!
Bundle your rust code in a the embedded cargo package (see the Cargo.toml
file) and then the src/Makevars file is written such that R will automatically build the rust modules when the R package is installed.
hellorust
├─ configure ← checks if 'cargo' is installed
├─ src
│ ├─ myrustlib ← bundled cargo package with your code
│ | ├─ Cargo.toml ← cargo dependencies and metadata
│ | ├─ src ← rust source code
│ | └─ api.h ← C headers for exported rust API
| |
│ ├─ Makevars ← Ties everything together
│ └─ wrapper.c ← C code for R package
├─ DESCRIPTION
└─ R ← Standard R+C stuff
As per the new 2023 cran guidelines we now vendor the cargo crates in the R source packages in order to support offline installation. This is done in a two step process:
vendor.tar.xz
bundle that contains all the cargo sources. In addition, the vendor-authors.R script generates an inst/AUTHORS
file that lists the authors of the dependencies, as required by CRAN. Both of these scripts are called in the package cleanup file and therefore run automatically during R CMD build
when the source package is created.vendor.tar.xz
bundle (when available) and generates a .cargo/config.toml
file to instruct cargo build
to use the vendored (offline) sources.If you run R CMD INSTALL
directly from a checkout (without building a source package), then no vendor.tar.xz
is created and cargo falls back to downloading crates on-the-fly.
You can test or force the use of vendored sources by passing --offline
to cargo build
.
If Rust is available, clone this repository and run the regular R CMD INSTALL
command:
R CMD INSTALL hellorust
Alternatively, to download and install from within R itself:
# install.packages("remotes")
remotes::install_github("r-rust/hellorust")
The standard rust toolchain includes a great package manager cargo
with a corresponding registry crates.io. Cargo makes it very easy to build a rust package including all dependencies into a static library that can easily be linked into an R package.
This is perfect for R because we can compile and link all rust code at build-time without any system dependencies. Rust itself has no substantial runtime so the resulting R package is entirely self contained. Indeed, rust has been designed specifically to serve well as an embedded language.
Note that cargo
is only needed at build-time. Rust has no runtime dependencies. The easiest way to install the latest version of Rust (including cargo) is from: https://www.rust-lang.org/tools/install
Alternatively, you may install cargo from your OS package manager:
sudo apt-get install cargo
sudo yum install cargo
brew install rustc
*Note that on CentOS you first need to enable EPEL via sudo yum install epel-release
.
In order for rust to work with R you need to install the toolchain using rustup
and then add the x86_64-pc-windows-gnu
target. First download rustup-init.exe and then install the default toolchain:
rustup-init.exe -y --default-host x86_64-pc-windows-gnu
Or if rust is already installed (for example on GitHub actions), you can simply add the target:
rustup target add x86_64-pc-windows-gnu
To compile 32bit packages also add the i686-pc-windows-gnu
target, but 32-bit is no longer supported as of R 4.2.
Update 2023: This step is no longer needed because GitHub action runners now have the required Rust targets preinstalled by default.
To use GitHub actions, you can use the standard r workflow script in combination with this extra step:
- name: Add Rtools targets to Rust
if: runner.os == 'Windows'
run: |
rustup target add i686-pc-windows-gnu
rustup target add x86_64-pc-windows-gnu
The gifski package has been on CRAN since 2018, and uses this same structure.