├── .Rbuildignore
├── .github
├── .gitignore
└── workflows
│ └── R-CMD-check.yaml
├── .gitignore
├── DESCRIPTION
├── LICENSE
├── NAMESPACE
├── NEWS
├── R
└── hello.R
├── README.md
├── cleanup
├── cleanup.win
├── configure
├── configure.ucrt
├── hellorust.Rproj
├── man
└── hellorust.Rd
├── src
├── Makevars
├── Makevars.win
├── myrustlib
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── api.h
│ ├── src
│ │ ├── hello.rs
│ │ ├── lib.rs
│ │ ├── mythreads.rs
│ │ └── random.rs
│ ├── vendor-authors.R
│ ├── vendor-config.toml
│ └── vendor-update.sh
└── wrapper.c
└── tools
└── rustarch.R
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^src/myrustlib/target
4 | ^src/myrustlib/vendor/
5 | \.lock$
6 | \.rs\.bk$
7 | ^README.md$
8 | ^.travis.yml$
9 | ^appveyor.yml$
10 | ^\.github$
11 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/workflows/R-CMD-check.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | pull_request:
6 |
7 | name: R-CMD-check
8 |
9 | jobs:
10 | R-CMD-check:
11 | runs-on: ${{ matrix.config.os }}
12 |
13 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
14 |
15 | strategy:
16 | fail-fast: false
17 | matrix:
18 | config:
19 | - { os: macos-latest, r: 'release' }
20 | - { os: macos-15, r: 'next' }
21 | - { os: windows-latest, r: 'release' }
22 | - { os: windows-latest, r: 'devel' }
23 | - { os: ubuntu-latest, r: 'devel', http-user-agent: 'release' }
24 | - { os: ubuntu-latest, r: 'release' }
25 | - { os: ubuntu-latest, r: 'oldrel-1' }
26 | - { os: ubuntu-24.04-arm, r: 'release' }
27 |
28 | env:
29 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
30 | R_KEEP_PKG_SOURCE: yes
31 |
32 | steps:
33 | - name: Add more rust targets
34 | if: runner.os == 'windows'
35 | run: rustup target add x86_64-pc-windows-gnu
36 |
37 | - uses: actions/checkout@v3
38 |
39 | - uses: r-lib/actions/setup-pandoc@v2
40 |
41 | - uses: r-lib/actions/setup-r@v2
42 | with:
43 | r-version: ${{ matrix.config.r }}
44 | http-user-agent: ${{ matrix.config.http-user-agent }}
45 | use-public-rspm: true
46 |
47 | - uses: r-lib/actions/setup-r-dependencies@v2
48 | with:
49 | extra-packages: any::rcmdcheck
50 | needs: check
51 |
52 | - uses: r-lib/actions/check-r-package@v2
53 | with:
54 | upload-snapshots: true
55 | env:
56 | MAKEFLAGS: -j4
57 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | src/*.o
5 | src/*.so
6 | src/*.dll
7 | src/*.a
8 | src/myrustlib/target/*
9 | src/myrustlib/vendor.tar.xz
10 | src/myrustlib/vendor/*
11 | inst/AUTHORS
12 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: hellorust
2 | Type: Package
3 | Title: Minimal Examples of Using Rust Code in R
4 | Version: 1.2.3
5 | Authors@R: c(person("Jeroen", "Ooms", role = c("aut", "cre"), email = "jeroenooms@gmail.com",
6 | comment = c(ORCID = "0000-0002-4035-0289")),
7 | person("Authors of the dependency Rust crates", role = "aut", comment = "see AUTHORS file"))
8 | Description: Template R package with minimal setup to use Rust code in R without
9 | hacks or frameworks. Includes basic examples of importing cargo dependencies,
10 | spawning threads and passing numbers or strings from Rust to R. Cargo crates
11 | are automatically 'vendored' in the R source package to support offline
12 | installation. The GitHub repository for this package has more details and also
13 | explains how to set up CI. This project was first presented at 'Erum2018' to
14 | showcase R-Rust integration ; for a real
15 | world use-case, see the 'gifski' package on 'CRAN'.
16 | License: MIT + file LICENSE
17 | URL: https://github.com/r-rust/hellorust
18 | BugReports: https://github.com/r-rust/hellorust/issues
19 | SystemRequirements: Cargo (Rust's package manager), rustc
20 | Encoding: UTF-8
21 | RoxygenNote: 7.2.1
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2022
2 | COPYRIGHT HOLDER: Jeroen Ooms
3 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(hello)
4 | export(random)
5 | export(runthreads)
6 | useDynLib(hellorust,hello_wrapper)
7 | useDynLib(hellorust,random_wrapper)
8 | useDynLib(hellorust,threads_wapper)
9 |
--------------------------------------------------------------------------------
/NEWS:
--------------------------------------------------------------------------------
1 | 1.2.3
2 | - Fix parallel make; more cleanup after build
3 |
4 | 1.2.2
5 | - Fix commented out CARGO_HOME in Makevars
6 |
7 | 1.2.1
8 | - Print rustc --version in configure as per CRAN request
9 | - Update maintainer email address
10 |
11 | 1.2.0
12 | - Windows: support aarch64-pc-windows-gnullvm
13 |
14 | 1.1.1
15 | - CRAN request: use role="aut" for rust dependencies
16 | - CRAN request: use -j2 instead of CARGO_BUILD_JOBS=2
17 |
18 | 1.1.0
19 | - Vendor cargo sources to comply with new CRAN guidlines
20 |
21 | 1.0.2
22 | - Windows: add -lntdll to PKG_LIBS as needed by Rust 1.70 and up
23 |
--------------------------------------------------------------------------------
/R/hello.R:
--------------------------------------------------------------------------------
1 | #' Hello Rust!
2 | #'
3 | #' Minimal examples of calling rust functions in R via C.
4 | #'
5 | #' These functions call out to rust functions defined in the `myrustlib` cargo
6 | #' crate which is embedded in this package. They return values generated in Rust,
7 | #' such as a UTF-8 string or random number. In addition, `runthreads` is an
8 | #' example of a multi-threaded rust function.
9 | #'
10 | #' @export
11 | #' @rdname hellorust
12 | #' @examples hello()
13 | #' @return a value generated in Rust (a string, random number, and NULL respectively).
14 | #' @useDynLib hellorust hello_wrapper
15 | hello <- function() {
16 | .Call(hello_wrapper)
17 | }
18 |
19 | #' @export
20 | #' @rdname hellorust
21 | #' @examples random()
22 | #' @useDynLib hellorust random_wrapper
23 | random <- function(){
24 | .Call(random_wrapper)
25 | }
26 |
27 | #' @export
28 | #' @rdname hellorust
29 | #' @examples runthreads()
30 | #' @useDynLib hellorust threads_wapper
31 | runthreads <- function(){
32 | .Call(threads_wapper)
33 | invisible()
34 | }
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Hello Rust
2 |
3 | [](https://github.com/r-rust/hellorust/actions?workflow=R-CMD-check)
4 |
5 | > Minimal Examples of Using Rust Code in R
6 |
7 | 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](https://github.com/r-rust) organization contains several more simple R packages interfacing with cargo crates.
8 |
9 | To learn more about using Rust code in R packages, also have a look at the [r-rust FAQ](https://github.com/r-rust/faq) and the [slides](https://jeroen.github.io/erum2018/) about this project presented at eRum2018!
10 |
11 | ## Package Structure
12 |
13 | Bundle your rust code in a the embedded cargo package (see the `Cargo.toml` file) and then the [src/Makevars](src/Makevars) file is written such that R will automatically build the rust modules when the R package is installed.
14 |
15 | ```
16 | hellorust
17 | ├─ configure ← checks if 'cargo' is installed
18 | ├─ src
19 | │ ├─ myrustlib ← bundled cargo package with your code
20 | │ | ├─ Cargo.toml ← cargo dependencies and metadata
21 | │ | ├─ src ← rust source code
22 | │ | └─ api.h ← C headers for exported rust API
23 | | |
24 | │ ├─ Makevars ← Ties everything together
25 | │ └─ wrapper.c ← C code for R package
26 | ├─ DESCRIPTION
27 | └─ R ← Standard R+C stuff
28 | ```
29 |
30 | ## Vendoring
31 |
32 | As per the new [2023 cran guidelines](https://cran.r-project.org/web/packages/using_rust.html) 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:
33 |
34 | 1. (by package author) The [vendor-update.sh](src/myrustlib/vendor-update.sh) script creates the `vendor.tar.xz` bundle that contains all the cargo sources. In addition, the [vendor-authors.R](src/myrustlib/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](cleanup) file and therefore run automatically during `R CMD build` when the source package is created.
35 | 2. (by the user) At install time, the [Makevars](src/Makevars) extracts the `vendor.tar.xz` bundle (when available) and generates a `.cargo/config.toml` file to instruct `cargo build` to use the vendored (offline) sources.
36 |
37 | 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.
38 |
39 | You can test or force the use of vendored sources by passing `--offline` to `cargo build`.
40 |
41 | ## Installing this package
42 |
43 | If Rust is available, clone this repository and run the regular `R CMD INSTALL` command:
44 |
45 | ```
46 | R CMD INSTALL hellorust
47 | ```
48 |
49 | Alternatively, to download and install from within R itself:
50 |
51 | ```r
52 | # install.packages("remotes")
53 | remotes::install_github("r-rust/hellorust")
54 | ```
55 |
56 | ## What is Cargo
57 |
58 | The standard rust toolchain includes a great package manager `cargo` with a corresponding registry [crates.io](https://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.
59 |
60 | 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.
61 |
62 | ## Installing Rust on Linux / MacOS
63 |
64 | 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
65 |
66 | Alternatively, you may install cargo from your OS package manager:
67 |
68 | - Debian/Ubuntu: `sudo apt-get install cargo`
69 | - Fedora/CentOS*: `sudo yum install cargo`
70 | - MacOS: `brew install rustc`
71 |
72 | *Note that on CentOS you first need to enable EPEL via `sudo yum install epel-release`.
73 |
74 | ## Installing Rust for R on Windows
75 |
76 | 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](https://win.rustup.rs/) and then install the default toolchain:
77 |
78 | ```
79 | rustup-init.exe -y --default-host x86_64-pc-windows-gnu
80 | ```
81 |
82 | Or if rust is already installed (for example on GitHub actions), you can simply add the target:
83 |
84 | ```
85 | rustup target add x86_64-pc-windows-gnu
86 | ```
87 |
88 | To compile 32bit packages also add the `i686-pc-windows-gnu` target, but 32-bit is no longer supported as of R 4.2.
89 |
90 | ## GitHub Actions
91 |
92 | __Update 2023:__ This step is no longer needed because GitHub action runners now have the required Rust targets preinstalled by default.
93 |
94 | To use GitHub actions, you can use the [standard r workflow](https://github.com/r-lib/actions/blob/HEAD/.github/workflows/check-standard.yaml) script in combination with this extra step:
95 |
96 | ```
97 | - name: Add Rtools targets to Rust
98 | if: runner.os == 'Windows'
99 | run: |
100 | rustup target add i686-pc-windows-gnu
101 | rustup target add x86_64-pc-windows-gnu
102 | ```
103 |
104 | ## In the real world
105 |
106 | The [gifski](https://cran.r-project.org/web/packages/gifski/index.html) package has been on CRAN since 2018, and uses this same structure.
107 |
108 | ## More Resources
109 | - [r-rust FAQ](https://github.com/r-rust/faq)
110 | - Erum2018 [slides](https://jeroen.github.io/erum2018/) about this project presented by Jeroen
111 | - [Rust Inside Other Languages](https://doc.rust-lang.org/1.6.0/book/rust-inside-other-languages.html) chapter from official rust documentation
112 | - [extendr](https://github.com/extendr): a more advanced R extension interface using Rust
113 | - Duncan's proof of concept: [RCallRust](https://github.com/duncantl/RCallRust)
114 |
--------------------------------------------------------------------------------
/cleanup:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export PATH="$HOME/.cargo/bin:$PATH"
3 | cd src/myrustlib
4 | ./vendor-update.sh
5 |
6 | # Update ../inst/AUTHORS
7 | ${R_HOME}/bin/Rscript vendor-authors.R
8 |
--------------------------------------------------------------------------------
/cleanup.win:
--------------------------------------------------------------------------------
1 | cleanup
--------------------------------------------------------------------------------
/configure:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export PATH="$PATH:$HOME/.cargo/bin"
3 | if [ $(command -v cargo) ]; then
4 | cargo --version
5 | rustc --version || true
6 | else
7 | echo "----------------------- [RUST NOT FOUND]---------------------------"
8 | echo "The 'cargo' command was not found on the PATH. Please install rustc"
9 | echo "from: https://www.rust-lang.org/tools/install"
10 | echo ""
11 | echo "Alternatively, you may install cargo from your OS package manager:"
12 | echo " - Debian/Ubuntu: sudo apt-get install cargo"
13 | echo " - Fedora/CentOS: sudo yum install cargo"
14 | echo " - MacOS: brew install rustc"
15 | echo "-------------------------------------------------------------------"
16 | echo ""
17 | exit 1
18 | fi
19 | exit 0
20 |
--------------------------------------------------------------------------------
/configure.ucrt:
--------------------------------------------------------------------------------
1 | configure
--------------------------------------------------------------------------------
/hellorust.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 | ProjectId: 96528bc3-6344-4293-93e2-82a0487b38a2
3 |
4 | RestoreWorkspace: Default
5 | SaveWorkspace: Default
6 | AlwaysSaveHistory: Default
7 |
8 | EnableCodeIndexing: Yes
9 | UseSpacesForTab: Yes
10 | NumSpacesForTab: 2
11 | Encoding: UTF-8
12 |
13 | RnwWeave: Sweave
14 | LaTeX: pdfLaTeX
15 |
16 | AutoAppendNewline: Yes
17 | StripTrailingWhitespace: Yes
18 |
19 | BuildType: Package
20 | PackageUseDevtools: Yes
21 | PackageInstallArgs: --no-multiarch --with-keep.source
22 |
--------------------------------------------------------------------------------
/man/hellorust.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/hello.R
3 | \name{hello}
4 | \alias{hello}
5 | \alias{random}
6 | \alias{runthreads}
7 | \title{Hello Rust!}
8 | \usage{
9 | hello()
10 |
11 | random()
12 |
13 | runthreads()
14 | }
15 | \value{
16 | a value generated in Rust (a string, random number, and NULL respectively).
17 | }
18 | \description{
19 | Minimal examples of calling rust functions in R via C.
20 | }
21 | \details{
22 | These functions call out to rust functions defined in the `myrustlib` cargo
23 | crate which is embedded in this package. They return values generated in Rust,
24 | such as a UTF-8 string or random number. In addition, `runthreads` is an
25 | example of a multi-threaded rust function.
26 | }
27 | \examples{
28 | hello()
29 | random()
30 | runthreads()
31 | }
32 |
--------------------------------------------------------------------------------
/src/Makevars:
--------------------------------------------------------------------------------
1 | LIBDIR = myrustlib/target/release
2 | STATLIB = $(LIBDIR)/libmyrustlib.a
3 | PKG_CFLAGS = -pthread
4 | PKG_CPPFLAGS = -DSTRICT_R_HEADERS -DR_NO_REMAP
5 | PKG_LIBS = -L$(LIBDIR) -lmyrustlib -lresolv -pthread
6 |
7 | all: cleanup
8 |
9 | $(SHLIB): $(STATLIB)
10 |
11 | # CRAN policy forbids using $HOME so we build in the current working dir and
12 | # never use local cache. Also CRAN does not allow using more than 2 CPUs.
13 | # This makes things really slow because we have to reinstall all dependencies.
14 | # You can comment these things out if you do not submit to CRAN.
15 | CRANFLAGS=-j 2
16 | CARGOTMP=$(PWD)/.cargo
17 | export CARGO_HOME=$(CARGOTMP)
18 |
19 | $(STATLIB):
20 | if [ -f myrustlib/vendor.tar.xz ]; then tar xf myrustlib/vendor.tar.xz && mkdir -p $(CARGOTMP) && cp myrustlib/vendor-config.toml $(CARGOTMP)/config.toml; fi
21 | PATH="${PATH}:${HOME}/.cargo/bin" cargo build ${CRANFLAGS} --release --manifest-path=myrustlib/Cargo.toml
22 | @$(STRIP_STATIC_LIB) $(STATLIB) || true
23 | @rm -Rf $(CARGOTMP) vendor || true # CRAN wants us to remove "detritus"
24 | @rm -Rf $(LIBDIR)/build || true
25 |
26 | cleanup: $(SHLIB)
27 | @rm -Rf $(STATLIB) myrustlib/target
28 |
--------------------------------------------------------------------------------
/src/Makevars.win:
--------------------------------------------------------------------------------
1 | TARGET = $(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript.exe" "../tools/rustarch.R")
2 | LIBDIR = myrustlib/target/$(TARGET)/release
3 | STATLIB = $(LIBDIR)/libmyrustlib.a
4 | PKG_CPPFLAGS = -DSTRICT_R_HEADERS -DR_NO_REMAP
5 | PKG_LIBS = -L$(LIBDIR) -lmyrustlib -lws2_32 -ladvapi32 -lgdi32 -lbcrypt -lcrypt32 -luserenv -lntdll
6 |
7 | all: cleanup
8 |
9 | $(SHLIB): $(STATLIB)
10 |
11 | $(STATLIB):
12 | if [ -f myrustlib/vendor.tar.xz ]; then tar xf myrustlib/vendor.tar.xz && mkdir -p .cargo && cp myrustlib/vendor-config.toml .cargo/config.toml; fi
13 | PATH="$(USERPROFILE)\.cargo\bin:$(PATH)" cargo build --target=$(TARGET) --release --manifest-path=myrustlib/Cargo.toml
14 |
15 | cleanup: $(SHLIB)
16 | @rm -Rf $(STATLIB) myrustlib/target
17 |
--------------------------------------------------------------------------------
/src/myrustlib/.gitignore:
--------------------------------------------------------------------------------
1 | x
2 | **/*.rs.bk
3 | Cargo.lock
4 |
--------------------------------------------------------------------------------
/src/myrustlib/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "myrustlib"
3 | version = "0.1.0"
4 | authors = ["Jeroen "]
5 |
6 | [lib]
7 | crate-type = ["staticlib"]
8 |
9 | [dependencies]
10 | rand = "0.4.1"
11 | libc = "*"
12 |
--------------------------------------------------------------------------------
/src/myrustlib/api.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #ifdef __cplusplus
4 | extern "C" {
5 | #endif
6 |
7 | char * string_from_rust(void);
8 | void free_string_from_rust(char*);
9 | int32_t random_number(void);
10 | void run_threads(void);
11 |
12 | #ifdef __cplusplus
13 | }
14 | #endif
15 |
--------------------------------------------------------------------------------
/src/myrustlib/src/hello.rs:
--------------------------------------------------------------------------------
1 | use std::ffi::CString;
2 | use std::os::raw::c_char;
3 |
4 | #[no_mangle]
5 | pub extern "C" fn string_from_rust() -> *const c_char {
6 | let s = CString::new("Hello ピカチュウ !").unwrap();
7 | s.into_raw()
8 | }
9 |
10 | #[no_mangle]
11 | pub extern "C" fn free_string_from_rust(ptr: *mut c_char) {
12 | let _ = unsafe { CString::from_raw(ptr) };
13 | }
14 |
--------------------------------------------------------------------------------
/src/myrustlib/src/lib.rs:
--------------------------------------------------------------------------------
1 | // Import dependencies
2 | extern crate libc;
3 | extern crate rand;
4 |
5 | // Modules are other .rs source files
6 | mod hello;
7 | mod random;
8 | mod mythreads;
9 |
10 | // Export functions called by R
11 | pub use hello::string_from_rust;
12 | pub use random::random_number;
13 | pub use mythreads::run_threads;
14 |
--------------------------------------------------------------------------------
/src/myrustlib/src/mythreads.rs:
--------------------------------------------------------------------------------
1 | use std::thread;
2 | use std::time::Duration;
3 |
4 | #[no_mangle]
5 | pub extern fn run_threads() {
6 | thread::spawn(|| {
7 | for i in 1..10 {
8 | println!("hi number {} from the spawned thread!", i);
9 | thread::sleep(Duration::from_millis(1));
10 | }
11 | });
12 |
13 | for i in 1..5 {
14 | println!("hi number {} from the main thread!", i);
15 | thread::sleep(Duration::from_millis(1));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/myrustlib/src/random.rs:
--------------------------------------------------------------------------------
1 | use rand::random;
2 |
3 | #[no_mangle]
4 | pub extern fn random_number() -> i32 {
5 | let tuple = random::();
6 | tuple
7 | }
8 |
--------------------------------------------------------------------------------
/src/myrustlib/vendor-authors.R:
--------------------------------------------------------------------------------
1 | if(!require('jsonlite')) install.packages('jsonlite', repos = 'https://cloud.r-project.org')
2 | metadata <- jsonlite::fromJSON(pipe("cargo metadata --format-version 1"))
3 | packages <- metadata$packages
4 | stopifnot(is.data.frame(packages))
5 | packages <- subset(packages, sapply(packages$authors, length) > 0 & name != 'myrustlib')
6 | authors <- vapply(packages$authors, function(x) paste(sub(" <.*>", "", x), collapse = ', '), character(1))
7 | lines <- sprintf(" - %s %s: %s", packages$name, packages$version, authors)
8 | dir.create('../../inst', showWarnings = FALSE)
9 | footer <- sprintf("\n(This file was auto-generated from 'cargo metadata' on %s)", Sys.Date())
10 | writeLines(c('Authors of vendored cargo crates', lines, footer), '../../inst/AUTHORS')
11 |
--------------------------------------------------------------------------------
/src/myrustlib/vendor-config.toml:
--------------------------------------------------------------------------------
1 | [source.crates-io]
2 | replace-with = "vendored-sources"
3 |
4 | [source.vendored-sources]
5 | directory = "vendor"
6 |
7 |
--------------------------------------------------------------------------------
/src/myrustlib/vendor-update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | rm -Rf vendor vendor.tar.xz
3 | cargo vendor
4 | tar -cJ --no-xattrs -f vendor.tar.xz vendor
5 | rm -Rf vendor
6 |
7 |
--------------------------------------------------------------------------------
/src/wrapper.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | // Import C headers for rust API
4 | #include "myrustlib/api.h"
5 |
6 | // Actual Wrappers
7 | SEXP hello_wrapper(void){
8 | char* hello_rust = string_from_rust();
9 | SEXP hello_world_string = PROTECT(Rf_mkCharCE(hello_rust, CE_UTF8));
10 | free_string_from_rust(hello_rust);
11 | UNPROTECT(1);
12 | return Rf_ScalarString(hello_world_string);
13 | }
14 |
15 | SEXP random_wrapper(void){
16 | return Rf_ScalarInteger(random_number());
17 | }
18 |
19 | SEXP threads_wapper(void){
20 | run_threads();
21 | return R_NilValue;
22 | }
23 |
24 | // Standard R package stuff
25 | static const R_CallMethodDef CallEntries[] = {
26 | {"hello_wrapper", (DL_FUNC) &hello_wrapper, 0},
27 | {"random_wrapper", (DL_FUNC) &random_wrapper, 0},
28 | {"threads_wapper", (DL_FUNC) &threads_wapper, 0},
29 | {NULL, NULL, 0}
30 | };
31 |
32 | void R_init_hellorust(DllInfo *dll) {
33 | R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
34 | R_useDynamicSymbols(dll, FALSE);
35 | }
36 |
--------------------------------------------------------------------------------
/tools/rustarch.R:
--------------------------------------------------------------------------------
1 | # See notes in FAQ about ARM64 support:
2 | # https://github.com/r-rust/faq#does-rust-support-windows-on-arm64-aarch64
3 | arch <- if(grepl("aarch", R.version$platform)){
4 | "aarch64-pc-windows-gnullvm"
5 | } else if(grepl("clang", Sys.getenv('R_COMPILED_BY'))){
6 | "x86_64-pc-windows-gnullvm"
7 | } else if(grepl("i386", R.version$platform)){
8 | "i686-pc-windows-gnu"
9 | } else {
10 | "x86_64-pc-windows-gnu"
11 | }
12 |
13 | cat(arch)
14 |
--------------------------------------------------------------------------------