nandi/frqpublic Fork 0
472e179
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.

Take the Android objects from jolt-native's CI, always the latest

jolt-native publishes prebuilt arm64 objects per build now, so an APK no
longer composes an NDK and a Rust cross toolchain to produce two files
upstream already built. They arrive as a flake input at a 'latest' alias,
and scripts/apk.bb re-resolves that one input before every build, so
'latest' means latest rather than whatever the lock first recorded.

The archive carries include/ and libc++_shared.so besides, which retires
the separate glue pin and the composed NDK's copy of the C++ runtime --
this one is what the libraries were actually linked against.

The source input moves to d970307c for the glimmer-backends/ rename;
desktop still builds from the flake, where the published desktop tarball
would carry RUNPATHs into the builder's store.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-07T22:16:54-07:00 Browse files
472e179 parent: 618f3f9
modified flake.lock +19 -5
@@ -155,20 +155,33 @@
155155 "rust-overlay": "rust-overlay"
156156 },
157157 "locked": {
158- "lastModified": 1788725141,
159- "narHash": "sha256-W7pCZAO9QTEXqk7c4t5rv1w2ESGi5o+bLQvCs1dNv2Y=",
158+ "lastModified": 1788842653,
159+ "narHash": "sha256-x8MK9ftM0Ya0hh4luXEasLVaTbMUOI8NAevN7pgd/aE=",
160160 "ref": "refs/heads/main",
161- "rev": "16408ca25dde0dc34bec4930ba79a6cf5adedc0c",
162- "revCount": 48,
161+ "rev": "d970307ccf1fe67e2e971f2837d2282d8ba79a62",
162+ "revCount": 64,
163163 "type": "git",
164164 "url": "https://gitlab.com/nandithebull/jolt-native"
165165 },
166166 "original": {
167- "rev": "16408ca25dde0dc34bec4930ba79a6cf5adedc0c",
167+ "rev": "d970307ccf1fe67e2e971f2837d2282d8ba79a62",
168168 "type": "git",
169169 "url": "https://gitlab.com/nandithebull/jolt-native"
170170 }
171171 },
172+ "jolt-native-android": {
173+ "flake": false,
174+ "locked": {
175+ "lastModified": 1788844464,
176+ "narHash": "sha256-HgVSQR2XiS3De/gP9Z1JZ2Tqj4yPzzN6mx2Xyp6DuRg=",
177+ "type": "tarball",
178+ "url": "https://gitlab.com/api/v4/projects/nandithebull%2Fjolt-native/packages/generic/jolt-native/latest/android-arm64-v8a.tar.gz"
179+ },
180+ "original": {
181+ "type": "tarball",
182+ "url": "https://gitlab.com/api/v4/projects/nandithebull%2Fjolt-native/packages/generic/jolt-native/latest/android-arm64-v8a.tar.gz"
183+ }
184+ },
172185 "jolt-src": {
173186 "inputs": {
174187 "makes": "makes_2",
@@ -297,6 +310,7 @@
297310 "glimmer": "glimmer",
298311 "jolt-android-src": "jolt-android-src",
299312 "jolt-native": "jolt-native",
313+ "jolt-native-android": "jolt-native-android",
300314 "jolt-src": "jolt-src",
301315 "nix-appimage": "nix-appimage",
302316 "nixgl": "nixgl",
@@ -155,20 +155,33 @@
155 "rust-overlay": "rust-overlay"155 "rust-overlay": "rust-overlay"
156 },156 },
157 "locked": {157 "locked": {
158- "lastModified": 1788725141,158+ "lastModified": 1788842653,
159- "narHash": "sha256-W7pCZAO9QTEXqk7c4t5rv1w2ESGi5o+bLQvCs1dNv2Y=",159+ "narHash": "sha256-x8MK9ftM0Ya0hh4luXEasLVaTbMUOI8NAevN7pgd/aE=",
160 "ref": "refs/heads/main",160 "ref": "refs/heads/main",
161- "rev": "16408ca25dde0dc34bec4930ba79a6cf5adedc0c",161+ "rev": "d970307ccf1fe67e2e971f2837d2282d8ba79a62",
162- "revCount": 48,162+ "revCount": 64,
163 "type": "git",163 "type": "git",
164 "url": "https://gitlab.com/nandithebull/jolt-native"164 "url": "https://gitlab.com/nandithebull/jolt-native"
165 },165 },
166 "original": {166 "original": {
167- "rev": "16408ca25dde0dc34bec4930ba79a6cf5adedc0c",167+ "rev": "d970307ccf1fe67e2e971f2837d2282d8ba79a62",
168 "type": "git",168 "type": "git",
169 "url": "https://gitlab.com/nandithebull/jolt-native"169 "url": "https://gitlab.com/nandithebull/jolt-native"
170 }170 }
171 },171 },
172+ "jolt-native-android": {
173+ "flake": false,
174+ "locked": {
175+ "lastModified": 1788844464,
176+ "narHash": "sha256-HgVSQR2XiS3De/gP9Z1JZ2Tqj4yPzzN6mx2Xyp6DuRg=",
177+ "type": "tarball",
178+ "url": "https://gitlab.com/api/v4/projects/nandithebull%2Fjolt-native/packages/generic/jolt-native/latest/android-arm64-v8a.tar.gz"
179+ },
180+ "original": {
181+ "type": "tarball",
182+ "url": "https://gitlab.com/api/v4/projects/nandithebull%2Fjolt-native/packages/generic/jolt-native/latest/android-arm64-v8a.tar.gz"
183+ }
184+ },
172 "jolt-src": {185 "jolt-src": {
173 "inputs": {186 "inputs": {
174 "makes": "makes_2",187 "makes": "makes_2",
@@ -297,6 +310,7 @@
297 "glimmer": "glimmer",310 "glimmer": "glimmer",
298 "jolt-android-src": "jolt-android-src",311 "jolt-android-src": "jolt-android-src",
299 "jolt-native": "jolt-native",312 "jolt-native": "jolt-native",
313+ "jolt-native-android": "jolt-native-android",
300 "jolt-src": "jolt-src",314 "jolt-src": "jolt-src",
301 "nix-appimage": "nix-appimage",315 "nix-appimage": "nix-appimage",
302 "nixgl": "nixgl",316 "nixgl": "nixgl",
modified flake.nix +28 -11
@@ -38,10 +38,11 @@
3838 inputs.nixpkgs.follows = "nixpkgs";
3939 };
4040
41- # Ahead of v0.1.3, which is what nix/android.nix pins the APK to — and
42- # deliberately: that pin is the last release, and this is what `just run`
43- # builds, so a change to jolt-native can be run before there is a release
44- # to fetch. The two meet again at `just bump`.
41+ # The source half of jolt-native: the Jolt code under glimmer-backends/ that
42+ # binds the native objects, and the flake that builds the desktop ones. The
43+ # Android objects no longer come from here — jolt-native-android below
44+ # fetches those prebuilt — so this input is what `just run` builds against
45+ # and what an APK's Clojure side is read from, both at this rev.
4546 #
4647 # Pinned all the same, and pinned to a rev: this input carries both halves of
4748 # glimmer-vidya — libvidya, and the Jolt side that binds it — so an
@@ -55,10 +56,26 @@
5556 # drift this comment warns about wearing a different hat: one input, and
5657 # the window and the terminal are the same library either way.
5758 jolt-native = {
58- url = "git+https://gitlab.com/nandithebull/jolt-native?rev=16408ca25dde0dc34bec4930ba79a6cf5adedc0c";
59+ url = "git+https://gitlab.com/nandithebull/jolt-native?rev=d970307ccf1fe67e2e971f2837d2282d8ba79a62";
5960 inputs.nixpkgs.follows = "nixpkgs";
6061 };
6162
63+ # The Android objects, prebuilt by jolt-native's CI rather than compiled
64+ # here: an APK needs libvidya and libjoltmoq for arm64, and building them
65+ # locally means an NDK, a Rust cross toolchain and the whole crane graph
66+ # for two files that upstream already built and published.
67+ #
68+ # "latest" is the version its CI overwrites on every default-branch build,
69+ # so this input finds a new one on `nix flake update` -- but flake.lock
70+ # still records exactly which bytes an APK was built from, which is the
71+ # pin that matters. `just bump` decides when to move; this only decides
72+ # where to look. The archive is rooted at include/ and lib/arm64-v8a/, so
73+ # nothing here has to unpack it.
74+ jolt-native-android = {
75+ url = "https://gitlab.com/api/v4/projects/nandithebull%2Fjolt-native/packages/generic/jolt-native/latest/android-arm64-v8a.tar.gz";
76+ flake = false;
77+ };
78+
6279 # Chez itself, because the APK needs a cross target nixpkgs does not
6380 # build: frq's Scheme is compiled to an arm64 boot image, and that wants
6481 # Chez's own `tarm64le` workarea — boot files, xpatch and libkernel.a.
@@ -100,7 +117,7 @@
100117 };
101118 };
102119
103- outputs = { self, nixpkgs, jolt-src, jolt-native, glimmer, chez-src, jolt-android-src, nixgl, nix-appimage }:
120+ outputs = { self, nixpkgs, jolt-src, jolt-native, jolt-native-android, glimmer, chez-src, jolt-android-src, nixgl, nix-appimage }:
104121 let
105122 systems = [ "x86_64-linux" "aarch64-linux" ];
106123 forEachSystem = f:
@@ -220,8 +237,8 @@
220237 # glimmer-vidya lives inside the jolt-native checkout, and its own
221238 # deps.edn asks for glimmer by git — the top-level override below
222239 # answers for both.
223- glimmerVidya = "${jolt-native}/jolt/glimmer-vidya";
224- glimmerTui = "${jolt-native}/jolt/glimmer-tui";
240+ glimmerVidya = "${jolt-native}/glimmer-backends/glimmer-vidya";
241+ glimmerTui = "${jolt-native}/glimmer-backends/glimmer-tui";
225242
226243 runtimeLibs = runtimeLibsFor pkgs;
227244
@@ -310,7 +327,7 @@
310327 };
311328
312329 android = import ./nix/android.nix {
313- inherit pkgs self chez-src jolt-native glimmer joltAndroid;
330+ inherit pkgs self chez-src jolt-native jolt-native-android glimmer joltAndroid;
314331 inherit (pkgs) lib;
315332 androidSdk = androidComposition.androidsdk;
316333 ndk = androidComposition.ndk-bundle;
@@ -390,8 +407,8 @@
390407 # answers. Naming these is also what makes the shell build them.
391408 JOLT_NATIVE_LIB = "${native}/lib";
392409 GLIMMER_SRC = glimmer;
393- GLIMMER_VIDYA_SRC = "${jolt-native}/jolt/glimmer-vidya";
394- GLIMMER_TUI_SRC = "${jolt-native}/jolt/glimmer-tui";
410+ GLIMMER_VIDYA_SRC = "${jolt-native}/glimmer-backends/glimmer-vidya";
411+ GLIMMER_TUI_SRC = "${jolt-native}/glimmer-backends/glimmer-tui";
395412 FRQ_LIB_PATH = lib.makeLibraryPath (runtimeLibsFor pkgs);
396413 NIXGL = "${nixGLFor pkgs}/bin/nixGLIntel";
397414 };
@@ -38,10 +38,11 @@
38 inputs.nixpkgs.follows = "nixpkgs";38 inputs.nixpkgs.follows = "nixpkgs";
39 };39 };
40 40
41- # Ahead of v0.1.3, which is what nix/android.nix pins the APK to — and41+ # The source half of jolt-native: the Jolt code under glimmer-backends/ that
42- # deliberately: that pin is the last release, and this is what `just run`42+ # binds the native objects, and the flake that builds the desktop ones. The
43- # builds, so a change to jolt-native can be run before there is a release43+ # Android objects no longer come from here — jolt-native-android below
44- # to fetch. The two meet again at `just bump`.44+ # fetches those prebuilt — so this input is what `just run` builds against
45+ # and what an APK's Clojure side is read from, both at this rev.
45 #46 #
46 # Pinned all the same, and pinned to a rev: this input carries both halves of47 # Pinned all the same, and pinned to a rev: this input carries both halves of
47 # glimmer-vidya — libvidya, and the Jolt side that binds it — so an48 # glimmer-vidya — libvidya, and the Jolt side that binds it — so an
@@ -55,10 +56,26 @@
55 # drift this comment warns about wearing a different hat: one input, and56 # drift this comment warns about wearing a different hat: one input, and
56 # the window and the terminal are the same library either way.57 # the window and the terminal are the same library either way.
57 jolt-native = {58 jolt-native = {
58- url = "git+https://gitlab.com/nandithebull/jolt-native?rev=16408ca25dde0dc34bec4930ba79a6cf5adedc0c";59+ url = "git+https://gitlab.com/nandithebull/jolt-native?rev=d970307ccf1fe67e2e971f2837d2282d8ba79a62";
59 inputs.nixpkgs.follows = "nixpkgs";60 inputs.nixpkgs.follows = "nixpkgs";
60 };61 };
61 62
63+ # The Android objects, prebuilt by jolt-native's CI rather than compiled
64+ # here: an APK needs libvidya and libjoltmoq for arm64, and building them
65+ # locally means an NDK, a Rust cross toolchain and the whole crane graph
66+ # for two files that upstream already built and published.
67+ #
68+ # "latest" is the version its CI overwrites on every default-branch build,
69+ # so this input finds a new one on `nix flake update` -- but flake.lock
70+ # still records exactly which bytes an APK was built from, which is the
71+ # pin that matters. `just bump` decides when to move; this only decides
72+ # where to look. The archive is rooted at include/ and lib/arm64-v8a/, so
73+ # nothing here has to unpack it.
74+ jolt-native-android = {
75+ url = "https://gitlab.com/api/v4/projects/nandithebull%2Fjolt-native/packages/generic/jolt-native/latest/android-arm64-v8a.tar.gz";
76+ flake = false;
77+ };
78+
62 # Chez itself, because the APK needs a cross target nixpkgs does not79 # Chez itself, because the APK needs a cross target nixpkgs does not
63 # build: frq's Scheme is compiled to an arm64 boot image, and that wants80 # build: frq's Scheme is compiled to an arm64 boot image, and that wants
64 # Chez's own `tarm64le` workarea — boot files, xpatch and libkernel.a.81 # Chez's own `tarm64le` workarea — boot files, xpatch and libkernel.a.
@@ -100,7 +117,7 @@
100 };117 };
101 };118 };
102 119
103- outputs = { self, nixpkgs, jolt-src, jolt-native, glimmer, chez-src, jolt-android-src, nixgl, nix-appimage }:120+ outputs = { self, nixpkgs, jolt-src, jolt-native, jolt-native-android, glimmer, chez-src, jolt-android-src, nixgl, nix-appimage }:
104 let121 let
105 systems = [ "x86_64-linux" "aarch64-linux" ];122 systems = [ "x86_64-linux" "aarch64-linux" ];
106 forEachSystem = f:123 forEachSystem = f:
@@ -220,8 +237,8 @@
220 # glimmer-vidya lives inside the jolt-native checkout, and its own237 # glimmer-vidya lives inside the jolt-native checkout, and its own
221 # deps.edn asks for glimmer by git — the top-level override below238 # deps.edn asks for glimmer by git — the top-level override below
222 # answers for both.239 # answers for both.
223- glimmerVidya = "${jolt-native}/jolt/glimmer-vidya";240+ glimmerVidya = "${jolt-native}/glimmer-backends/glimmer-vidya";
224- glimmerTui = "${jolt-native}/jolt/glimmer-tui";241+ glimmerTui = "${jolt-native}/glimmer-backends/glimmer-tui";
225 242
226 runtimeLibs = runtimeLibsFor pkgs;243 runtimeLibs = runtimeLibsFor pkgs;
227 244
@@ -310,7 +327,7 @@
310 };327 };
311 328
312 android = import ./nix/android.nix {329 android = import ./nix/android.nix {
313- inherit pkgs self chez-src jolt-native glimmer joltAndroid;330+ inherit pkgs self chez-src jolt-native jolt-native-android glimmer joltAndroid;
314 inherit (pkgs) lib;331 inherit (pkgs) lib;
315 androidSdk = androidComposition.androidsdk;332 androidSdk = androidComposition.androidsdk;
316 ndk = androidComposition.ndk-bundle;333 ndk = androidComposition.ndk-bundle;
@@ -390,8 +407,8 @@
390 # answers. Naming these is also what makes the shell build them.407 # answers. Naming these is also what makes the shell build them.
391 JOLT_NATIVE_LIB = "${native}/lib";408 JOLT_NATIVE_LIB = "${native}/lib";
392 GLIMMER_SRC = glimmer;409 GLIMMER_SRC = glimmer;
393- GLIMMER_VIDYA_SRC = "${jolt-native}/jolt/glimmer-vidya";410+ GLIMMER_VIDYA_SRC = "${jolt-native}/glimmer-backends/glimmer-vidya";
394- GLIMMER_TUI_SRC = "${jolt-native}/jolt/glimmer-tui";411+ GLIMMER_TUI_SRC = "${jolt-native}/glimmer-backends/glimmer-tui";
395 FRQ_LIB_PATH = lib.makeLibraryPath (runtimeLibsFor pkgs);412 FRQ_LIB_PATH = lib.makeLibraryPath (runtimeLibsFor pkgs);
396 NIXGL = "${nixGLFor pkgs}/bin/nixGLIntel";413 NIXGL = "${nixGLFor pkgs}/bin/nixGLIntel";
397 };414 };
modified justfile +3 -1
@@ -12,7 +12,9 @@ default:
1212 apk action="build":
1313 scripts/apk.bb {{action}}
1414
15-# Every jolt-native pin — nix/android.nix and deps.edn — at a release.
15+# The jolt-native source pin — deps.edn and the flake input — at a release. The
16+# Android objects are not pinned here any more; `just apk` takes the latest CI
17+# build of those on every run.
1618 bump tag="":
1719 scripts/bump-jolt-native.bb {{tag}}
1820
@@ -12,7 +12,9 @@ default:
12 apk action="build":12 apk action="build":
13 scripts/apk.bb {{action}}13 scripts/apk.bb {{action}}
14 14
15-# Every jolt-native pin — nix/android.nix and deps.edn — at a release.15+# The jolt-native source pin — deps.edn and the flake input — at a release. The
16+# Android objects are not pinned here any more; `just apk` takes the latest CI
17+# build of those on every run.
16 bump tag="":18 bump tag="":
17 scripts/bump-jolt-native.bb {{tag}}19 scripts/bump-jolt-native.bb {{tag}}
18 20
modified nix/android.nix +20 -35
@@ -25,7 +25,7 @@
2525 # The steps are the ones the graph before it ran, in the same order; where a
2626 # genrule read a path out of `read_root_config`, a derivation takes an
2727 # argument.
28-{ pkgs, lib, self, chez-src, jolt-native, glimmer, joltAndroid, androidSdk, ndk }:
28+{ pkgs, lib, self, chez-src, jolt-native, jolt-native-android, glimmer, joltAndroid, androidSdk, ndk }:
2929
3030 let
3131 # What the APK targets, in the three spellings the tools want it in.
@@ -47,45 +47,30 @@ let
4747 ndkBin = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/bin";
4848 cc = "${ndkBin}/aarch64-linux-android${apiLevel}-clang";
4949
50- # What comes out of jolt-native's releases. These two pins are the whole of
51- # what `just bump` moves on the native side — a desktop run builds the flake
52- # input instead, so this is the only place a release is fetched. Do not edit
53- # them by hand: bump-jolt-native.bb fetches each archive, weighs it, and
54- # writes both the url and the digest below.
50+ # What comes out of jolt-native's CI, as a flake input rather than a fetchurl:
51+ # nix unpacks a tarball input itself, and flake.lock holds the digest that
52+ # used to be written here by hand. `just bump` moves it with
53+ # `nix flake update jolt-native-android` and nothing in this file changes.
5554 #
5655 # One archive, two libraries: libvidya (the retained-tree UI) and libjoltmoq
5756 # (the AV media plane). They are built together and only make sense together
5857 # — libjoltapp links both — so there is one pin for the pair rather than two
59- # that could drift apart.
60- nativeRelease = pkgs.fetchurl {
61- url = "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz";
62- sha256 = "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108";
63- };
64-
65- glue = pkgs.fetchurl {
66- url = "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz";
67- sha256 = "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5";
68- };
69-
70- # Unpacked once, so the consumers below name files rather than repeat the tar.
71- nativeLibs = pkgs.runCommand "jolt-native-android" { } ''
72- mkdir -p "$out"
73- tar -xzf ${nativeRelease} -C "$out"
74- '';
75-
76- glueSrc = pkgs.runCommand "jolt-android-glue" { } ''
77- mkdir -p "$out"
78- tar -xzf ${glue} -C "$out" --strip-components=1
79- '';
58+ # that could drift apart. It carries include/ and libc++_shared.so besides,
59+ # which is why the glue's headers and the C++ runtime come from here too.
60+ nativeLibs = jolt-native-android;
8061
81- # The C++ runtime, out of the same NDK the glue is compiled with.
62+ # The C++ runtime, out of the archive rather than the NDK composed here.
8263 #
8364 # openh264 is C++, and its build script asks to be linked against
8465 # `libc++_shared.so` by name — so libjoltmoq carries that as a DT_NEEDED. An
8566 # app's linker namespace will not hand out the platform's own copy (there is
8667 # no stable one to hand out), so the APK carries it, exactly as it carries
8768 # OpenSSL below and for the same reason.
88- libcxx = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so";
69+ #
70+ # jolt-native ships it beside the libraries that need it, so this is the copy
71+ # they were actually linked against — where the NDK path was whichever
72+ # revision `composeAndroidPackages` happened to resolve here.
73+ libcxx = "${nativeLibs}/lib/${abi}/libc++_shared.so";
8974
9075 # --- Chez's arm64 cross target ------------------------------------------
9176 # The one piece with no nixpkgs equivalent: `pkgs.chez` builds a Scheme for
@@ -261,14 +246,14 @@ let
261246 # crash on the phone.
262247 libjoltapp = pkgs.runCommand "libjoltapp.so" { } ''
263248 mkdir -p lib
264- cp ${nativeLibs}/libvidya.so lib/libvidya.so
265- cp ${nativeLibs}/libjoltmoq.so lib/libjoltmoq.so
249+ cp ${nativeLibs}/lib/${abi}/libvidya.so lib/libvidya.so
250+ cp ${nativeLibs}/lib/${abi}/libjoltmoq.so lib/libjoltmoq.so
266251
267252 ${cc} -shared -fPIC -O2 -o "$out" \
268- ${glueSrc}/android/jolt_main.c \
253+ ${jolt-native}/android/jolt_main.c \
269254 ${joltBootObj} \
270255 -I${joltBoot} \
271- -I${glueSrc}/include \
256+ -I${nativeLibs}/include \
272257 -Llib \
273258 ${chezAndroid}/tarm64le/boot/tarm64le/libkernel.a \
274259 ${chezAndroid}/lz4/lib/liblz4.a \
@@ -341,8 +326,8 @@ let
341326 nativeBuildInputs = [ pkgs.zip ];
342327 } ''
343328 mkdir -p stage/lib/${abi}
344- cp ${nativeLibs}/libvidya.so stage/lib/${abi}/libvidya.so
345- cp ${nativeLibs}/libjoltmoq.so stage/lib/${abi}/libjoltmoq.so
329+ cp ${nativeLibs}/lib/${abi}/libvidya.so stage/lib/${abi}/libvidya.so
330+ cp ${nativeLibs}/lib/${abi}/libjoltmoq.so stage/lib/${abi}/libjoltmoq.so
346331 cp ${libcxx} stage/lib/${abi}/libc++_shared.so
347332 cp ${libjoltapp} stage/lib/${abi}/libjoltapp.so
348333 cp ${opensslAndroid.out}/lib/libssl.so stage/lib/${abi}/libssl.so
@@ -25,7 +25,7 @@
25 # The steps are the ones the graph before it ran, in the same order; where a25 # The steps are the ones the graph before it ran, in the same order; where a
26 # genrule read a path out of `read_root_config`, a derivation takes an26 # genrule read a path out of `read_root_config`, a derivation takes an
27 # argument.27 # argument.
28-{ pkgs, lib, self, chez-src, jolt-native, glimmer, joltAndroid, androidSdk, ndk }:28+{ pkgs, lib, self, chez-src, jolt-native, jolt-native-android, glimmer, joltAndroid, androidSdk, ndk }:
29 29
30 let30 let
31 # What the APK targets, in the three spellings the tools want it in.31 # What the APK targets, in the three spellings the tools want it in.
@@ -47,45 +47,30 @@ let
47 ndkBin = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/bin";47 ndkBin = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/bin";
48 cc = "${ndkBin}/aarch64-linux-android${apiLevel}-clang";48 cc = "${ndkBin}/aarch64-linux-android${apiLevel}-clang";
49 49
50- # What comes out of jolt-native's releases. These two pins are the whole of50+ # What comes out of jolt-native's CI, as a flake input rather than a fetchurl:
51- # what `just bump` moves on the native side — a desktop run builds the flake51+ # nix unpacks a tarball input itself, and flake.lock holds the digest that
52- # input instead, so this is the only place a release is fetched. Do not edit52+ # used to be written here by hand. `just bump` moves it with
53- # them by hand: bump-jolt-native.bb fetches each archive, weighs it, and53+ # `nix flake update jolt-native-android` and nothing in this file changes.
54- # writes both the url and the digest below.
55 #54 #
56 # One archive, two libraries: libvidya (the retained-tree UI) and libjoltmoq55 # One archive, two libraries: libvidya (the retained-tree UI) and libjoltmoq
57 # (the AV media plane). They are built together and only make sense together56 # (the AV media plane). They are built together and only make sense together
58 # — libjoltapp links both — so there is one pin for the pair rather than two57 # — libjoltapp links both — so there is one pin for the pair rather than two
59- # that could drift apart.58+ # that could drift apart. It carries include/ and libc++_shared.so besides,
60- nativeRelease = pkgs.fetchurl {59+ # which is why the glue's headers and the C++ runtime come from here too.
61- url = "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz";60+ nativeLibs = jolt-native-android;
62- sha256 = "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108";
63- };
64-
65- glue = pkgs.fetchurl {
66- url = "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz";
67- sha256 = "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5";
68- };
69-
70- # Unpacked once, so the consumers below name files rather than repeat the tar.
71- nativeLibs = pkgs.runCommand "jolt-native-android" { } ''
72- mkdir -p "$out"
73- tar -xzf ${nativeRelease} -C "$out"
74- '';
75-
76- glueSrc = pkgs.runCommand "jolt-android-glue" { } ''
77- mkdir -p "$out"
78- tar -xzf ${glue} -C "$out" --strip-components=1
79- '';
80 61
81- # The C++ runtime, out of the same NDK the glue is compiled with.62+ # The C++ runtime, out of the archive rather than the NDK composed here.
82 #63 #
83 # openh264 is C++, and its build script asks to be linked against64 # openh264 is C++, and its build script asks to be linked against
84 # `libc++_shared.so` by name — so libjoltmoq carries that as a DT_NEEDED. An65 # `libc++_shared.so` by name — so libjoltmoq carries that as a DT_NEEDED. An
85 # app's linker namespace will not hand out the platform's own copy (there is66 # app's linker namespace will not hand out the platform's own copy (there is
86 # no stable one to hand out), so the APK carries it, exactly as it carries67 # no stable one to hand out), so the APK carries it, exactly as it carries
87 # OpenSSL below and for the same reason.68 # OpenSSL below and for the same reason.
88- libcxx = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so";69+ #
70+ # jolt-native ships it beside the libraries that need it, so this is the copy
71+ # they were actually linked against — where the NDK path was whichever
72+ # revision `composeAndroidPackages` happened to resolve here.
73+ libcxx = "${nativeLibs}/lib/${abi}/libc++_shared.so";
89 74
90 # --- Chez's arm64 cross target ------------------------------------------75 # --- Chez's arm64 cross target ------------------------------------------
91 # The one piece with no nixpkgs equivalent: `pkgs.chez` builds a Scheme for76 # The one piece with no nixpkgs equivalent: `pkgs.chez` builds a Scheme for
@@ -261,14 +246,14 @@ let
261 # crash on the phone.246 # crash on the phone.
262 libjoltapp = pkgs.runCommand "libjoltapp.so" { } ''247 libjoltapp = pkgs.runCommand "libjoltapp.so" { } ''
263 mkdir -p lib248 mkdir -p lib
264- cp ${nativeLibs}/libvidya.so lib/libvidya.so249+ cp ${nativeLibs}/lib/${abi}/libvidya.so lib/libvidya.so
265- cp ${nativeLibs}/libjoltmoq.so lib/libjoltmoq.so250+ cp ${nativeLibs}/lib/${abi}/libjoltmoq.so lib/libjoltmoq.so
266 251
267 ${cc} -shared -fPIC -O2 -o "$out" \252 ${cc} -shared -fPIC -O2 -o "$out" \
268- ${glueSrc}/android/jolt_main.c \253+ ${jolt-native}/android/jolt_main.c \
269 ${joltBootObj} \254 ${joltBootObj} \
270 -I${joltBoot} \255 -I${joltBoot} \
271- -I${glueSrc}/include \256+ -I${nativeLibs}/include \
272 -Llib \257 -Llib \
273 ${chezAndroid}/tarm64le/boot/tarm64le/libkernel.a \258 ${chezAndroid}/tarm64le/boot/tarm64le/libkernel.a \
274 ${chezAndroid}/lz4/lib/liblz4.a \259 ${chezAndroid}/lz4/lib/liblz4.a \
@@ -341,8 +326,8 @@ let
341 nativeBuildInputs = [ pkgs.zip ];326 nativeBuildInputs = [ pkgs.zip ];
342 } ''327 } ''
343 mkdir -p stage/lib/${abi}328 mkdir -p stage/lib/${abi}
344- cp ${nativeLibs}/libvidya.so stage/lib/${abi}/libvidya.so329+ cp ${nativeLibs}/lib/${abi}/libvidya.so stage/lib/${abi}/libvidya.so
345- cp ${nativeLibs}/libjoltmoq.so stage/lib/${abi}/libjoltmoq.so330+ cp ${nativeLibs}/lib/${abi}/libjoltmoq.so stage/lib/${abi}/libjoltmoq.so
346 cp ${libcxx} stage/lib/${abi}/libc++_shared.so331 cp ${libcxx} stage/lib/${abi}/libc++_shared.so
347 cp ${libjoltapp} stage/lib/${abi}/libjoltapp.so332 cp ${libjoltapp} stage/lib/${abi}/libjoltapp.so
348 cp ${opensslAndroid.out}/lib/libssl.so stage/lib/${abi}/libssl.so333 cp ${opensslAndroid.out}/lib/libssl.so stage/lib/${abi}/libssl.so
modified scripts/apk.bb +15 -0
@@ -47,10 +47,25 @@ exec "$(dirname "$0")/bb" "$0" "$@"
4747 (when-let [s (paths/env "FRQ_NIX_STORE" nil)]
4848 ["--store" s "--eval-store" "auto"]))
4949
50+;; The Android objects come from jolt-native's CI under a "latest" alias, and a
51+;; flake input is locked once and then stays put — so without this an APK is
52+;; built against whatever `flake.lock` recorded the first time, however old.
53+;; Re-resolving that one input before every build is what makes "latest" mean
54+;; latest; the lock still records which bytes this APK was built from, so a
55+;; build remains reproducible after the fact.
56+;;
57+;; Only this input: `nix flake update` with no argument would move jolt,
58+;; nixpkgs and glimmer too, and the whole point of their pins is that they move
59+;; when someone decides they should.
60+(defn refresh-native []
61+ (apply paths/out (paths/nix root ["nix" "flake" "update" "jolt-native-android"
62+ "--flake" (str root)])))
63+
5064 ;; Built without a `result` symlink: the path is what the caller wants, and a
5165 ;; symlink into a store that may not be this one is not a useful thing to leave
5266 ;; in the tree.
5367 (defn build []
68+ (refresh-native)
5469 (let [out (->> (paths/nix root (concat ["nix" "build" (str root "#apk")
5570 "--no-link" "--print-out-paths"]
5671 store))
@@ -47,10 +47,25 @@ exec "$(dirname "$0")/bb" "$0" "$@"
47 (when-let [s (paths/env "FRQ_NIX_STORE" nil)]47 (when-let [s (paths/env "FRQ_NIX_STORE" nil)]
48 ["--store" s "--eval-store" "auto"]))48 ["--store" s "--eval-store" "auto"]))
49 49
50+;; The Android objects come from jolt-native's CI under a "latest" alias, and a
51+;; flake input is locked once and then stays put — so without this an APK is
52+;; built against whatever `flake.lock` recorded the first time, however old.
53+;; Re-resolving that one input before every build is what makes "latest" mean
54+;; latest; the lock still records which bytes this APK was built from, so a
55+;; build remains reproducible after the fact.
56+;;
57+;; Only this input: `nix flake update` with no argument would move jolt,
58+;; nixpkgs and glimmer too, and the whole point of their pins is that they move
59+;; when someone decides they should.
60+(defn refresh-native []
61+ (apply paths/out (paths/nix root ["nix" "flake" "update" "jolt-native-android"
62+ "--flake" (str root)])))
63+
50 ;; Built without a `result` symlink: the path is what the caller wants, and a64 ;; Built without a `result` symlink: the path is what the caller wants, and a
51 ;; symlink into a store that may not be this one is not a useful thing to leave65 ;; symlink into a store that may not be this one is not a useful thing to leave
52 ;; in the tree.66 ;; in the tree.
53 (defn build []67 (defn build []
68+ (refresh-native)
54 (let [out (->> (paths/nix root (concat ["nix" "build" (str root "#apk")69 (let [out (->> (paths/nix root (concat ["nix" "build" (str root "#apk")
55 "--no-link" "--print-out-paths"]70 "--no-link" "--print-out-paths"]
56 store))71 store))