nandi/frqpublic Fork 0
ae207b8c4aecfb8a781e6ea4ef2d3802bb6e68cf
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

flake.nix · 225 lines · 8.4 KBNix Blame HistoryRaw
Build the client with Nix, not just a shell for it ca3afbe nandi 19d ago1{
2 # frq is Jolt source, so "building" it is three things, not one:
3 #
4 # jolt the runtime that reads it (github:jolt-lang/jolt)
5 # jolt-native libvidya and libjoltmoq, in Rust (gitlab:nandithebull/jolt-native)
6 # frq this tree, with its deps resolved to store paths
7 #
8 # Jolt resolves deps.edn by running git at startup, which a build sandbox has
9 # no network for — so every dep is fetched by Nix instead and handed back as
10 # a :local/root through -Sdeps.
11 #
12 # nix build .#frq && ./result/bin/frq
13 #
14 # On a machine that is not NixOS the GL driver is the host's and the loader
15 # will not find it, so the window never opens ("GL display: argument does not
Find the host's GL driver when the store's is not the system's 633faad nandi 19d ago16 # name a valid config"). The launcher handles that itself: off NixOS it hands
17 # the process to nixGL, which puts the host's driver ahead of the store's.
18 # Nothing extra to type, and a distrobox/container Arch is the same case as
19 # a bare one.
Build the client with Nix, not just a shell for it ca3afbe nandi 19d ago20 description = "frq a freeq client in jolt";
21
22 inputs = {
23 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
24 # Jolt's own flake declares `self.submodules`, which this Nix rejects when
25 # the flake is fetched through the github scheme — so take the source and
26 # build it here. `vendor/` is a submodule and the build needs it.
27 jolt-src = {
28 url = "git+https://github.com/jolt-lang/jolt?submodules=1";
29 flake = false;
30 };
31
32 jolt-native = {
33 url = "git+https://gitlab.com/nandithebull/jolt-native";
34 flake = false;
35 };
36
37 # The sha deps.edn pins, on the fork with the reconciler fixes.
38 glimmer = {
39 url = "git+https://gitlab.com/nandithebull/glimmer?rev=399df371c790d690fb6e4560c3d4d7f838502857";
40 flake = false;
41 };
Find the host's GL driver when the store's is not the system's 633faad nandi 19d ago42
43 # Only ever used off NixOS, to put the host GL driver on the loader path.
44 nixgl = {
45 url = "github:nix-community/nixGL";
46 inputs.nixpkgs.follows = "nixpkgs";
47 };
Build the client with Nix, not just a shell for it ca3afbe nandi 19d ago48 };
49
Find the host's GL driver when the store's is not the system's 633faad nandi 19d ago50 outputs = { self, nixpkgs, jolt-src, jolt-native, glimmer, nixgl }:
Build the client with Nix, not just a shell for it ca3afbe nandi 19d ago51 let
52 systems = [ "x86_64-linux" "aarch64-linux" ];
53 forEachSystem = f:
54 nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
55 in
56 {
57 packages = forEachSystem (pkgs:
58 let
59 inherit (pkgs) lib;
60
Find the host's GL driver when the store's is not the system's 633faad nandi 19d ago61 # Mesa, despite the name: it covers Intel and AMD alike. The NVIDIA
62 # wrappers are the ones that need --impure (they read the host kernel
63 # module's version), which is why this only ever reaches for Intel.
64 nixGL = nixgl.packages.${pkgs.stdenv.hostPlatform.system}.nixGLIntel;
65
Build the client with Nix, not just a shell for it ca3afbe nandi 19d ago66 # libvidya (the retained-tree ABI glimmer-vidya binds, on egui) and
67 # libjoltmoq (the AV media plane). One workspace, two cdylibs.
68 native = pkgs.rustPlatform.buildRustPackage {
69 pname = "jolt-native";
70 version = "0.1.0";
71 src = jolt-native;
72
73 cargoLock = {
74 lockFile = "${jolt-native}/Cargo.lock";
75 allowBuiltinFetchGit = true;
76 };
77
78 nativeBuildInputs = with pkgs; [
79 pkg-config
80 cmake
81 rustPlatform.bindgenHook
82 ];
83
84 buildInputs = with pkgs; [
85 alsa-lib
86 pipewire
87 openssl
88 libxkbcommon
89 wayland
90 libGL
91 ];
92
93 # Upstream's .cargo/config.toml drives the whole build through
94 # DotSlash: a pinned rustc, sccache, and zig as the C/C++ compiler
95 # and linker, each fetched from the network on first use. None of
96 # that survives a build sandbox, and none of it is needed when the
97 # toolchain comes from the store — so drop it and let stdenv's cc
98 # link (openh264 is C++, which stdenv covers too).
99 postPatch = ''
100 rm -f .cargo/config.toml
101 '';
102
103 # bindgen reads linux/videodev2.h directly; upstream points it at
104 # zig's bundled headers, which under Nix is just the kernel headers.
105 V4L2R_VIDEODEV2_H_PATH = "${pkgs.linuxHeaders}/include";
106
107 doCheck = false;
108
109 installPhase = ''
110 runHook preInstall
111 mkdir -p "$out/lib"
112 install -m644 target/*/release/*.so "$out/lib/"
113 runHook postInstall
114 '';
115 };
116
117 # Jolt itself: Clojure on Chez, built the way its own flake builds it.
118 joltRuntime = pkgs.stdenv.mkDerivation {
119 pname = "jolt";
120 version = "dev";
121 src = jolt-src;
122
123 strictDeps = true;
124 nativeBuildInputs = with pkgs; [ chez makeWrapper pkg-config xxd ];
125 buildInputs = with pkgs; [ lz4 zlib ncurses openssl libuuid ];
126
127 JOLT_VERSION = "dev";
128 dontConfigure = true;
129
130 buildPhase = ''
131 runHook preBuild
132 scheme --script host/chez/build-jolt.ss release target/release/jolt
133 runHook postBuild
134 '';
135
136 installPhase = ''
137 runHook preInstall
138 mkdir -p "$out/bin"
139 install -m755 target/release/jolt "$out/bin/jolt"
140 runHook postInstall
141 '';
142
143 # jolt.deps shells out to git and unzip, and jolt.mvn-http dlopens
144 # OpenSSL through the JOLT_OPENSSL_LIBDIR seam.
145 postFixup = ''
146 wrapProgram "$out/bin/jolt" \
147 --prefix PATH : "${pkgs.lib.makeBinPath [ pkgs.git pkgs.unzip ]}" \
148 --set-default JOLT_OPENSSL_LIBDIR "${pkgs.lib.makeLibraryPath [ pkgs.openssl ]}" \
149 --set-default SSL_CERT_FILE "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"
150 '';
151 };
152
153 # glimmer-vidya lives inside the jolt-native checkout, and its own
154 # deps.edn asks for glimmer by git — the top-level override below
155 # answers for both.
156 glimmerVidya = "${jolt-native}/jolt/glimmer-vidya";
157
158 # egui reaches for these with dlopen rather than linking them, so
159 # being in the cdylib's buildInputs is not enough — the launcher has
160 # to put them on the loader path itself. Without libX11 here, vidya
161 # reports "X11 unavailable", falls back to Wayland, and winit refuses
162 # to build a second event loop after the failed first one.
163 runtimeLibs = with pkgs; [
164 libGL
165 libxkbcommon
166 wayland
167 xorg.libX11
168 xorg.libXcursor
169 xorg.libXi
170 xorg.libXrandr
171 vulkan-loader
172 ];
173
174 # The project as jolt sees it: source, deps.edn, nothing else.
175 frqSource = pkgs.runCommand "frq-source" { } ''
176 mkdir -p "$out"
177 cp -r ${self}/src ${self}/deps.edn "$out/"
178 '';
179
180 # Jolt resolves deps.edn from the working directory, so the launcher
181 # runs from the store copy. Its .jolt/cpcache write lands on a
182 # read-only directory and jolt treats that as a quiet cache miss, so
183 # the only cost is re-resolving the (already local) graph per start.
184 frqScript = pkgs.writeShellScript "frq" ''
185 export LD_LIBRARY_PATH="${native}/lib:${lib.makeLibraryPath runtimeLibs}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
186 cd ${frqSource}
Find the host's GL driver when the store's is not the system's 633faad nandi 19d ago187
188 # On NixOS the store's Mesa is the system's and the window opens.
189 # Anywhere else the real driver is the host's, so defer to nixGL
190 # it prepends the host driver, which has to win over ours.
191 runner=""
192 [ -e /run/current-system ] || runner="${nixGL}/bin/nixGLIntel"
193
194 exec ''${runner} ${joltRuntime}/bin/jolt \
Build the client with Nix, not just a shell for it ca3afbe nandi 19d ago195 -Sdeps '{:deps {jolt-lang/glimmer {:local/root "${glimmer}"} nandi/glimmer-vidya {:local/root "${glimmerVidya}"}}}' \
196 -M:frq "$@"
197 '';
198
199 frq = pkgs.runCommand "frq-0.1.0"
200 {
201 meta = {
202 description = "A freeq client in jolt";
203 mainProgram = "frq";
204 platforms = systems;
205 };
206 }
207 ''
208 mkdir -p "$out/bin"
209 ln -s ${frqScript} "$out/bin/frq"
210 '';
211 in
212 {
213 inherit native frq;
214 jolt = joltRuntime;
215 default = frq;
216 });
217
218 apps = forEachSystem (pkgs: {
219 default = {
220 type = "app";
221 program = "${self.packages.${pkgs.stdenv.hostPlatform.system}.frq}/bin/frq";
222 };
223 });
224 };
225}