diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 706daac6d..c7b032f07 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -377,11 +377,91 @@ jobs: path: dist/release/* if-no-files-found: error + linux-riscv64: + name: Linux riscv64 + needs: version + # Cross-compiled on x86_64 (no hosted RISC-V runners) against the runner's own Ubuntu release + # from ports.ubuntu.com, so the binaries need that release's glibc (24.04: 2.39). 22.04's + # riscv64 ports lag its amd64 updates, which breaks the multiarch install. tar.gz only; the + # CLI is smoke-tested under QEMU (package.sh runs `vectorcraft-cli --version` through $EMULATOR). + runs-on: ubuntu-24.04 + # No `environment: release`: this job signs nothing, so it gets no release secrets. + env: + VECTORCRAFT_VERSION: ${{ needs.version.outputs.version }} + VECTORCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + steps: + - uses: actions/checkout@v7 + # Japanese UI/document fonts, embedded by crates/text/build.rs (CRAFT_FONTS_DIR on the build + # step). Bump the commit deliberately; see craftrules standards/fonts.md. + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: storytold/craft-fonts + ref: abb83316d96aa59c1cf64784289e378fe9fa5695 + path: craft-fonts + - uses: dtolnay/rust-toolchain@stable + with: + targets: riscv64gc-unknown-linux-gnu + - uses: Swatinem/rust-cache@v2 + with: + key: release-linux-riscv64 + - name: Apply version override + if: inputs.version != '' + run: cargo xtask version set "$VECTORCRAFT_VERSION" + - name: Install cross-compilation dependencies + run: | + . /etc/os-release + sudo dpkg --add-architecture riscv64 + # Pin the existing (archive.ubuntu.com) sources to amd64; riscv64 comes from ports. + 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 + for suite in "$VERSION_CODENAME" "$VERSION_CODENAME-updates" "$VERSION_CODENAME-security"; do + echo "deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports $suite main universe restricted multiverse" + done | sudo tee /etc/apt/sources.list.d/riscv64.list + sudo apt-get update + # The riscv64 variants of the linux job's -dev packages. + sudo apt-get install -y --no-install-recommends \ + gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu libc6-dev-riscv64-cross libc6-dev:riscv64 qemu-user \ + libxkbcommon-dev:riscv64 libwayland-dev:riscv64 libx11-dev:riscv64 libxrandr-dev:riscv64 \ + libxi-dev:riscv64 libgl1-mesa-dev:riscv64 \ + desktop-file-utils appstream + - name: Build and package (tar.gz) + env: + CRAFT_FONTS_DIR: ${{ github.workspace }}/craft-fonts + CRAFT_FONTS_REQUIRED: "1" + CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER: riscv64-linux-gnu-gcc + CC_riscv64gc_unknown_linux_gnu: riscv64-linux-gnu-gcc + CXX_riscv64gc_unknown_linux_gnu: riscv64-linux-gnu-g++ + AR_riscv64gc_unknown_linux_gnu: riscv64-linux-gnu-ar + 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 + QEMU_LD_PREFIX: /usr/riscv64-linux-gnu + run: packaging/linux/package.sh --formats tar + - name: Check the package + run: | + tar -tzf dist/release/vectorcraft-*-linux-riscv64.tar.gz \ + | grep -E '/bin/vectorcraft$|/bin/vectorcraft-cli$|/share/applications/ai\.storyteller\.vectorcraft\.desktop$' + file target/riscv64gc-unknown-linux-gnu/release/vectorcraft | grep -F 'RISC-V' + - uses: actions/upload-artifact@v7 + with: + name: release-linux-riscv64 + path: dist/release/*.tar.gz + if-no-files-found: error + release: name: Draft GitHub Release # Needs the signed jobs, so a branch dry run (where the environment refuses them) never # drafts a release. - needs: [version, macos, windows, linux, flatpak, freebsd, web] + needs: [version, macos, windows, linux, linux-riscv64, flatpak, freebsd, web] runs-on: ubuntu-latest environment: release permissions: diff --git a/Cargo.lock b/Cargo.lock index ce87c92c9..9b09db608 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4320,7 +4320,7 @@ dependencies = [ [[package]] name = "vectorcraft" -version = "0.8.0" +version = "0.9.0" dependencies = [ "arboard", "block2 0.6.2", @@ -4350,7 +4350,7 @@ dependencies = [ [[package]] name = "vectorcraft-affinity" -version = "0.8.0" +version = "0.9.0" dependencies = [ "crc32fast", "flate2", @@ -4361,7 +4361,7 @@ dependencies = [ [[package]] name = "vectorcraft-brush" -version = "0.8.0" +version = "0.9.0" dependencies = [ "kurbo 0.13.1", "serde", @@ -4373,7 +4373,7 @@ dependencies = [ [[package]] name = "vectorcraft-cad" -version = "0.8.0" +version = "0.9.0" dependencies = [ "image", "kurbo 0.13.1", @@ -4389,7 +4389,7 @@ dependencies = [ [[package]] name = "vectorcraft-cli" -version = "0.8.0" +version = "0.9.0" dependencies = [ "log", "objc2-core-foundation", @@ -4410,7 +4410,7 @@ dependencies = [ [[package]] name = "vectorcraft-color" -version = "0.8.0" +version = "0.9.0" dependencies = [ "kurbo 0.13.1", "moxcms", @@ -4422,7 +4422,7 @@ dependencies = [ [[package]] name = "vectorcraft-doc" -version = "0.8.0" +version = "0.9.0" dependencies = [ "image", "jpeg-encoder", @@ -4439,7 +4439,7 @@ dependencies = [ [[package]] name = "vectorcraft-effects" -version = "0.8.0" +version = "0.9.0" dependencies = [ "kurbo 0.13.1", "serde_json", @@ -4454,7 +4454,7 @@ dependencies = [ [[package]] name = "vectorcraft-engine" -version = "0.8.0" +version = "0.9.0" dependencies = [ "crc32fast", "flate2", @@ -4489,7 +4489,7 @@ dependencies = [ [[package]] name = "vectorcraft-eps" -version = "0.8.0" +version = "0.9.0" dependencies = [ "flate2", "image", @@ -4509,7 +4509,7 @@ dependencies = [ [[package]] name = "vectorcraft-format" -version = "0.8.0" +version = "0.9.0" dependencies = [ "flate2", "proptest", @@ -4523,7 +4523,7 @@ dependencies = [ [[package]] name = "vectorcraft-geom" -version = "0.8.0" +version = "0.9.0" dependencies = [ "kurbo 0.13.1", "proptest", @@ -4535,7 +4535,7 @@ dependencies = [ [[package]] name = "vectorcraft-mcp" -version = "0.8.0" +version = "0.9.0" dependencies = [ "image", "log", @@ -4554,7 +4554,7 @@ dependencies = [ [[package]] name = "vectorcraft-metafile" -version = "0.8.0" +version = "0.9.0" dependencies = [ "image", "kurbo 0.13.1", @@ -4568,7 +4568,7 @@ dependencies = [ [[package]] name = "vectorcraft-pathops" -version = "0.8.0" +version = "0.9.0" dependencies = [ "kurbo 0.13.1", "linesweeper", @@ -4580,7 +4580,7 @@ dependencies = [ [[package]] name = "vectorcraft-pdf" -version = "0.8.0" +version = "0.9.0" dependencies = [ "aes", "flate2", @@ -4609,7 +4609,7 @@ dependencies = [ [[package]] name = "vectorcraft-plugins" -version = "0.8.0" +version = "0.9.0" dependencies = [ "serde", "serde_json", @@ -4623,7 +4623,7 @@ dependencies = [ [[package]] name = "vectorcraft-render" -version = "0.8.0" +version = "0.9.0" dependencies = [ "flate2", "gif", @@ -4648,7 +4648,7 @@ dependencies = [ [[package]] name = "vectorcraft-svg" -version = "0.8.0" +version = "0.9.0" dependencies = [ "flate2", "image", @@ -4672,7 +4672,7 @@ dependencies = [ [[package]] name = "vectorcraft-testkit" -version = "0.8.0" +version = "0.9.0" dependencies = [ "image", "kurbo 0.13.1", @@ -4689,7 +4689,7 @@ dependencies = [ [[package]] name = "vectorcraft-text" -version = "0.8.0" +version = "0.9.0" dependencies = [ "harfrust 0.13.3", "kurbo 0.13.1", @@ -4707,14 +4707,14 @@ dependencies = [ [[package]] name = "vectorcraft-three-d" -version = "0.8.0" +version = "0.9.0" dependencies = [ "vectorcraft-geom", ] [[package]] name = "vectorcraft-tools" -version = "0.8.0" +version = "0.9.0" dependencies = [ "image", "kurbo 0.13.1", @@ -4729,7 +4729,7 @@ dependencies = [ [[package]] name = "vectorcraft-trace" -version = "0.8.0" +version = "0.9.0" dependencies = [ "image", "kurbo 0.13.1", @@ -4742,7 +4742,7 @@ dependencies = [ [[package]] name = "vectorcraft-ui-egui" -version = "0.8.0" +version = "0.9.0" dependencies = [ "egui", "egui_extras", @@ -4773,7 +4773,7 @@ dependencies = [ [[package]] name = "vectorcraft-web" -version = "0.8.0" +version = "0.9.0" dependencies = [ "eframe", "egui", @@ -5883,7 +5883,7 @@ checksum = "9440ea3e5aeabb0ac63af70daf835274065238cdd0cec83418f417eae38bacee" [[package]] name = "xtask" -version = "0.8.0" +version = "0.9.0" dependencies = [ "serde_json", ] diff --git a/Cargo.toml b/Cargo.toml index ae4d113a8..dfbb344c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = ["crates/*", "apps/*", "xtask"] default-members = ["crates/*", "apps/vectorcraft", "apps/vectorcraft-cli", "xtask"] [workspace.package] -version = "0.8.0" +version = "0.9.0" edition = "2024" license = "MIT OR Apache-2.0" rust-version = "1.95" diff --git a/docs/releasing.md b/docs/releasing.md index fe475dd26..bfa8782c8 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -1,7 +1,7 @@ # Releasing VectorCraft Every push to the `release` branch runs `.github/workflows/release.yml`. The workflow builds -installers for macOS, Windows, Linux (including Flatpak bundles) and FreeBSD, plus the web build, and creates or updates a +installers for macOS, Windows, Linux (including Flatpak bundles and a RISC-V tarball) and FreeBSD, plus the web build, and creates or updates a **draft** GitHub Release named `VectorCraft v`. Nobody sees a draft until a maintainer publishes it. @@ -50,6 +50,7 @@ and no draft release is created. | Windows on ARM64 | `vectorcraft--windows-arm64.msi`, `vectorcraft--windows-arm64-portable.zip` | `windows-latest` (cross-compiled) | | Linux x86_64 | `vectorcraft--linux-x86_64.{AppImage,deb,rpm,tar.gz}` | `ubuntu-22.04` | | Linux aarch64 | `vectorcraft--linux-aarch64.{AppImage,deb,rpm,tar.gz}` | `ubuntu-22.04-arm` | +| Linux riscv64 | `vectorcraft--linux-riscv64.tar.gz` (cross-compiled, glibc >= 2.39; CLI smoke-tested under QEMU) | `ubuntu-24.04` | | Linux AppImage updates | `vectorcraft--linux-{x86_64,aarch64}.AppImage.zsync` | with the AppImages | | Flatpak x86_64, aarch64 | `vectorcraft--linux-{x86_64,aarch64}.flatpak` | `ubuntu-24.04`, `ubuntu-24.04-arm` (repackages the Linux tarball) | | FreeBSD 14 x86_64 | `vectorcraft--freebsd-x86_64.tar.gz` | a FreeBSD 14.3 VM on `ubuntu-latest` | @@ -144,6 +145,11 @@ glibc 2.35 or newer: Ubuntu 22.04+, Debian 12+, Fedora 36+ and RHEL 10. Moving t image raises that floor, so do it deliberately. After packaging, the job prints the `.deb`'s metadata and contents, runs `ldd` on the binary and runs each AppImage with `--version`. +**RISC-V.** The `linux-riscv64` job cross-compiles `riscv64gc-unknown-linux-gnu` on `ubuntu-24.04` +against riscv64 libraries from ports.ubuntu.com (so the floor there is glibc 2.39) and runs +`package.sh --formats tar` with `CROSS_ARCH`, `CROSS_TARGET`, `CROSS_COMPILE` and +`EMULATOR=qemu-riscv64` set: a `.tar.gz` only, with `vectorcraft-cli --version` run under QEMU. + **AppImage updates.** Each AppImage embeds the update information `gh-releases-zsync|storytold|vectorcraft|latest|vectorcraft-*-linux-.AppImage.zsync` (appimagetool `-u`), and `package.sh` writes the matching `.zsync` beside it when `zsyncmake` (the diff --git a/packaging/linux/package.sh b/packaging/linux/package.sh index 1036031f2..7efbaf44e 100755 --- a/packaging/linux/package.sh +++ b/packaging/linux/package.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Build and package VectorCraft for Linux ( is x86_64 or aarch64): +# Build and package VectorCraft for Linux ( is x86_64 or aarch64, or riscv64 when cross-compiling): # # $DIST/vectorcraft--linux-.AppImage any distro with glibc >= the build host's # $DIST/vectorcraft--linux-.AppImage.zsync delta updates (needs zsyncmake) @@ -9,6 +9,10 @@ # # Usage: packaging/linux/package.sh [--skip-build] [--formats "appimage deb rpm tar"] # +# Cross-compiling (release.yml's linux-riscv64 job): set CROSS_ARCH (riscv64), CROSS_TARGET (the Rust +# target), CROSS_COMPILE (the binutils prefix, for strip) and EMULATOR (e.g. qemu-riscv64, to +# smoke-test the CLI), and pass --formats tar. +# # Needs: cargo; nfpm for deb/rpm (https://nfpm.goreleaser.com); appimagetool for the AppImage # (downloaded into $CARGO_TARGET_DIR if missing). Build on an old distro (CI: Ubuntu 22.04, # glibc 2.35) so the binaries run on newer ones. Optional: desktop-file-validate, appstreamcli, @@ -25,13 +29,14 @@ while [ $# -gt 0 ]; do case "$1" in --skip-build) SKIP_BUILD=1; shift ;; --formats) FORMATS="$2"; shift 2 ;; - -h | --help) sed -n '2,15p' "$0"; exit 0 ;; + -h | --help) sed -n '2,19p' "$0"; exit 0 ;; *) echo "unknown argument: $1" >&2; exit 2 ;; 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 +47,13 @@ BASENAME="vectorcraft-$VERSION-linux-$ARCH" echo "==> VectorCraft $VERSION for Linux $ARCH ($FORMATS)" if [ "$SKIP_BUILD" = 0 ]; then - (cd "$ROOT" && cargo build --release --locked -p vectorcraft -p vectorcraft-cli) + if [ -n "${CROSS_TARGET:-}" ]; then + (cd "$ROOT" && cargo build --release --locked -p vectorcraft -p vectorcraft-cli --target "$CROSS_TARGET") + else + (cd "$ROOT" && cargo build --release --locked -p vectorcraft -p vectorcraft-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 +61,7 @@ rm -rf "$WORK" # ---- stage an FHS tree (shared by every format) ------------------------------------------------- install -Dm755 "$BIN/vectorcraft" "$STAGE/usr/bin/vectorcraft" install -Dm755 "$BIN/vectorcraft-cli" "$STAGE/usr/bin/vectorcraft-cli" -strip "$STAGE/usr/bin/vectorcraft" "$STAGE/usr/bin/vectorcraft-cli" 2>/dev/null || true +"${CROSS_COMPILE:-}strip" "$STAGE/usr/bin/vectorcraft" "$STAGE/usr/bin/vectorcraft-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 +144,10 @@ if has appimage; then fi fi -"$STAGE/usr/bin/vectorcraft-cli" --version +if [ -z "${CROSS_TARGET:-}" ]; then + "$STAGE/usr/bin/vectorcraft-cli" --version +elif [ -n "${EMULATOR:-}" ]; then + "$EMULATOR" "$STAGE/usr/bin/vectorcraft-cli" --version +fi echo "==> done" ls -lh "$DIST"