--- title: "Distributing a package that uses RZig" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Distributing a package that uses RZig} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(rzig) ``` A package that uses RZig is a source package with compiled code: whoever installs it from source needs R's build tools and a Zig compiler of the supported series (0.16 or 0.17). rzig itself is pure R and needs no compiler. This vignette describes what a package states about Zig, how users obtain the compiler, and the channels through which such a package reaches its users. The code is plain R. ## What the package states `create_rzig_package()` and `use_rzig()` write the field that names the compiler, and `rzig_status()` notes a `DESCRIPTION` without it: ```{r fields} path <- file.path(tempdir(), "distpkg") create_rzig_package(path, tests = FALSE) read.dcf(file.path(path, "DESCRIPTION"), fields = "SystemRequirements") ``` `configure` reports the compiler it uses in the installation log and rejects other versions with a message that names the version it found, and the Zig build uses at most two jobs, as CRAN's policy for compiled code asks. ## How users get Zig `find_zig()` reports the compiler that an installation would use. A user without one installs a verified release with `install_zig()`, which asks for permission, downloads the archive of a pinned release, checks its SHA-256 checksum and keeps it in the user cache folder of rzig, where `configure` finds it: ```{r find} find_zig(required = FALSE) ``` Alternatives are a download from , with the compiler on `PATH` or named by `ZIG`, or `RZIG_DOWNLOAD_ZIG=true` in the environment of the installation, with which `configure` downloads and checks the same pinned release itself when it finds no compiler. ## GitHub and r-universe `remotes::install_github()` and `pak::pak()` build the package from source on the user's machine, so the user needs Zig as above. r-universe builds binary packages for Windows and macOS on its own machines, which have no Zig; a package for r-universe or GitHub can ask `configure` to download the pinned release into its build folder when no compiler is found: ```{r download} cat("Config/rzig/download-zig: true\n", file = file.path(path, "DESCRIPTION"), append = TRUE) status <- rzig_status(path) status[status$step == "DESCRIPTION", ] ``` The download goes to `src/rzig/.zig-download`, which the build excludes from the package and `cleanup` removes. Users of binary packages need no compiler at all. ## CRAN CRAN's build machines have no Zig compiler, and CRAN's policy forbids downloading a compiler during the installation without the agreement of the CRAN team, so `Config/rzig/download-zig` is not for packages on CRAN. A package for CRAN states Zig in `SystemRequirements`, as packages with Rust code state Cargo; whether CRAN builds such packages depends on CRAN providing the compiler. rzig itself is on CRAN because its checks compile no Zig code. ## Continuous integration `use_rzig_ci()` writes a GitHub Actions workflow that installs Zig 0.16 and 0.17 and runs `R CMD check` with the settings that CRAN applies to compiled code on Linux, macOS and Windows: ```{r ci} use_rzig_ci(path) file.exists(file.path(path, ".github", "workflows", "rzig-check.yaml")) ``` ```{r cleanup, include = FALSE} unlink(path, recursive = TRUE) ```