From d3b8929fde9161e5c1e7d0066469f4009e765d1a Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Fri, 9 Oct 2026 23:14:29 -0400 Subject: [PATCH] ci: add RISC-V Linux build --- .github/workflows/release.yml | 69 +++++++++++++++++++++++++++++++++++ docs/releasing.md | 1 + packaging/linux/package.sh | 19 +++++++--- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de15fd8a2..5ae44f579 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -323,6 +323,75 @@ jobs: # FreeBSD has no hosted runners: freebsd.yml builds in a FreeBSD VM and, with package: true, # uploads the release-freebsd artifact (gridcraft--freebsd-x86_64.tar.gz). It needs no # secrets, so the called workflow runs without the release environment (and in dry runs). + linux-riscv64: + name: Linux riscv64 + needs: version + runs-on: ubuntu-26.04 + env: + GRIDCRAFT_VERSION: ${{ needs.version.outputs.version }} + GRIDCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + steps: + - uses: actions/checkout@v4 + - name: Check out craft-fonts + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + repository: storytold/craft-fonts + ref: abb83316d96aa59c1cf64784289e378fe9fa5695 + path: craft-fonts + - uses: dtolnay/rust-toolchain@686976e191b89faba57d3206551f0f330d8cb249 # stable + with: + toolchain: stable + targets: riscv64gc-unknown-linux-gnu + - name: Apply version override + if: inputs.version != '' + run: cargo xtask version set "$GRIDCRAFT_VERSION" + - name: Install cross-compilation dependencies + run: | + sudo dpkg --add-architecture riscv64 + if [ -f /etc/apt/sources.list.d/ubuntu.sources ]; then + sudo sed -i '/^Types: deb/a Architectures: amd64' /etc/apt/sources.list.d/ubuntu.sources + fi + if [ -f /etc/apt/sources.list ]; then + sudo sed -i 's/^deb /deb [arch=amd64] /g' /etc/apt/sources.list + sudo sed -i 's/^deb-src /deb-src [arch=amd64] /g' /etc/apt/sources.list + fi + cat << 'EOF' | sudo tee /etc/apt/sources.list.d/riscv64.list + deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports resolute main universe restricted multiverse + deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports resolute-updates main universe restricted multiverse + deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports resolute-security main universe restricted multiverse + EOF + sudo apt-get update + sudo apt-get install -y --allow-downgrades --no-install-recommends \ + gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu libc6-dev-riscv64-cross libc6-dev:riscv64 qemu-user \ + libasound2-dev:riscv64 libxkbcommon-dev:riscv64 \ + libwayland-dev:riscv64 libx11-dev:riscv64 libxrandr-dev:riscv64 libxi-dev:riscv64 libgl1-mesa-dev:riscv64 + if command -v qemu-riscv64 >/dev/null 2>&1 && ! command -v qemu-riscv64-static >/dev/null 2>&1; then + sudo ln -s "$(command -v qemu-riscv64)" /usr/local/bin/qemu-riscv64-static + fi + - name: Build and package + env: + CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER: riscv64-linux-gnu-gcc + CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUSTFLAGS: "-C link-arg=-L/usr/riscv64-linux-gnu/lib -C link-arg=-L/usr/lib/riscv64-linux-gnu" + PKG_CONFIG_SYSROOT_DIR: / + PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig:/usr/share/pkgconfig + PKG_CONFIG_ALLOW_CROSS: "1" + CROSS_ARCH: riscv64 + CROSS_TARGET: riscv64gc-unknown-linux-gnu + CROSS_COMPILE: riscv64-linux-gnu- + EMULATOR: qemu-riscv64-static + run: | + export CRAFT_FONTS_DIR="$PWD/craft-fonts" CRAFT_FONTS_REQUIRED=1 + packaging/linux/package.sh --formats "tar" + - name: Smoke test CLI under QEMU + run: | + tar -xzf dist/release/*.tar.gz + qemu-riscv64-static -L /usr/riscv64-linux-gnu gridcraft-*/bin/gridcraft-cli --version + - uses: actions/upload-artifact@v4 + with: + name: release-linux-riscv64 + path: dist/release/*.tar.gz + if-no-files-found: error + freebsd: name: FreeBSD needs: version diff --git a/docs/releasing.md b/docs/releasing.md index f4a28eba7..de94b212b 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -82,6 +82,7 @@ and upload their artifacts, the environment refuses macOS and Windows, and no re | Windows 11 ARM64 | `gridcraft--windows-arm64.msi`, `…-portable.zip` (cross-compiled, signed like x64) | `windows-latest`; installed and run on `windows-11-arm` by `windows-arm64.yml` | | Linux x86_64 | `gridcraft--linux-x86_64.{AppImage,AppImage.zsync,deb,rpm,tar.gz}` | `ubuntu-22.04` | | Linux aarch64 | `gridcraft--linux-aarch64.{AppImage,AppImage.zsync,deb,rpm,tar.gz}` | `ubuntu-22.04-arm` | +| Linux riscv64 | `gridcraft--linux-riscv64.tar.gz` | cross-compiled on `ubuntu-26.04` | | Flatpak x86_64, aarch64 | `gridcraft--linux-.flatpak` (repackages the Linux tarball) | `ubuntu-24.04`, `ubuntu-24.04-arm` | | FreeBSD 14 x86_64 | `gridcraft--freebsd-x86_64.tar.gz` | FreeBSD 14.3 VM (`freebsd.yml`, called by `release.yml`) | | Web | `gridcraft-web-.zip` (static site; see [`packaging/web/README.md`](../packaging/web/README.md)) | `ubuntu-latest` | diff --git a/packaging/linux/package.sh b/packaging/linux/package.sh index 20ad1b2b8..e7123034a 100755 --- a/packaging/linux/package.sh +++ b/packaging/linux/package.sh @@ -30,8 +30,9 @@ while [ $# -gt 0 ]; do esac done -ARCH="$(uname -m)" +ARCH="${CROSS_ARCH:-$(uname -m)}" case "$ARCH" in + riscv64) DEB_ARCH=riscv64 ;; x86_64) DEB_ARCH=amd64 ;; aarch64 | arm64) ARCH=aarch64; DEB_ARCH=arm64 ;; *) echo "unsupported architecture $ARCH" >&2; exit 2 ;; @@ -42,9 +43,13 @@ BASENAME="gridcraft-$VERSION-linux-$ARCH" echo "==> GridCraft $VERSION for Linux $ARCH ($FORMATS)" if [ "$SKIP_BUILD" = 0 ]; then - (cd "$ROOT" && cargo build --release --locked -p gridcraft -p gridcraft-cli) + if [ -n "${CROSS_TARGET:-}" ]; then + (cd "$ROOT" && cargo build --release --locked -p gridcraft -p gridcraft-cli --target "$CROSS_TARGET") + else + (cd "$ROOT" && cargo build --release --locked -p gridcraft -p gridcraft-cli) + fi fi -BIN="$CARGO_TARGET_DIR/release" +BIN="$CARGO_TARGET_DIR/${CROSS_TARGET:+$CROSS_TARGET/}release" WORK="$CARGO_TARGET_DIR/linux-package" STAGE="$WORK/root" rm -rf "$WORK" @@ -52,7 +57,7 @@ rm -rf "$WORK" # ---- stage an FHS tree (shared by every format) ------------------------------------------------- install -Dm755 "$BIN/gridcraft" "$STAGE/usr/bin/gridcraft" install -Dm755 "$BIN/gridcraft-cli" "$STAGE/usr/bin/gridcraft-cli" -strip "$STAGE/usr/bin/gridcraft" "$STAGE/usr/bin/gridcraft-cli" 2>/dev/null || true +"${CROSS_COMPILE:-}strip" "$STAGE/usr/bin/gridcraft" "$STAGE/usr/bin/gridcraft-cli" 2>/dev/null || true install -Dm644 "$HERE/$APP_ID.desktop" "$STAGE/usr/share/applications/$APP_ID.desktop" install -Dm644 "$HERE/$APP_ID.mime.xml" "$STAGE/usr/share/mime/packages/$APP_ID.xml" mkdir -p "$STAGE/usr/share/metainfo" @@ -135,6 +140,10 @@ if has appimage; then fi fi -"$STAGE/usr/bin/gridcraft-cli" --version +if [ -z "${CROSS_TARGET:-}" ]; then + "$STAGE/usr/bin/gridcraft-cli" --version +elif [ -n "${EMULATOR:-}" ]; then + $EMULATOR "$STAGE/usr/bin/gridcraft-cli" --version +fi echo "==> done" ls -lh "$DIST"