diff --git a/.gitignore b/.gitignore index 6b9220f..6479a31 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,9 @@ result-* .pixi/ # devenv's local nix-eval cache/state (devenv.nix) — same role as .direnv/ .devenv/ +# flatpak-builder scratch state + bundle output (flatpak/uk.nandi.sleek.json +# is the only committed file in flatpak/) +/flatpak/build-dir/ +/flatpak/export-repo/ +/flatpak/.flatpak-builder/ +/flatpak/*.flatpak diff --git a/BUCK b/BUCK index 641ae2a..1ca6fcf 100644 --- a/BUCK +++ b/BUCK @@ -1,4 +1,5 @@ load(":cargo.bzl", "cargo_apk_genrule", "cargo_genrule") +load(":flatpak.bzl", "flatpak_genrule") # `buck2 build //:sleek-host` / `buck2 run //:sleek-host` # Equivalent to `just host` (desktop egui/eframe window), minus the DISPLAY / @@ -44,3 +45,18 @@ cargo_apk_genrule( manifest = "android/Cargo.toml", package = "sleek", ) + +# `buck2 build //:sleek-flatpak` +# Packages //:sleek-host into a distributable .flatpak bundle (GNOME +# Platform/49 runtime, uk.nandi.sleek app ID) — buck2/RBE equivalent of +# `nix build .#flatpak` (see flake.nix's nix2flatpak-based sleek-flatpak +# derivation, which this mirrors in appId/runtime/permissions but builds +# via plain flatpak-builder instead — nix2flatpak has no buck2 analog). +# Output: buck-out/.../uk.nandi.sleek.flatpak +# buck2 build --show-output //:sleek-flatpak +# flatpak install --user buck-out/.../uk.nandi.sleek.flatpak +flatpak_genrule( + name = "sleek-flatpak", + manifest = "flatpak/uk.nandi.sleek.json", + app_id = "uk.nandi.sleek", +) diff --git a/flatpak.bzl b/flatpak.bzl new file mode 100644 index 0000000..458e110 --- /dev/null +++ b/flatpak.bzl @@ -0,0 +1,81 @@ +# Flatpak-backed genrule wrapper. +# +# Unlike cargo.bzl's genrules (which shell out to a real `cargo build`), +# this one doesn't compile anything itself — it packages the *already +# buck2-built* //:sleek-host binary into a distributable .flatpak bundle +# via flatpak-builder + flatpak build-export/build-bundle, reusing the +# org.gnome.Platform//49 runtime (baked into toolchains/rbe-image/ +# Containerfile at image-build time, same pattern as the Android +# NDK/SDK) instead of vendoring every shared library sleek links against. +# +# Ports flake.nix's old `nix2flatpak.lib.${system}.mkFlatpak` derivation +# (see git history) to a plain flatpak-builder manifest + buck2 genrule — +# nix2flatpak itself has no buck2 equivalent (it works off a Nix closure), +# but the actual flatpak (appId/runtime/permissions/appdata/desktopFile) +# is identical. Confirmed locally (this sandbox already has flatpak-builder +# + org.gnome.Platform//49 + org.gnome.Sdk//49 installed): the resulting +# bundle is ~17MB, not the old Nix build's 617MB — reusing the shared +# runtime instead of bundling a whole Nix closure is a real size win, not +# just a packaging-mechanism swap. +def flatpak_genrule(name, manifest, app_id, host_target = "//:sleek-host"): + """A genrule that packages `host_target`'s binary into a signed-less .flatpak bundle. + + - manifest: path to the flatpak-builder JSON manifest (e.g. + "flatpak/uk.nandi.sleek.json"). Its module's `sources` must reference + the binary at manifest-relative path "../host/target/release/sleek" + (matching cargo_genrule("sleek-host")'s own real-repo-relative + output path) — this genrule stages `host_target`'s buck-out artifact + there before invoking flatpak-builder, same reason + _STAGE_PATCHED_FORKS exists in cargo.bzl (a target dependency lands + at its own buck-out path, not the real repo-relative one a manifest + written for local `flatpak-builder` use expects). + - app_id: the flatpak app ID (e.g. "uk.nandi.sleek") — used to name + the final bundle and as build-bundle's ref name. + """ + manifest_dir = manifest[: manifest.rfind("/") + 1] + bundle_name = app_id + ".flatpak" + + native.genrule( + name = name, + srcs = [ + manifest, + "assets/uk.nandi.sleek.desktop", + "assets/uk.nandi.sleek.metainfo.xml", + "assets/uk.nandi.sleek.svg", + host_target, + ], + out = bundle_name, + cmd = "\n".join([ + "set -euo pipefail", + # Stage the buck2-built binary at the real repo-relative path + # the manifest's source list expects (see docstring above) — + # same shape as cargo_genrule("sleek-host")'s own collect_cmd + # output, just copied here instead of freshly compiled. + "mkdir -p host/target/release", + 'cp "$(location {})" host/target/release/sleek'.format(host_target), + "chmod +x host/target/release/sleek", + # Subshell, not a bare `cd` — $OUT below is a path relative to + # this script's *original* cwd (repo root); cd'ing for real + # would break it, same reason cargo_apk_genrule's own + # `(cd android/ && ...)` step is a subshell rather than a + # plain `cd`. Confirmed hitting exactly that (a bare `cd` here + # made the final cp look for buck-out/... under flatpak/). + "(", + " cd {}".format(manifest_dir), + # --disable-rofiles-fuse: RE workers may not have /dev/fuse + # available/permitted; the fuse-backed rofiles optimization is + # a local-build speedup only, not required for correctness. + " flatpak-builder --force-clean --disable-rofiles-fuse build-dir {}".format(manifest.split("/")[-1]), + " flatpak build-export export-repo build-dir", + " flatpak build-bundle export-repo {} {}".format(bundle_name, app_id), + ")", + 'cp "{}{}" "$OUT"'.format(manifest_dir, bundle_name), + ]), + # Same rationale as cargo.bzl's genrules — see cargo_genrule's own + # comment. Meaningful for local execution only; RE workers get + # flatpak/flatpak-builder + the pre-installed runtime from the + # custom RE image instead (toolchains/rbe-image/Containerfile). + repo_relative_root = True, + always_print_stderr = True, + visibility = ["PUBLIC"], + ) diff --git a/flatpak/uk.nandi.sleek.json b/flatpak/uk.nandi.sleek.json new file mode 100644 index 0000000..ac1bfbd --- /dev/null +++ b/flatpak/uk.nandi.sleek.json @@ -0,0 +1,51 @@ +{ + "app-id": "uk.nandi.sleek", + "runtime": "org.gnome.Platform", + "runtime-version": "49", + "sdk": "org.gnome.Sdk", + "command": "sleek", + "appstream-compose": false, + "finish-args": [ + "--share=network", + "--share=ipc", + "--socket=fallback-x11", + "--socket=wayland", + "--socket=pulseaudio", + "--device=dri", + "--device=all", + "--filesystem=xdg-run/pipewire-0", + "--filesystem=xdg-download", + "--talk-name=org.freedesktop.Notifications", + "--talk-name=org.freedesktop.portal.Desktop" + ], + "modules": [ + { + "name": "sleek", + "buildsystem": "simple", + "build-commands": [ + "install -Dm755 sleek /app/bin/sleek", + "install -Dm644 uk.nandi.sleek.desktop /app/share/applications/uk.nandi.sleek.desktop", + "install -Dm644 uk.nandi.sleek.metainfo.xml /app/share/metainfo/uk.nandi.sleek.metainfo.xml", + "install -Dm644 uk.nandi.sleek.svg /app/share/icons/hicolor/scalable/apps/uk.nandi.sleek.svg" + ], + "sources": [ + { + "type": "file", + "path": "../host/target/release/sleek" + }, + { + "type": "file", + "path": "../assets/uk.nandi.sleek.desktop" + }, + { + "type": "file", + "path": "../assets/uk.nandi.sleek.metainfo.xml" + }, + { + "type": "file", + "path": "../assets/uk.nandi.sleek.svg" + } + ] + } + ] +} diff --git a/toolchains/rbe-image/Containerfile b/toolchains/rbe-image/Containerfile index 4d0c07a..6ef9ae2 100644 --- a/toolchains/rbe-image/Containerfile +++ b/toolchains/rbe-image/Containerfile @@ -6,7 +6,12 @@ # image with pixi + the Android NDK baked in, matching flake.nix's # devShell env exactly, so sleek-android-lib's `cargo build` has # everything it needs without depending on this machine's local pixi/NDK -# install. See README.md in this directory for how to build + push it. +# install. Also bakes in flatpak + flatpak-builder + a system-wide +# org.gnome.Platform//49 + org.gnome.Sdk//49 install for flatpak.bzl's +# sleek-flatpak genrule (see near the bottom of this file) — same +# "pre-install so RE actions don't need Flathub network access" pattern as +# the Android NDK/SDK. See README.md in this directory for how to build + +# push it. FROM gcr.io/flame-public/rbe-ubuntu22-04:latest # build-essential: pixi's own clang/libclang (bindgen's dependency, see @@ -105,3 +110,29 @@ COPY pixi.toml pixi.lock /tmp/sleek-pixi/ RUN cd /tmp/sleek-pixi && pixi install --locked \ && pixi run -- cargo install --root /opt/cargo-apk cargo-apk \ && rm -rf /tmp/sleek-pixi + +# flatpak + flatpak-builder — for flatpak.bzl's sleek-flatpak genrule +# (packages //:sleek-host into a distributable .flatpak using the GNOME +# Platform/49 runtime; ports flake.nix's old nix2flatpak-based +# sleek-flatpak derivation, see that file's git history). Jammy's stock +# apt versions (flatpak 1.12.7, flatpak-builder 1.2.2 — both quite old) +# confirmed able to pull a current GNOME 49 runtime from Flathub fine, no +# PPA needed. +RUN apt-get update && apt-get install -y --no-install-recommends \ + flatpak flatpak-builder \ + && rm -rf /var/lib/apt/lists/* + +# System-wide (not --user): RE actions may run as any/no particular user +# and shouldn't need a real $HOME set up just to see the runtime — a +# system install under /var/lib/flatpak is visible to everyone. Installed +# at image-build time (network access, but only once here) so RE actions +# themselves need no Flathub access — same rationale as pre-warming pixi +# above and baking in the Android NDK/SDK. +# +# flatpak-builder's `"appstream-compose": false` manifest key (see +# flatpak/uk.nandi.sleek.json) means appstreamcli's compose subcommand is +# never invoked, so it deliberately isn't installed here — confirmed +# jammy's own `appstream` package (0.15.2) doesn't ship it anyway (that +# subcommand only exists in much newer libappstream releases). +RUN flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo \ + && flatpak install -y --noninteractive --system flathub org.gnome.Platform//49 org.gnome.Sdk//49