GitHub - jeroen/hellorust: Minimal Example of Using Rust in R Packages
source link: https://github.com/jeroen/hellorust
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Hello Rust
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!
Package Structure
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
Installing this package
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")
What is Cargo
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.
Installing Rust on Linux / MacOS
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:
- Debian/Ubuntu:
sudo apt-get install cargo
- Fedora/CentOS*:
sudo yum install cargo
- MacOS:
brew install rustc
*Note that on CentOS you first need to enable EPEL via sudo yum install epel-release
.
Installing Rust for R on Windows
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.
GitHub Actions
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
In the real world
The gifski package has been on CRAN since 2018, and uses this same structure.
However, do note that for the CRAN release we used a hack in src/Makevars.win
to download a precompiled version of the gifski crate on Windows, because the CRAN winbuilder did not have a Rust compiler installed.
More Resources
- Erum2018 slides about this project presented by Jeroen
- Rust Inside Other Languages chapter from official rust documentation
- extendr: a more advanced R extension interface using Rust
- Duncan's proof of concept: RCallRust
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK