Files
wickra/bindings/r/configure.win
T
kingchenc 5b7523265c Make the R binding self-contained (fetch the C ABI at install time) (#235)
## Problem
The R package built **only** inside the dev/CI workspace. `src/Makevars` and `configure.win` hard-required `WICKRA_INCLUDE_DIR` / `WICKRA_LIB_DIR` pointing at a pre-built `libwickra` (`configure.win` literally `: "${WICKRA_LIB_DIR:?...}"`), and there was no Unix `configure`. So **r-universe** and any plain `install.packages` / `install_github` failed — R had no working end-user install path.

## Fix
Fetch the prebuilt `wickra-c-<triple>.tar.gz` release asset matching the package version at install time and bundle the library into the package (same outcome as the C# / Java bindings, which bundle per-platform native libs):

- **New POSIX `configure`** (the Unix hook R lacked): detect OS/arch → triple, download + `untar` via **base R** (no curl/wget system dep), stage `wickra.h` + `libwickra.{so,dylib}` into `src/`, generate `src/Makevars` from `Makevars.in` with an rpath (`$ORIGIN` Linux, `@loader_path` + `install_name_tool` macOS) so the bundled lib resolves post-install.
- **`configure.win`**: drop the hard `WICKRA_LIB_DIR` requirement; download the Windows triple when unset, then keep the existing `wickra_abi.dll` rename + `objdump`/`dlltool` import-lib dance (sourcing the dll/header from the asset).
- **`install.libs.R`** also bundles `libwickra.dylib` (macOS); the `*.so`/`*.dll` globs already covered Linux/Windows.
- `WICKRA_INCLUDE_DIR`/`WICKRA_LIB_DIR` stay as an optional **dev override**.
- **CI (3 OS)** keeps building against the locally built C ABI (version-independent — avoids the chicken-egg of downloading the in-flight version) but **no longer exports `LD_LIBRARY_PATH`/`DYLD_LIBRARY_PATH`**, so it now verifies the bundled rpath — the real self-contained path users and r-universe get.

`Makevars` is now generated from `Makevars.in`; `SystemRequirements` + ignore/attributes files updated.

## Validation
- The Windows `objdump`/`dlltool` import-lib dance was smoke-tested locally against the real v0.7.9 asset (2412 `wickra_` exports → import lib built).
- Linux/macOS rpath bundling can't be tested on this Windows host → **the 3-OS `r` CI job is the gate** (now without the loader-path mask).
- Follow-up (separate, after release): set up `wickra-lib/wickra-lib.r-universe.dev` (`packages.json` → `bindings/r`).

Closes the R half of the self-contained-distribution gap (`todo-10`).
2026-06-09 22:11:50 +02:00

44 lines
2.0 KiB
Bash

#!/bin/sh
# Windows build: the package compiles to wickra.dll, which would collide with the
# C ABI's own wickra.dll (the loader would resolve the import to the package
# itself). Stage a renamed copy, wickra_abi.dll, into src/ and build a mingw
# import library that references it by that name (objdump + dlltool, both shipped
# with Rtools — no gendef/pexports needed). install.libs.R then bundles the DLL.
#
# Self-contained by default: download the prebuilt wickra-c-<triple>.tar.gz
# release asset matching this package's version. Set WICKRA_INCLUDE_DIR +
# WICKRA_LIB_DIR to build against a locally built C ABI instead (dev override).
set -e
if [ -n "${WICKRA_INCLUDE_DIR}" ] && [ -n "${WICKRA_LIB_DIR}" ]; then
echo "wickra: using C ABI from WICKRA_INCLUDE_DIR / WICKRA_LIB_DIR (dev override)"
inc="${WICKRA_INCLUDE_DIR}"
lib="${WICKRA_LIB_DIR}"
else
version=$(sed -n 's/^Version:[[:space:]]*//p' DESCRIPTION)
arch=$(uname -m)
case "${arch}" in
x86_64) triple="x86_64-pc-windows-msvc" ;;
aarch64 | arm64) triple="aarch64-pc-windows-msvc" ;;
*) echo "wickra: unsupported Windows arch '${arch}' — set WICKRA_INCLUDE_DIR/WICKRA_LIB_DIR"; exit 1 ;;
esac
url="https://github.com/wickra-lib/wickra/releases/download/v${version}/wickra-c-${triple}.tar.gz"
echo "wickra: downloading C ABI ${triple} for v${version}"
"${R_HOME}/bin/Rscript" -e "download.file('${url}', 'src/wickra-c.tar.gz', mode = 'wb', quiet = TRUE)" \
|| { echo "wickra: failed to download ${url}"; exit 1; }
"${R_HOME}/bin/Rscript" -e "untar('src/wickra-c.tar.gz', exdir = 'src/wickra-c')"
inc="src/wickra-c/wickra-c-${triple}/include"
lib="src/wickra-c/wickra-c-${triple}/lib"
fi
cp "${inc}/wickra.h" src/wickra.h
cp "${lib}/wickra.dll" src/wickra_abi.dll
{
echo 'LIBRARY wickra_abi.dll'
echo 'EXPORTS'
objdump -p src/wickra_abi.dll | awk '/\[ *[0-9]+\]/ {print $NF}' | grep '^wickra_'
} > src/wickra_abi.def
dlltool --input-def src/wickra_abi.def --dllname wickra_abi.dll \
--output-lib src/libwickra_abi.dll.a
exit 0