1{ 2 description = "whiskers: Rust core + Android shell for a talking cat on a Fire tablet"; 3 4 inputs = { 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 }; 7 8 outputs = 9 { nixpkgs, ... }: 10 let 11 system = "x86_64-linux"; 12 pkgs = nixpkgs.legacyPackages.${system}; 13 14 # celld, Deno Land's self-hosted Durable Objects host, from its release binary: the 15 # asset's sha256 is the one GitHub publishes for it, and the build attests to commit f2bf648 16 # (`gh attestation verify celld-x86_64-unknown-linux-gnu.gz --repo denoland/celld`, 2026-10-05). 17 # Not in nixpkgs. Used by `celld dev` for backend/worker. 18 celld = pkgs.stdenv.mkDerivation rec { 19 pname = "celld"; 20 version = "0.6.1"; 21 src = pkgs.fetchurl { 22 url = "https://github.com/denoland/celld/releases/download/v${version}/celld-x86_64-unknown-linux-gnu.gz"; 23 hash = "sha256-eaglPP9dTopKn3omEeOTOQ9/6QJfAOiEZ4dbAHxEhms="; 24 }; 25 dontUnpack = true; 26 nativeBuildInputs = [ pkgs.autoPatchelfHook ]; 27 buildInputs = [ pkgs.stdenv.cc.cc.lib ]; 28 installPhase = '' 29 install -d $out/bin 30 gzip -dc $src > $out/bin/celld 31 chmod 755 $out/bin/celld 32 ''; 33 meta.mainProgram = "celld"; 34 }; 35 36 # whiskersd, the service the tablet talks to, built from the workspace so nixos-config can run it as a real 37 # service (modules/whiskers/service.nix there). Only what the build reads is in the source: a change to the 38 # Android app, the website or the docs leaves this derivation, and so the running service, alone. 39 # 40 # The jevcrates submodule is in the source only when this flake is fetched with submodules, so a consumer takes 41 # it as `git+file:///home/nixos/whiskers?submodules=1` and a local build is `nix build '.?submodules=1#whiskersd'`. 42 # Without them the build stops at the first path dependency instead of building something else. 43 mkWhiskersd = rustPlatform: rustPlatform.buildRustPackage { 44 pname = "whiskersd"; 45 version = "0.0.0"; 46 src = pkgs.lib.fileset.toSource { 47 root = ./.; 48 fileset = pkgs.lib.fileset.unions [ 49 ./Cargo.toml 50 ./Cargo.lock 51 ./crates 52 ./third-party 53 ]; 54 }; 55 cargoLock = { 56 lockFile = ./Cargo.lock; 57 # jevcrates takes rustls-rustcrypto from git (no release has the version it needs); the hash is the 58 # fetched tree, so it moves with the rev pinned in Cargo.lock. 59 outputHashes."rustls-rustcrypto-0.0.2-alpha" = "sha256-tkaRZgDoaP0cuajGcfNvayKh2xgXxhJ6YXLCrSZ3JUE="; 60 }; 61 cargoBuildFlags = [ "-p" "whiskersd" ]; 62 cargoTestFlags = [ "-p" "whiskersd" ]; 63 meta.mainProgram = "whiskersd"; 64 }; 65 whiskersd = mkWhiskersd pkgs.rustPlatform; 66 # The same, linked statically against musl, so one file runs on any x86-64 Linux with no nix store: this is 67 # what a release carries. `nix build '.?submodules=1#whiskersd-static'`. 68 whiskersd-static = mkWhiskersd pkgs.pkgsStatic.rustPlatform; 69 in 70 { 71 packages.${system} = { inherit celld whiskersd whiskersd-static; }; 72 73 devShells.${system} = rec { 74 # The toolchain is mise's, written in mise.toml (Rust, the Android SDK and NDK, JDK, Gradle, wasm-bindgen, 75 # wrangler, hk, pitchfork, fnox, usage); anyone can use it without nix: see README.md. This shell only wraps 76 # it: mise itself, plus the native things a downloaded toolchain cannot bring (a C compiler and linker, 77 # pkg-config, OpenSSL for crates that link it, curl, unzip and bzip2 for the fetch scripts, git). 78 # 79 # Entering it puts whatever `mise install` has already installed on PATH (it does not install anything 80 # itself: the first install is large). Downloaded programs are ordinary dynamically linked binaries; this 81 # machine's NixOS runs them through nix-ld (NIX_LD below tells nix-ld where its libraries are). Where 82 # nix-ld is not enabled, use `nix develop .#fhs`. 83 default = pkgs.mkShell { 84 packages = [ 85 pkgs.mise 86 pkgs.gcc 87 pkgs.pkg-config 88 pkgs.openssl 89 pkgs.curl 90 pkgs.unzip 91 pkgs.bzip2 92 pkgs.git 93 pkgs.cacert 94 ]; 95 NIX_LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ pkgs.stdenv.cc.cc.lib pkgs.zlib pkgs.openssl ]; 96 shellHook = '' 97 root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" 98 if [ -f "$root/mise.toml" ]; then 99 export MISE_TRUSTED_CONFIG_PATHS="$root''${MISE_TRUSTED_CONFIG_PATHS:+:$MISE_TRUSTED_CONFIG_PATHS}" 100 eval "$(mise env -s bash 2>/dev/null)" || true 101 fi 102 ''; 103 }; 104 105 # The same, inside an FHS root (bubblewrap), for a machine without nix-ld: downloaded programs find 106 # /lib64/ld-linux-x86-64.so.2 and the usual libraries where they expect them. 107 fhs = (pkgs.buildFHSEnv { 108 name = "whiskers-fhs"; 109 targetPkgs = p: [ 110 p.mise p.gcc p.pkg-config p.openssl p.curl p.unzip p.bzip2 p.git p.cacert p.zlib p.stdenv.cc.cc.lib 111 ]; 112 runScript = "bash"; 113 }).env; 114 115 # The names these shells had before the toolchain moved to mise.toml. 116 web = default; 117 backend = default; 118 android = default; 119 android-emu = default; 120 }; 121 }; 122}