Skip to content

Commit c6fe360

Browse files
authored
Merge pull request #79 from kbvernon/update-freeze
update freeze files
2 parents f27d7d7 + 4adc626 commit c6fe360

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

  • _freeze/contributing
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"hash": "125b0874f1c9139fd9b376ef08f2fb49",
3+
"result": {
4+
"engine": "knitr",
5+
"markdown": "---\ntitle: \"{extendr} Internals\"\nengine: knitr\n---\n\n::: {.callout-note}\n[Coming soon!]{.fs-1 .fw-bold}\n:::",
6+
"supporting": [],
7+
"filters": [
8+
"rmarkdown/pagebreak.lua"
9+
],
10+
"includes": {},
11+
"engineDependencies": {},
12+
"preserve": {},
13+
"postProcess": true
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"hash": "e674867d1d95f4da2dd5b9f31f9d69cf",
3+
"result": {
4+
"engine": "knitr",
5+
"markdown": "---\ntitle: \"{rextendr} Internals\"\n---\n\nThis page describes various internal functions and processes used by rextendr to\nsetup and build R packages. It is designed to get contributors up-to-speed on \nthe internal mechanics of rextendr, so that they can more efficiently contribute\nto development and maintenance.\n\n## Package Setup\n\nGeneral R package setup is achieved with `usethis::create_package()`. \nScaffolding files required to call Rust code in R using extendr is then added to \nthe package directory with `rextendr::use_extendr()`. This involves \ninterpolating strings into template files in `inst/templates/`, which are then \nwritten to the user's package directory via the internal function \n`use_rextendr_template()`:\n\n```{.r filename=\"R/use_extendr.R\"}\nuse_rextendr_template <- function(\n template, # filename in inst/templates/\n save_as, # destination path in the user's package\n data = list(), # named list of variables to interpolate into the template\n quiet = FALSE,\n overwrite = NULL\n)\n```\n\nWhen `usethis` is available and `overwrite = NULL`, this delegates to\n`usethis::use_template()`, which handles interactive prompting if the file\nalready exists. Otherwise it reads the template file directly, performs\ninterpolation, and writes the result. The templates directory currently includes \nall of the following:\n\n\n::: {.cell}\n\n```{.r .cell-code}\nfs::dir_tree(system.file(\"templates\", package = \"rextendr\"))\n#> C:/Users/kenne/AppData/Local/R/win-library/4.5/rextendr/templates\n#> ├── Cargo.toml\n#> ├── cleanup\n#> ├── cleanup.win\n#> ├── config.R\n#> ├── configure\n#> ├── configure.win\n#> ├── document.rs\n#> ├── entrypoint.c\n#> ├── extendr-wrappers.R\n#> ├── lib.rs\n#> ├── Makevars.in\n#> ├── Makevars.win.in\n#> ├── msrv.R\n#> ├── settings.json\n#> ├── win.def\n#> └── _gitignore\n```\n:::\n\n\nThe exceptions to simple string interpolation are `Cargo.toml`, whose content is \ngenerated programmatically before being written to file, and `Makevars.in` / \n`Makevars.win.in`, which use a second layer of `@PLACEHOLDER@` substitution \nperformed at package build time by `tools/config.R`.\n\nYou can see the content of these template files on main in the rextendr \nrepository here: {{< iconify bi:github >}} \n[source](https://github.com/extendr/rextendr/tree/main/inst/templates). \nFor a description of what each generated file does, see the \n[Project Structure](../user-guide/package-structure.qmd) page in the user guide.\n\n## Package Build\n\nWhen a developer calls `devtools::document()`, they initiate a set of steps to\nbuild, document, and register functions in their R package. Here are those steps \nin order:\n\n1. Check Rust and cargo versions\n2. Generate `Makevars` from template\n3. Compile the Rust crate into a static library\n4. Generate R wrappers\n5. Compile `entrypoint.c` and link the static library\n6. Register exported routines with R on load\n7. Clean up build artifacts\n\nThese steps are driven by `R CMD INSTALL`, which `devtools::document()` calls \nimplicitly.\n\n### Setup\n\nThe first thing that gets called is `configure` (`configure.win` on Windows). \nThe sole purpose of the configure script is to source the R script \n`tools/config.R`, which in broad outline does two things. First, it runs\n`tools/msrv.R` to check that the Rust version is consistent across metadata \nfiles like `DESCRIPTION` and `Cargo.toml` (step 1). Second, it substitutes \n`@PLACEHOLDER@` variables in the `Makevars.in` and `Makevars.win.in` templates \n(signaled by `.in`) with relevant data to generate the actual Makevars file \n(step 2). \n\n### Build\n\nThe R package build process next invokes Makevars, which was just generated by \nthe configuration file. The Makevars in turn does two things. First, it calls\n`cargo build` to compile the static library (step 3). Then it calls `cargo run` \nto compile and execute the associated `document` binary, which generates all \nextendr wrappers (basically `.Call()`) and writes them into \n`R/extendr-wrappers.R` (step 4). Note that if a `vendor/` directory or \n`rust/vendor.tar.xz` tarball is present, the Makevars also ensures that Cargo is \nconfigured to use it for offline compilation — this is the essential mechanism \nrequired for CRAN submissions. \n\n### Registration\n\nBecause we are building an R package with compiled code, R requires that we \nregister all routines via a C-level initialization function named \n`R_init_<pkgname>`. This is where `entrypoint.c` comes in. Currently, extendr \ngenerates its own version of this function — `R_init_{{{mod_name}}}_extendr` — \ninside the Rust library. The C entrypoint then bridges the two, calling the \nRust-generated function through the R-facing `R_init_{{{mod_name}}}`. Compiling\n`entrypoint.c` makes that symbol available on package load (step 5). When the \npackage next gets loaded, the C function is called to register compiled routines \n(step 6). If you inspect `R/extendr-wrappers.R`, you will see where this \nhappens. The call is `@useDynLib(pkgname, .registration = TRUE)`.\n\n### Cleanup\n\nTo prevent the `Makevars` generated by `configure` from being committed to git, \na `cleanup` is invoked (`cleanup.win` on Windows) that calls the shell command \n`rm` to remove that file (step 7).\n\nOnce these steps are taken, the compiled Rust should become available in the \ncurrent R session.\n",
6+
"supporting": [],
7+
"filters": [
8+
"rmarkdown/pagebreak.lua"
9+
],
10+
"includes": {},
11+
"engineDependencies": {},
12+
"preserve": {},
13+
"postProcess": true
14+
}
15+
}

0 commit comments

Comments
 (0)