From 5bcddb90272a32a25527c8f164b6253429c89065 Mon Sep 17 00:00:00 2001 From: Test User Date: Thu, 23 Jul 2026 14:26:36 +0200 Subject: [PATCH] Embed the web UI in the aarch64 (Raspberry Pi) flake build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The static aarch64 crabidy-server now ships the browser UI. crane builds the cbd-web wasm bundle with trunk, then stages it into the server's `web-ui` feature (build.rs embeds cbd-web/dist). - webSrc: a source variant that keeps cbd-web's non-cargo assets (index.html, style.css, Trunk.toml) that filterCargoSources drops, minus any stale prebuilt dist/. - wasmBindgenCli: nixpkgs ships an older wasm-bindgen CLI and the dev shell lets trunk download the matching one at build time, which a sealed Nix build can't do — so pin an overridden CLI at 0.2.126 to match the wasm-bindgen crate. - webBundle: buildTrunkPackage over a wasm32 toolchain; build from inside cbd-web (virtual workspace ⇒ trunk can't resolve the member from the root) and index.html-first so trunk's optional-valued --release doesn't swallow the positional. - The aarch64 server drops --no-default-features (web-ui back on) and a preBuild stages the bundle into cbd-web/dist before the crate compiles. Verified: nix build .#crabidy-server-aarch64 produces a static aarch64 ELF whose embedded index.html carries the real hashed wasm/js assets (not the headless placeholder). Native .#crabidy stays headless. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 7 +++-- flake.nix | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 97 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7f799df..69d52d1 100644 --- a/README.md +++ b/README.md @@ -296,8 +296,11 @@ scp ./result/bin/crabidy-server pi:/usr/local/bin/ Nix cross-compiles the Rust *and* the C dependencies (ALSA, aws-lc) hermetically on an x86_64 host — the isolated build avoids the host-linker -pitfalls of cross-compiling in a plain shell. The flake packages are headless -(no embedded web UI); use a normal `cargo build` if you need the bundle. +pitfalls of cross-compiling in a plain shell. The aarch64 server **includes +the embedded web UI**: the flake builds the `cbd-web` wasm bundle with trunk +(pinning a `wasm-bindgen` CLI that matches the crate) and stages it into the +server's `web-ui` feature. The native `.#crabidy` package stays headless; use +a normal `cargo build` there if you want the bundle. A container-based `cross` setup also exists (`Cross.toml` + the `*-Dockerfile`s) for building against Debian's glibc, but the flake is the diff --git a/flake.nix b/flake.nix index 34b15e5..06d1176 100644 --- a/flake.nix +++ b/flake.nix @@ -36,11 +36,93 @@ (builtins.match ".*\\.proto$" path != null) || (crane.mkLib pkgs).filterCargoSources path type; }; + # trunk needs cbd-web's non-cargo assets (index.html, style.css, + # Trunk.toml) which filterCargoSources drops. Keep everything under + # cbd-web/ (except a stale prebuilt dist/) plus the usual cargo/proto + # sources. + webSrc = lib.cleanSourceWith { + src = ./.; + name = "crabidy-web-source"; + filter = + path: type: + ( + (builtins.match ".*\\.proto$" path != null) + || (lib.hasInfix "/cbd-web/" path) + || (crane.mkLib pkgs).filterCargoSources path type + ) + && !(lib.hasInfix "/cbd-web/dist" path); + }; + # Only the real binary crates; never build cbd-web (a wasm crate) for a # host or aarch64 target. Headless: --no-default-features drops the - # embedded web UI (its own wasm-bundle derivation is future work). + # embedded web UI. The aarch64 server (below) re-enables it and stages + # the wasm bundle. workspaceBins = "-p crabidy-server -p cbd -p cbd-tui"; + # --- Web UI (wasm) bundle --------------------------------------------- + # cbd-web is compiled to wasm by trunk; the output dist/ is what + # crabidy-server's build.rs embeds (feature `web-ui`). The bundle is + # architecture-independent — the same wasm runs in the browser whatever + # the server's CPU — so one derivation feeds every server build. + # + # The wasm-bindgen CLI version must match the wasm-bindgen crate + # (0.2.126) exactly. nixpkgs ships an older CLI and, in the dev shell, + # trunk downloads the matching one at build time — impossible in a + # sealed Nix build, so we pin an overridden CLI here. + wasmBindgenCli = pkgs.wasm-bindgen-cli.overrideAttrs (_: rec { + version = "0.2.126"; + src = pkgs.fetchCrate { + pname = "wasm-bindgen-cli"; + inherit version; + hash = "sha256-H6Is3fiZVxZCfOMWK5dWMSrtn50VGv0sfdnsT+cTtyk="; + }; + cargoDeps = pkgs.rustPlatform.fetchCargoVendor { + inherit src; + name = "wasm-bindgen-cli-${version}-vendor"; + hash = "sha256-VucqkXbCi4qtQzY/HrXiDnbSURsagPsdNVMn1Tw3UiY="; + }; + }); + + wasmToolchain = fenixPkgs.combine [ + fenixPkgs.stable.rustc + fenixPkgs.stable.cargo + fenixPkgs.targets.wasm32-unknown-unknown.stable.rust-std + ]; + craneLibWasm = (crane.mkLib pkgs).overrideToolchain (_: wasmToolchain); + + webArgs = { + src = webSrc; + strictDeps = true; + cargoExtraArgs = "--locked -p cbd-web"; + CARGO_BUILD_TARGET = "wasm32-unknown-unknown"; + doCheck = false; + # crabidy-core's build.rs (a transitive dep of cbd-web) needs protoc. + nativeBuildInputs = [ pkgs.protobuf ]; + }; + webDeps = craneLibWasm.buildDepsOnly webArgs; + webBundle = craneLibWasm.buildTrunkPackage ( + webArgs + // { + pname = "cbd-web"; + version = "0.1.0"; + cargoArtifacts = webDeps; + wasm-bindgen-cli = wasmBindgenCli; + # wasm-opt for the release bundle. + wasm-opt = pkgs.binaryen; + # This is a virtual workspace, so trunk run from the root can't + # resolve the cbd-web member (it reports "could not find the root + # package"). Build from inside cbd-web, exactly like the dev-shell + # `build-web` script. The vendored cargo config already pins cargo + # to the offline vendor dir, so no network is needed. + buildPhaseCargoCommand = '' + ( cd cbd-web && trunk build index.html --release ) + ''; + installPhaseCommand = '' + cp -r cbd-web/dist $out + ''; + } + ); + # --- Native toolchain / build (for `nix profile install` on x86_64, # aarch64, etc.) --- craneLib = (crane.mkLib pkgs).overrideToolchain (_: fenixPkgs.stable.toolchain); @@ -88,9 +170,17 @@ crossArgs = { inherit src; strictDeps = true; - cargoExtraArgs = "--locked --no-default-features -p crabidy-server"; + # web-ui is a default feature; keep it on so the embedded UI ships. + cargoExtraArgs = "--locked -p crabidy-server"; CARGO_BUILD_TARGET = muslTarget; + # crabidy-server's build.rs embeds cbd-web/dist (feature `web-ui`). + # Stage the prebuilt wasm bundle there before the crate compiles. + preBuild = '' + rm -rf cbd-web/dist + cp -rL --no-preserve=mode,ownership ${webBundle} cbd-web/dist + ''; + # Build scripts / proc-macros compile for the build host; deps for the # target use the cross toolchain. protoc + pkg-config are host tools. nativeBuildInputs = [