Bundle our own R 4.5.3 instead of building against Arch's R
Arch ships R 4.6.1, but JASP pins its R packages against a frozen CRAN snapshot (2026-03-31 for 0.98.1) that targets R 4.5. Configuring against Arch's R fails at Rcpp 1.1.1, which cannot compile on R 4.6 since R_NamespaceRegistry was removed; the Rcpp release that fixes it is newer than the pinned snapshot, so the lockfile cannot reach it either. Build R 4.5.3 into /opt/jasp-desktop/R and point R_HOME at it, matching what upstream CI does. This drops 'r' from depends entirely, so an Arch R upgrade can no longer break an installed JASP, and the rebuild triggers become Qt6 and ICU - the libraries actually still linked against.
This commit is contained in:
@@ -14,19 +14,30 @@ users download the result.
|
||||
|
||||
## The constraint that shapes everything
|
||||
|
||||
JASP does **not** bundle R or Qt6 on Linux. `Tools/CMake/R.cmake` only fetches
|
||||
`R.framework` on macOS; on Linux JASP links against the distribution's R and Qt6,
|
||||
and the R module library it ships is compiled against one specific R minor version.
|
||||
JASP pins its R package set with renv lockfiles against a **frozen CRAN snapshot**
|
||||
— for 0.98.1, `Modules/Rcpp_RInside.lock` points at the Posit snapshot of
|
||||
2026-03-31. That set targets R 4.5.
|
||||
|
||||
A binary is therefore only valid for the R minor and Qt6 minor it was built
|
||||
against. Two consequences:
|
||||
Building against Arch's current R (4.6.1) fails immediately: Rcpp 1.1.1 does not
|
||||
compile there, because `R_NamespaceRegistry` is gone in R 4.6. The Rcpp release
|
||||
that fixes this (1.1.2, 2026-07-05) is *newer than the pinned snapshot*, so the
|
||||
lockfile cannot resolve it either. This is precisely the "old libraries with
|
||||
issues" problem that makes the source AUR package painful.
|
||||
|
||||
1. A rebuild is triggered by a new JASP release **or** by Arch bumping `r` or
|
||||
`qt6-base`. `scripts/check-upstream.py` checks all three.
|
||||
2. The generated PKGBUILD pins `depends` to those versions
|
||||
(`r>=4.6 r<4.7`, `qt6-base>=6.11 qt6-base<6.12`). If Arch moves ahead before a
|
||||
rebuild lands, pacman refuses the combination rather than leaving users with a
|
||||
JASP that fails to start.
|
||||
So this build **compiles and bundles its own R 4.5.3** into
|
||||
`/opt/jasp-desktop/R` and points `R_HOME` at it — which is what upstream's own CI
|
||||
does (`.github/workflows/ubuntu.yml` sets `JASP_R_VERSION: 4.5.3` and an explicit
|
||||
`R_HOME`). `Tools/CMake/R.cmake` reads `R_HOME` from the environment on Linux, so
|
||||
this is a supported configuration rather than a hack.
|
||||
|
||||
Consequences:
|
||||
|
||||
1. `r` is **not** a dependency of the package. An Arch R upgrade cannot break an
|
||||
installed JASP.
|
||||
2. What the binary is still linked against is Qt6 and ICU, both of which break ABI
|
||||
across releases. The generated PKGBUILD pins those
|
||||
(`qt6-base>=6.11 <6.12`, `icu>=78 <79`), and `scripts/check-upstream.py`
|
||||
triggers a rebuild when Arch moves either — or when JASP releases.
|
||||
|
||||
`jags` and `librdata-git` are AUR-only, and JASP needs `freexl >= 2.0.99` while Arch
|
||||
ships 2.0.0 — so the build compiles those itself, matching what upstream CI does.
|
||||
@@ -36,7 +47,7 @@ ships 2.0.0 — so the build compiles those itself, matching what upstream CI do
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| `build/build-jasp.sh` | The actual build. Runs in an `archlinux:base-devel` container, emits the tarball plus `build-info.json`. |
|
||||
| `scripts/check-upstream.py` | Compares upstream JASP / Arch R / Arch Qt6 against `state.json`; decides whether to build. |
|
||||
| `scripts/check-upstream.py` | Compares upstream JASP / Arch Qt6 / Arch ICU against `state.json`; decides whether to build. |
|
||||
| `scripts/gen-pkgbuild.py` | Fills `packaging/PKGBUILD.in` from `build-info.json`; derives `pkgrel` from what is on the AUR. |
|
||||
| `scripts/publish-github-release.sh` | Creates the GitHub release and uploads the tarball. |
|
||||
| `scripts/push-aur.sh` | Generates `.SRCINFO` and pushes to `aur.archlinux.org`. |
|
||||
@@ -48,9 +59,10 @@ ships 2.0.0 — so the build compiles those itself, matching what upstream CI do
|
||||
|
||||
```
|
||||
nightly (03:00) ─► check-upstream.py
|
||||
│ new JASP tag, or Arch bumped r / qt6-base?
|
||||
│ new JASP tag, or Arch bumped qt6-base / icu?
|
||||
▼
|
||||
build-jasp.sh (Arch container, hours)
|
||||
│ builds R 4.5.3, JASP, then all R modules
|
||||
│ jasp-desktop-<ver>-x86_64.tar.zst + build-info.json
|
||||
▼
|
||||
GitHub release ──► gen-pkgbuild.py ──► push to AUR
|
||||
@@ -90,7 +102,8 @@ The build runs for hours and needs disk. On the Gitea runner host:
|
||||
time (set to `16h`).
|
||||
- Gitea's own job timeout (`[actions] ENDLESS_TASK_TIMEOUT` in `app.ini`, default
|
||||
3h) must match, otherwise Gitea kills the job at 3h regardless of the runner.
|
||||
- Roughly 40–60 GB of free disk for the build tree and staged install.
|
||||
- Roughly 40–60 GB of free disk for the build tree, the bundled R and the
|
||||
staged install.
|
||||
|
||||
## Running it by hand
|
||||
|
||||
|
||||
Reference in New Issue
Block a user