libR-sys
Low-level R library bindings
Installation
The recommended way to build this library is to use precompiled bindings, which are available for Linux, macOS, and Windows.
Alternatively, the library can be built from source, in which case it invokes bindgen crate, which has extra platform-specific dependencies (including msys2 for Windows).
Configuration
libR-sys recognizes the following environment variables:
LIBRSYS_R_VERSIONIf set, it is used to determine the version of R, for which bindings should be generated.LIBRSYS_R_VERSIONshould be set to one of the supported values, e.g.4.2.0or4.3.0-devel(the pattern ismajor.minor.patch[-devel]). MalformedLIBRSYS_R_VERSIONresults in compilation error. IfLIBRSYS_R_VERSIONis unset,Ris invoked and itsR.versionis used.
Using precompiled bindings (recommended)
Two components are required to build the library:
R: It needs to be installed and available in the search path.Rust: It is recommended to installRustusingrustup; search path should includeRustbinaries.
Note: On Windows, R < 4.2 requires a more complex setup in order to support the 32-bit version. Please refer to README-old-windows.md for more details.
Once R and Rust are configured, the library can be easily built:
# macOS & Linux
# Windows
To test the build, run cargo test.
# macOS & Linux
# Windows
Building bindings from source (advanced)
Note: On Windows, R < 4.2 requires a more complex setup in order to support the 32-bit version. Please refer to README-old-windows.md for more details.
The bindings can be generated using bindgen, special Rust crate.
bindgen usage is enabled via use-bindgen feature flag.
bindgen requires libclang, which should be installed first.
This library relies on LIBCLANG_PATH environment variable to determine path to the appropriate version of libclang.
The output folder for bindings can be configured using LIBRSYS_BINDINGS_OUTPUT_PATH environment variable, thus make sure it is set to e.g bindings.
-
Linux
Set
LIBCLANG_PATHto thelibdirectory of yourllvminstallation, e.g.,LIBCLANG_PATH=/usr/lib/llvm-3.9/lib. Build & test usingcargo build --features use-bindgen cargo test --features use-bindgen -
macOS
Install
llvm-configvia homebrew with:Add it to your search path via:
If you want to compile
libR-sysfrom within RStudio, you may also have to add the following line to your.Renvironfile:PATH=/usr/local/opt/llvm/bin:Build & test using
cargo build --features use-bindgen cargo test --features use-bindgen -
Windows Binding generation on Windows happens with the help of
MSYS2. Make sure the environment variableMSYS_ROOTpoints toMSYS2root, e.g.,C:\tools\msys64.Install
MSYS2. Here is an example usingchocolatey:choco install msys2 -ySet up
MSYS_ROOTenvironment variable. Installclangandmingw-toolchains (assumingPowerShellsyntax)&"$env:MSYS_ROOT\usr\bin\bash" -l -c "pacman -S --noconfirm mingw-w64-x86_64-clang mingw-w64-x86_64-toolchain"Add the following to the
PATH(usingPowerShellsyntax).# for R >= 4.3, this should be "C:\rtools43" $rtools_home = "C:\rtools42" $env:PATH = "${env:R_HOME}\bin\x64;${rtools_home}\usr\bin;${rtools_home}\x86_64-w64-mingw32.static.posix\bin;${env:MSYS_ROOT}\mingw64\bin;${env:PATH}"then build & test with
cargo build --target x86_64-pc-windows-gnu --features use-bindgen
Toolchain setup on Windows
The setup is tricky because the Rtools' toolchain is a bit different from the assumption of Rust.
Install the GNU target of Rust
Both the default MSVC toolchain and the GNU toolchain should work fine with libR-sys, but we recommend the MSVC toolchain because we mainly use it.
With either toolchain, since the R itself is built with the GNU toolchain, the target must be GNU. So, the GNU target needs to be installed.
rustup target add x86_64-pc-windows-gnu
Install Rtools42 (or Rtools43)
Rtools42 can be downloaded from here. For R >= 4.3, download
Rtools43 from here. Alternatively, Rtools will eventually
be available on chocolatey.
## TODO: Rtools42 is not yet on chocolatey
# choco install rtools -y
Setup R_HOME and PATH Environment Variables
First, ensure that R_HOME points to R home, e.g. C:\Program Files\R\R-4.2.0
(in an R session, this should be automatically set by R).
Second, ensure that PATH is properly configured that the following executables
are available:
- the
Rbinary to build against - the compiler toolchain that is used for compiling the R itself, i.e.,
Rtools
Typically, the following paths need to be added to the head of PATH (using
PowerShell syntax).
# for R >= 4.3, this should be "C:\rtools43"
$rtools_home = "C:\rtools42"
$env:PATH = "${env:R_HOME}\bin\x64;${rtools_home}\usr\bin;${rtools_home}\x86_64-w64-mingw32.static.posix\bin;${env:PATH}"
Note that the above prepends, rather than appends, because otherwise the wrong
toolchain might be accidentally chosen if the PATH already contains another
version of R or compiler toolchain.
Tweak the toolchain
As noted above, since the Rtools' toolchain is a bit different from the assumption of Rust, we need the following tweaks:
- Change the linker name to
x86_64-w64-mingw32.static.posix-gcc.exe. - Add empty
libgcc_s.aandlibgcc_eh.a, and add them to the compiler's library search paths viaLIBRARY_PATHenvironment variables.
The first tweak is needed because Rtools42 and Rtools43 don't contain
x86_64-w64-mingw32-gcc, which rustc uses as the default linker for the
x86_64-pc-windows-gnu target. This can be done by adding .cargo/config.toml
with the following lines on the root directory of the project:
[]
= "x86_64-w64-mingw32.static.posix-gcc.exe"
Alternatively, you can inject this configuration via the corresponding
environmental variable, CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER. See the
Cargo Book about how this works.
The second tweak is also required. rustc adds -lgcc_eh and -lgcc_s flags
to the compiler, but Rtools' GCC doesn't have libgcc_eh or libgcc_s due to
the compilation settings. So, in order to please the compiler, we need to add
empty libgcc_eh or libgcc_s to the library search paths. For more details,
please refer to r-windows/rtools-packages.
First, create a directory that contains empty libgcc_eh or libgcc_s.
# create a directory in an arbitrary location (e.g. libgcc_mock)
New-Item -Path libgcc_mock -Type Directory
# create empty libgcc_eh.a and libgcc_s.a
New-Item -Path libgcc_mock\libgcc_eh.a -Type File
New-Item -Path libgcc_mock\libgcc_s.a -Type File
Then, add the directory to LIBRARY_PATH environment variables. For example, this can be done
by adding the following lines to .cargo/config.toml:
[]
= "path/to/libgcc_mock"
Editor settings
Rust-analyzer might need some settings. For example, if you are using VS Code, you probably need to add the following options to .vscode/settings.json.