nandi/frqpublic Fork 0
a008d3b
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 every jolt-native half from the release, and only from there

A sibling checkout used to win over the pinned release, so what an APK
carried depended on which directories happened to sit beside this one.
It is gone: the manifests in scripts/ are the only answer, `just lib`
fetches both desktop objects out of the linux-x86_64 archive instead of
cloning and cargo-building them, and android/BUCK has one branch where it
had two — defs.bzl existed only to hold that fork and is deleted.

scripts/bump-jolt-native.bb moves every pin at once: the tag, URL, size
and digest of each archive, the release's commit in deps.edn, and the
table buck reads. `just bump` for the latest release, `just bump v0.1.2`
for a named one. Doing it by hand meant copying between a browser and a
sha256sum, and the failure mode was a manifest still naming one release
while carrying another's digest.

Two things the checkout had been covering for:

build-jolt-boot.bb computed glimmer-vidya's cache path itself, and had it
wrong — a dependency with :deps/root lands somewhere else entirely. It
asks `jolt path` now, which is the only thing that knows.

build-apk.bb compiled FrqActivity.java alone, so CameraCapture never
reached the dex; libjoltmoq looks that class up by name over JNI the
moment a call starts the camera. It globs android/java the way the BUCK
file does, and the two dexes are identical again.

The one wart is in lib.bb: v0.1.3's desktop libjoltmoq.so does not name
libasound, so a copy is patched to. jolt-native has the real fix now, and
the test for it — `patchelf --print-needed` — is what makes this go away
on its own with the release that carries it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-08-31T23:14:34-07:00 Browse files
a008d3b parent: 03d5a6b
modified .buckconfig +1 -1
@@ -29,4 +29,4 @@
2929 execution_platforms = root//platforms:cache
3030
3131 [project]
32- ignore = .git,android/build,.jolt-native,buck-out
32+ ignore = .git,android/build,build,buck-out
@@ -29,4 +29,4 @@
29 execution_platforms = root//platforms:cache29 execution_platforms = root//platforms:cache
30 30
31 [project]31 [project]
32- ignore = .git,android/build,.jolt-native,buck-out32+ ignore = .git,android/build,build,buck-out
modified .gitignore +3 -6
@@ -1,17 +1,14 @@
1-# Build outputs: the boot image, the staged libraries, the APK.
1+# Build outputs: the boot image and the APK.
22 /android/build/
33
4-# libvidya, staged out of jolt-native by the `buck` recipe.
5-/android/prebuilt/
4+# The native libraries `just lib` links out of the DotSlash cache.
5+/build/
66
77 # buck2 output tree.
88 /buck-out
99 # Written by the `buck` recipe: this machine's paths, not a shared setting.
1010 /.buckconfig.local
1111
12-# jolt-native, cloned by `just lib` when there is no sibling checkout.
13-/.jolt-native/
14-
1512 # Tool caches.
1613 /.cpcache/
1714 /.jolt/
@@ -1,17 +1,14 @@
1-# Build outputs: the boot image, the staged libraries, the APK.1+# Build outputs: the boot image and the APK.
2 /android/build/2 /android/build/
3 3
4-# libvidya, staged out of jolt-native by the `buck` recipe.4+# The native libraries `just lib` links out of the DotSlash cache.
5-/android/prebuilt/5+/build/
6 6
7 # buck2 output tree.7 # buck2 output tree.
8 /buck-out8 /buck-out
9 # Written by the `buck` recipe: this machine's paths, not a shared setting.9 # Written by the `buck` recipe: this machine's paths, not a shared setting.
10 /.buckconfig.local10 /.buckconfig.local
11 11
12-# jolt-native, cloned by `just lib` when there is no sibling checkout.
13-/.jolt-native/
14-
15 # Tool caches.12 # Tool caches.
16 /.cpcache/13 /.cpcache/
17 /.jolt/14 /.jolt/
modified README.md +20 -16
@@ -41,16 +41,19 @@ just lib
4141 just run
4242 ```
4343
44-`just lib` builds [jolt-native](https://gitlab.com/nandithebull/jolt-native),
45-cloning it into `.jolt-native` at the pinned commit unless you already have a
46-sibling checkout, which wins. That repo is where every shared object this
47-client loads comes from: `libvidya`, the retained-tree ABI glimmer paints
48-through, and `libjoltmoq`, the AV media plane. They come out of one directory,
49-and `just run` puts that one directory on the loader path.
50-
51-`just run` is `jolt -M:frq` with `LD_LIBRARY_PATH` pointed at the built
52-library. It connects to `irc.freeq.at:6697` over TLS and joins `#test`. Untick
53-TLS on the connect screen (or point it at `127.0.0.1`) for a local server's
44+`just lib` fetches both shared objects this client loads —
45+[jolt-native](https://gitlab.com/nandithebull/jolt-native)'s `libvidya`, the
46+retained-tree ABI glimmer paints through, and `libjoltmoq`, the AV media plane
47+— out of that project's release, by the digests in `scripts/*.dotslash`, and
48+links them into `build/lib`. Nothing is compiled: no Rust toolchain, and no
49+jolt-native checkout beside this one. It needs `patchelf`, and only to name
50+libasound in `libjoltmoq.so`, which v0.1.3 does not — see the comment in
51+`scripts/lib.bb`; that goes away with the release that links it. `just bump` moves every pin to the
52+latest release at once, and `just bump v0.1.2` to a named one.
53+
54+`just run` is `jolt -M:frq` with `LD_LIBRARY_PATH` pointed at `build/lib`. It
55+connects to `irc.freeq.at:6697` over TLS and joins `#test`. Untick TLS on the
56+connect screen (or point it at `127.0.0.1`) for a local server's
5457 plain listener:
5558
5659 ```bash
@@ -91,18 +94,19 @@ A refused sign-in is reported and the connection carries on as a guest.
9194
9295 ## Android
9396
94-An APK with two shared libraries and no Java: `libvidya.so` (vidya's Rust/egui
95-C ABI, which owns the event loop as the NativeActivity's own library) and
96-`libjoltapp.so` (frq compiled to a Chez boot image). Both native halves come
97-from the vidya checkout; only the boot image is frq's.
97+An APK whose native halves come from jolt-native's release and whose Jolt half
98+is frq's: `libvidya.so` (the Rust/egui C ABI, which owns the event loop as the
99+NativeActivity's own library), `libjoltmoq.so` (the media plane) and
100+`libjoltapp.so` (frq compiled to a Chez boot image, linked against both).
98101
99102 ```bash
100103 ./android/build-apk.bb run # build, install, launch on a connected device
101104 ./android/build-apk.bb log # logcat, filtered
102105 ```
103106
104-Needs what vidya's Android build needs — SDK, NDK r29, and a cross-built Chez
105-in `~/.cache/vidya-chez-android`.
107+Needs an SDK and a cross-built Chez in `~/.cache/vidya-chez-android`; the NDK
108+comes down through `scripts/android-ndk.dotslash`. `just apk` builds the same
109+APK as a buck2 graph, which is the incremental way in.
106110
107111 TLS does not work there: jolt reaches OpenSSL through the dynamic loader, and
108112 Android has no public `libssl` to load. The connect screen falls back to the
@@ -41,16 +41,19 @@ just lib
41 just run41 just run
42 ```42 ```
43 43
44-`just lib` builds [jolt-native](https://gitlab.com/nandithebull/jolt-native),44+`just lib` fetches both shared objects this client loads —
45-cloning it into `.jolt-native` at the pinned commit unless you already have a45+[jolt-native](https://gitlab.com/nandithebull/jolt-native)'s `libvidya`, the
46-sibling checkout, which wins. That repo is where every shared object this46+retained-tree ABI glimmer paints through, and `libjoltmoq`, the AV media plane
47-client loads comes from: `libvidya`, the retained-tree ABI glimmer paints47+— out of that project's release, by the digests in `scripts/*.dotslash`, and
48-through, and `libjoltmoq`, the AV media plane. They come out of one directory,48+links them into `build/lib`. Nothing is compiled: no Rust toolchain, and no
49-and `just run` puts that one directory on the loader path.49+jolt-native checkout beside this one. It needs `patchelf`, and only to name
50-50+libasound in `libjoltmoq.so`, which v0.1.3 does not — see the comment in
51-`just run` is `jolt -M:frq` with `LD_LIBRARY_PATH` pointed at the built51+`scripts/lib.bb`; that goes away with the release that links it. `just bump` moves every pin to the
52-library. It connects to `irc.freeq.at:6697` over TLS and joins `#test`. Untick52+latest release at once, and `just bump v0.1.2` to a named one.
53-TLS on the connect screen (or point it at `127.0.0.1`) for a local server's53+
54+`just run` is `jolt -M:frq` with `LD_LIBRARY_PATH` pointed at `build/lib`. It
55+connects to `irc.freeq.at:6697` over TLS and joins `#test`. Untick TLS on the
56+connect screen (or point it at `127.0.0.1`) for a local server's
54 plain listener:57 plain listener:
55 58
56 ```bash59 ```bash
@@ -91,18 +94,19 @@ A refused sign-in is reported and the connection carries on as a guest.
91 94
92 ## Android95 ## Android
93 96
94-An APK with two shared libraries and no Java: `libvidya.so` (vidya's Rust/egui97+An APK whose native halves come from jolt-native's release and whose Jolt half
95-C ABI, which owns the event loop as the NativeActivity's own library) and98+is frq's: `libvidya.so` (the Rust/egui C ABI, which owns the event loop as the
96-`libjoltapp.so` (frq compiled to a Chez boot image). Both native halves come99+NativeActivity's own library), `libjoltmoq.so` (the media plane) and
97-from the vidya checkout; only the boot image is frq's.100+`libjoltapp.so` (frq compiled to a Chez boot image, linked against both).
98 101
99 ```bash102 ```bash
100 ./android/build-apk.bb run # build, install, launch on a connected device103 ./android/build-apk.bb run # build, install, launch on a connected device
101 ./android/build-apk.bb log # logcat, filtered104 ./android/build-apk.bb log # logcat, filtered
102 ```105 ```
103 106
104-Needs what vidya's Android build needs — SDK, NDK r29, and a cross-built Chez107+Needs an SDK and a cross-built Chez in `~/.cache/vidya-chez-android`; the NDK
105-in `~/.cache/vidya-chez-android`.108+comes down through `scripts/android-ndk.dotslash`. `just apk` builds the same
109+APK as a buck2 graph, which is the incremental way in.
106 110
107 TLS does not work there: jolt reaches OpenSSL through the dynamic loader, and111 TLS does not work there: jolt reaches OpenSSL through the dynamic loader, and
108 Android has no public `libssl` to load. The connect screen falls back to the112 Android has no public `libssl` to load. The connect screen falls back to the
modified android/BUCK +49 -34
@@ -2,16 +2,13 @@
22 #
33 # Every step the old build-apk script ran in sequence is a target here, so a change
44 # to one screen rebuilds the boot image and repackages, and touches neither the
5-# Rust nor the Java. The two native halves come from jolt-native — libvidya out
6-# of its buck2 graph, the glue compiled by the NDK its scripts/ pin — and the
7-# rest is this repo's.
5+# Rust nor the Java. The two native halves and the glue come out of jolt-native's
6+# release, fetched by digest through scripts/*.dotslash; the rest is this repo's.
7+# Nothing here is built out of a jolt-native checkout, and none is needed.
88 #
99 # The machine-specific paths are read from .buckconfig.local, which the `buck`
1010 # recipe in the justfile writes. Nothing here is found by looking around the
1111 # machine; if a path is missing the recipe says which.
12-load(":defs.bzl", "glue", "libjoltmoq", "libvidya")
13-
14-_JOLT_NATIVE = read_root_config("frq", "jolt_native", "")
1512 _ANDROID_HOME = read_root_config("frq", "android_home", "")
1613 _CHEZ = read_root_config("frq", "chez_android", "")
1714 _OPENSSL = read_root_config("frq", "openssl_android", "")
@@ -21,24 +18,22 @@ _TOOLS = _ANDROID_HOME + "/build-tools/36.0.0"
2118 _ANDROID_JAR = _ANDROID_HOME + "/platforms/android-36/android.jar"
2219 # `$(...)` in a genrule cmd is a buck macro, not the shell's substitution, so
2320 # everything this file runs at command time uses backticks.
24-# This repo's own, not the other checkout's: an APK build needs a clang and an
25-# llvm-objcopy whether or not jolt-native is on the machine. Both resolve the
26-# NDK through scripts/android-ndk.dotslash, downloading it once.
21+# This repo's own: an APK build needs a clang and an llvm-objcopy, and neither
22+# is jolt-native's to supply. Both resolve the NDK through
23+# scripts/android-ndk.dotslash, downloading it once.
2724 _NDK_BIN = "ndk=`$(location //scripts:android-ndk-bin)`"
2825 _CC = "$(location //scripts:android-cc)"
2926
3027 # An absolute path for $OUT, so a command may cd without losing it. buck has
3128 # already made the parent directory. Spelled out step by step because backticks
3229 # do not nest.
33-# Empty when a checkout answers for it, so the script's own lookup wins.
3430 # The archive's top directory is what strip_prefix took off, so `src` is
3531 # directly inside it. Absolute, because the script is handed this and does its
3632 # own directory changing.
37-_GLIMMER_VIDYA = "" if read_root_config("frq", "libvidya", "pinned") == "checkout" else \
38- "GLIMMER_VIDYA=`realpath $(location toolchains//dist:glimmer-vidya)/src` "
33+_GLIMMER_VIDYA = "GLIMMER_VIDYA=`realpath $(location toolchains//dist:glimmer-vidya)/src` "
3934
40-# jolt_main.c and the ABI's headers, as targets — see defs.bzl for which of
41-# the two sources answers, and why neither may be a bare path.
35+# jolt_main.c and the ABI's headers, as targets rather than bare paths — see
36+# the rules below.
4237 _GLUE_C = "`realpath $(location :glue-c)`"
4338 _GLUE_INCLUDE = "`realpath $(location :glue-include)`"
4439
@@ -57,23 +52,43 @@ export_file(
5752 )
5853
5954 # --- the UI half ------------------------------------------------------------
60-# Two ways in, and both make the library's bytes an input rather than a
61-# command buck would cache forever:
62-#
63-# pinned the .so out of jolt-native's release, fetched by digest. What a
64-# build gets by default, and what makes an APK buildable with no
65-# jolt-native checkout and no NDK anywhere on the machine.
66-# checkout the .so a sibling jolt-native just built, staged into this cell
67-# by the `buck` recipe. Anyone working on both repos at once
68-# builds what they are editing.
69-#
70-# The recipe decides which, by whether that checkout exists, and says so here.
71-libvidya(name = "libvidya")
55+# The .so out of jolt-native's release, fetched by digest — which is what makes
56+# an APK buildable with no jolt-native checkout and no NDK anywhere on the
57+# machine. A genrule rather than a path, so the library's bytes are an input to
58+# what reads them: an action that shelled out to build it would have nothing to
59+# invalidate on and would serve the same stale object forever.
60+genrule(
61+ name = "libvidya",
62+ out = "libvidya.so",
63+ cmd = "cp $(location toolchains//dist:libvidya-android)/libvidya.so \"$OUT\"",
64+)
65+
66+# The media plane, out of the same archive. Necessarily the same release:
67+# libjoltapp links both, and pairing one release's media plane with another's
68+# UI is a combination nothing has tested.
69+genrule(
70+ name = "libjoltmoq",
71+ out = "libjoltmoq.so",
72+ cmd = "cp $(location toolchains//dist:libjoltmoq-android)/libjoltmoq.so \"$OUT\"",
73+)
7274
73-# The media plane, on the same terms and from the same release.
74-libjoltmoq(name = "libjoltmoq")
75+# jolt_main.c and the ABI's headers, from the glue archive of the same release.
76+# Targets rather than paths for the reason above — an input is the only thing
77+# buck can notice a change in.
78+genrule(
79+ name = "glue-c",
80+ out = "jolt_main.c",
81+ cmd = "cp $(location toolchains//dist:android-glue)/android/jolt_main.c \"$OUT\"",
82+)
7583
76-glue(c_name = "glue-c", include_name = "glue-include")
84+# A directory of headers rather than a filegroup: a filegroup keeps each file
85+# at its own path inside the output, so `-I` would have to name the staging
86+# directory again.
87+genrule(
88+ name = "glue-include",
89+ out = "include",
90+ cmd = "cp -r $(location toolchains//dist:android-glue)/include \"$OUT\"",
91+)
7792
7893 # The C++ runtime, out of the same NDK the glue is compiled with.
7994 #
@@ -96,8 +111,8 @@ genrule(
96111 # are an input so that editing one rebuilds this; the compile itself reads them
97112 # through the deps.edn the script writes.
98113 # The sources here are frq's own. The other two roots the image is compiled
99-# from — glimmer, out of the jolt cache, and glimmer-vidya, out of jolt-native
100-# — are outside this cell, and so are Chez's cross boot files and the pinned
114+# from — glimmer and glimmer-vidya, both out of the jolt cache — are outside
115+# this cell, and so are Chez's cross boot files and the pinned
101116 # jolt itself. None of them can be an input, so the `buck` recipe hashes them
102117 # and writes the digest below; naming it in the command is what puts them in
103118 # this action's identity.
@@ -112,9 +127,9 @@ genrule(
112127 cmd = "# sources outside this cell: " + read_root_config("frq", "boot_stamp", "unknown") + "\n" +
113128 "DOTSLASH=$(location toolchains//dist:dotslash)/dotslash " +
114129 "JOLT_MANIFEST=$(location //scripts:jolt) " +
115- # The one source root the script cannot find for itself when there
116- # is no jolt-native checkout. An input, so a new release recompiles
117- # the image.
130+ # The one source root the script cannot find for itself: the jolt
131+ # cache is not an action input, and this is. A new release recompiles
132+ # the image because of it.
118133 _GLIMMER_VIDYA +
119134 "$(location :build-jolt-boot.bb) \"$OUT\" >&2",
120135 )
@@ -2,16 +2,13 @@
2 #2 #
3 # Every step the old build-apk script ran in sequence is a target here, so a change3 # Every step the old build-apk script ran in sequence is a target here, so a change
4 # to one screen rebuilds the boot image and repackages, and touches neither the4 # to one screen rebuilds the boot image and repackages, and touches neither the
5-# Rust nor the Java. The two native halves come from jolt-native — libvidya out5+# Rust nor the Java. The two native halves and the glue come out of jolt-native's
6-# of its buck2 graph, the glue compiled by the NDK its scripts/ pin — and the6+# release, fetched by digest through scripts/*.dotslash; the rest is this repo's.
7-# rest is this repo's.7+# Nothing here is built out of a jolt-native checkout, and none is needed.
8 #8 #
9 # The machine-specific paths are read from .buckconfig.local, which the `buck`9 # The machine-specific paths are read from .buckconfig.local, which the `buck`
10 # recipe in the justfile writes. Nothing here is found by looking around the10 # recipe in the justfile writes. Nothing here is found by looking around the
11 # machine; if a path is missing the recipe says which.11 # machine; if a path is missing the recipe says which.
12-load(":defs.bzl", "glue", "libjoltmoq", "libvidya")
13-
14-_JOLT_NATIVE = read_root_config("frq", "jolt_native", "")
15 _ANDROID_HOME = read_root_config("frq", "android_home", "")12 _ANDROID_HOME = read_root_config("frq", "android_home", "")
16 _CHEZ = read_root_config("frq", "chez_android", "")13 _CHEZ = read_root_config("frq", "chez_android", "")
17 _OPENSSL = read_root_config("frq", "openssl_android", "")14 _OPENSSL = read_root_config("frq", "openssl_android", "")
@@ -21,24 +18,22 @@ _TOOLS = _ANDROID_HOME + "/build-tools/36.0.0"
21 _ANDROID_JAR = _ANDROID_HOME + "/platforms/android-36/android.jar"18 _ANDROID_JAR = _ANDROID_HOME + "/platforms/android-36/android.jar"
22 # `$(...)` in a genrule cmd is a buck macro, not the shell's substitution, so19 # `$(...)` in a genrule cmd is a buck macro, not the shell's substitution, so
23 # everything this file runs at command time uses backticks.20 # everything this file runs at command time uses backticks.
24-# This repo's own, not the other checkout's: an APK build needs a clang and an21+# This repo's own: an APK build needs a clang and an llvm-objcopy, and neither
25-# llvm-objcopy whether or not jolt-native is on the machine. Both resolve the22+# is jolt-native's to supply. Both resolve the NDK through
26-# NDK through scripts/android-ndk.dotslash, downloading it once.23+# scripts/android-ndk.dotslash, downloading it once.
27 _NDK_BIN = "ndk=`$(location //scripts:android-ndk-bin)`"24 _NDK_BIN = "ndk=`$(location //scripts:android-ndk-bin)`"
28 _CC = "$(location //scripts:android-cc)"25 _CC = "$(location //scripts:android-cc)"
29 26
30 # An absolute path for $OUT, so a command may cd without losing it. buck has27 # An absolute path for $OUT, so a command may cd without losing it. buck has
31 # already made the parent directory. Spelled out step by step because backticks28 # already made the parent directory. Spelled out step by step because backticks
32 # do not nest.29 # do not nest.
33-# Empty when a checkout answers for it, so the script's own lookup wins.
34 # The archive's top directory is what strip_prefix took off, so `src` is30 # The archive's top directory is what strip_prefix took off, so `src` is
35 # directly inside it. Absolute, because the script is handed this and does its31 # directly inside it. Absolute, because the script is handed this and does its
36 # own directory changing.32 # own directory changing.
37-_GLIMMER_VIDYA = "" if read_root_config("frq", "libvidya", "pinned") == "checkout" else \33+_GLIMMER_VIDYA = "GLIMMER_VIDYA=`realpath $(location toolchains//dist:glimmer-vidya)/src` "
38- "GLIMMER_VIDYA=`realpath $(location toolchains//dist:glimmer-vidya)/src` "
39 34
40-# jolt_main.c and the ABI's headers, as targets — see defs.bzl for which of35+# jolt_main.c and the ABI's headers, as targets rather than bare paths — see
41-# the two sources answers, and why neither may be a bare path.36+# the rules below.
42 _GLUE_C = "`realpath $(location :glue-c)`"37 _GLUE_C = "`realpath $(location :glue-c)`"
43 _GLUE_INCLUDE = "`realpath $(location :glue-include)`"38 _GLUE_INCLUDE = "`realpath $(location :glue-include)`"
44 39
@@ -57,23 +52,43 @@ export_file(
57 )52 )
58 53
59 # --- the UI half ------------------------------------------------------------54 # --- the UI half ------------------------------------------------------------
60-# Two ways in, and both make the library's bytes an input rather than a55+# The .so out of jolt-native's release, fetched by digest — which is what makes
61-# command buck would cache forever:56+# an APK buildable with no jolt-native checkout and no NDK anywhere on the
62-#57+# machine. A genrule rather than a path, so the library's bytes are an input to
63-# pinned the .so out of jolt-native's release, fetched by digest. What a58+# what reads them: an action that shelled out to build it would have nothing to
64-# build gets by default, and what makes an APK buildable with no59+# invalidate on and would serve the same stale object forever.
65-# jolt-native checkout and no NDK anywhere on the machine.60+genrule(
66-# checkout the .so a sibling jolt-native just built, staged into this cell61+ name = "libvidya",
67-# by the `buck` recipe. Anyone working on both repos at once62+ out = "libvidya.so",
68-# builds what they are editing.63+ cmd = "cp $(location toolchains//dist:libvidya-android)/libvidya.so \"$OUT\"",
69-#64+)
70-# The recipe decides which, by whether that checkout exists, and says so here.65+
71-libvidya(name = "libvidya")66+# The media plane, out of the same archive. Necessarily the same release:
67+# libjoltapp links both, and pairing one release's media plane with another's
68+# UI is a combination nothing has tested.
69+genrule(
70+ name = "libjoltmoq",
71+ out = "libjoltmoq.so",
72+ cmd = "cp $(location toolchains//dist:libjoltmoq-android)/libjoltmoq.so \"$OUT\"",
73+)
72 74
73-# The media plane, on the same terms and from the same release.75+# jolt_main.c and the ABI's headers, from the glue archive of the same release.
74-libjoltmoq(name = "libjoltmoq")76+# Targets rather than paths for the reason above — an input is the only thing
77+# buck can notice a change in.
78+genrule(
79+ name = "glue-c",
80+ out = "jolt_main.c",
81+ cmd = "cp $(location toolchains//dist:android-glue)/android/jolt_main.c \"$OUT\"",
82+)
75 83
76-glue(c_name = "glue-c", include_name = "glue-include")84+# A directory of headers rather than a filegroup: a filegroup keeps each file
85+# at its own path inside the output, so `-I` would have to name the staging
86+# directory again.
87+genrule(
88+ name = "glue-include",
89+ out = "include",
90+ cmd = "cp -r $(location toolchains//dist:android-glue)/include \"$OUT\"",
91+)
77 92
78 # The C++ runtime, out of the same NDK the glue is compiled with.93 # The C++ runtime, out of the same NDK the glue is compiled with.
79 #94 #
@@ -96,8 +111,8 @@ genrule(
96 # are an input so that editing one rebuilds this; the compile itself reads them111 # are an input so that editing one rebuilds this; the compile itself reads them
97 # through the deps.edn the script writes.112 # through the deps.edn the script writes.
98 # The sources here are frq's own. The other two roots the image is compiled113 # The sources here are frq's own. The other two roots the image is compiled
99-# from — glimmer, out of the jolt cache, and glimmer-vidya, out of jolt-native114+# from — glimmer and glimmer-vidya, both out of the jolt cache — are outside
100-# — are outside this cell, and so are Chez's cross boot files and the pinned115+# this cell, and so are Chez's cross boot files and the pinned
101 # jolt itself. None of them can be an input, so the `buck` recipe hashes them116 # jolt itself. None of them can be an input, so the `buck` recipe hashes them
102 # and writes the digest below; naming it in the command is what puts them in117 # and writes the digest below; naming it in the command is what puts them in
103 # this action's identity.118 # this action's identity.
@@ -112,9 +127,9 @@ genrule(
112 cmd = "# sources outside this cell: " + read_root_config("frq", "boot_stamp", "unknown") + "\n" +127 cmd = "# sources outside this cell: " + read_root_config("frq", "boot_stamp", "unknown") + "\n" +
113 "DOTSLASH=$(location toolchains//dist:dotslash)/dotslash " +128 "DOTSLASH=$(location toolchains//dist:dotslash)/dotslash " +
114 "JOLT_MANIFEST=$(location //scripts:jolt) " +129 "JOLT_MANIFEST=$(location //scripts:jolt) " +
115- # The one source root the script cannot find for itself when there130+ # The one source root the script cannot find for itself: the jolt
116- # is no jolt-native checkout. An input, so a new release recompiles131+ # cache is not an action input, and this is. A new release recompiles
117- # the image.132+ # the image because of it.
118 _GLIMMER_VIDYA +133 _GLIMMER_VIDYA +
119 "$(location :build-jolt-boot.bb) \"$OUT\" >&2",134 "$(location :build-jolt-boot.bb) \"$OUT\" >&2",
120 )135 )
modified android/build-apk.bb +45 -31
@@ -5,21 +5,24 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
55
66 ;; Glue the two halves of the frq Android app into an APK.
77 ;;
8-;; libvidya.so the C ABI on Rust/egui, cross-compiled by buck2, and the
8+;; libvidya.so the C ABI on Rust/egui, out of the pinned release, and the
99 ;; NativeActivity's own library (it holds android-activity's
1010 ;; glue, so it owns the event loop)
11+;; libjoltmoq.so the AV media plane — MoQ over QUIC, Opus, H.264, Camera2
1112 ;; libjoltapp.so jolt-native's android/jolt_main.c plus frq's Jolt boot
1213 ;; image, dlopened by the above
13-;; classes.dex one Java class, and only because a picture chooser answers
14-;; through onActivityResult and a NativeActivity has nowhere
15-;; to deliver that
14+;; libc++_shared.so the NDK's C++ runtime, which libjoltmoq names
15+;; classes.dex two Java classes: a picture chooser answers through
16+;; onActivityResult and a NativeActivity has nowhere to
17+;; deliver that, and Camera2 has no C API worth the name
1618 ;; libssl.so OpenSSL, because the platform's own is not ours to load: an
1719 ;; libcrypto.so app's linker namespace refuses /system/lib64/libssl.so, and
1820 ;; without one there is no TLS at all on the phone
1921 ;;
20-;; Neither half is built here beyond that last link: the UI library comes from
21-;; jolt-native's `just ffi-android` and the boot image from build-jolt-boot.bb.
22-;; Both native pieces are jolt-native's — only the boot image is frq's.
22+;; Neither half is built here beyond that last link: the UI library and the glue
23+;; come out of jolt-native's release, fetched by digest through the DotSlash
24+;; pins in scripts/, and the boot image from build-jolt-boot.bb. Both native
25+;; pieces are jolt-native's — only the boot image is frq's.
2326 ;;
2427 ;; build-apk.bb [build|install|run|log]
2528 (require '[babashka.classpath :as cp])
@@ -31,13 +34,6 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
3134 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
3235 (def action (or (first *command-line-args*) "build"))
3336
34-;; Where jolt-native is, answered the way the justfile answers it: a sibling
35-;; checkout wins, and otherwise it is the clone `just lib` leaves under
36-;; .jolt-native.
37-(def jolt-native (paths/jolt-native root))
38-(when-not (fs/directory? jolt-native)
39- (paths/die (str "no jolt-native at " jolt-native " — run `just lib` to clone it")))
40-
4137 (def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
4238 (def ndk-home (paths/env "ANDROID_NDK_HOME" (str (fs/path (fs/home) ".local" "share" "android-ndk-r29"))))
4339 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
@@ -62,12 +58,17 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
6258 (fs/path openssl "libssl.so") (fs/path openssl "libcrypto.so")])
6359
6460 ;; --- the UI half -----------------------------------------------------------
65-;; buck2 fetches its own NDK for this, from the pin in jolt-native's
66-;; scripts/android-ndk.dotslash, so the toolchain above is the only one that
67-;; has to be installed by hand.
68-(p/shell {:dir jolt-native :out *err*} "just" "ffi-android")
69-(def vidya-so (fs/path jolt-native "build" "android" "arm64-v8a" "libvidya.so"))
70-(paths/require-paths! "library" [vidya-so])
61+;; The release's own object, and the glue beside it, both by digest: this build
62+;; compiles no Rust and needs no jolt-native checkout, exactly as the graph in
63+;; android/BUCK needs none.
64+(def vidya-so (paths/dist root "libvidya-android"))
65+;; The media plane, out of the same archive. The glue registers its symbols and
66+;; includes its header, so this is not optional beside that jolt_main.c: link
67+;; without it and --no-undefined says so.
68+(def joltmoq-so (paths/dist root "libjoltmoq-android"))
69+(def glue-c (paths/dist root "android-glue"))
70+(def glue-include (fs/path (fs/parent (fs/parent glue-c)) "include"))
71+(paths/require-paths! "library" [vidya-so joltmoq-so glue-c glue-include])
7172
7273 ;; --- the Jolt half ---------------------------------------------------------
7374 (p/shell (str (fs/path root "android" "build-jolt-boot.bb")) (str jolt-build))
@@ -81,19 +82,24 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
8182 "jolt.boot" "jolt_boot.o")
8283
8384 ;; --- the Java half ---------------------------------------------------------
84-;; One class: the photo chooser's result has to land somewhere, and native code
85-;; is not somewhere. d8 turns it into the classes.dex the runtime loads.
85+;; Two classes: the photo chooser's result has to land somewhere and native
86+;; code is not somewhere, and Camera2 has no C API worth the name. d8 turns
87+;; them into the classes.dex the runtime loads.
8688 (def java-build (fs/path build "java"))
8789 (fs/delete-tree java-build)
8890 (fs/create-dirs (fs/path java-build "classes"))
8991 ;; android.jar on the class path is where every android.* type comes from; the
90-;; JDK's own java.* is what is left, and this class uses nothing of it that
92+;; JDK's own java.* is what is left, and neither class uses anything of it that
9193 ;; Android does not have. (`-bootclasspath` would be the stricter way to say
9294 ;; that, and javac refuses it for a release this recent.)
93-(p/shell "javac" "--release" "17"
94- "--class-path" (str android-jar)
95- "-d" (str (fs/path java-build "classes"))
96- (str (fs/path root "android" "java" "uk" "nandi" "frq" "FrqActivity.java")))
95+;;
96+;; Every class under android/java, the way android/BUCK globs them: naming one
97+;; here left CameraCapture out of the dex, and libjoltmoq looks that class up
98+;; by name over JNI the moment a call starts the camera.
99+(apply p/shell "javac" "--release" "17"
100+ "--class-path" (str android-jar)
101+ "-d" (str (fs/path java-build "classes"))
102+ (map str (fs/glob (fs/path root "android" "java") "**.java")))
97103 (apply p/shell (str (fs/path tools "d8")) "--min-api" api "--output" (str java-build)
98104 (map str (fs/glob (fs/path java-build "classes") "**.class")))
99105
@@ -101,6 +107,13 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
101107 (fs/create-dirs arm-lib)
102108 (fs/copy (fs/path java-build "classes.dex") (fs/path stage "classes.dex"))
103109 (fs/copy vidya-so (fs/path arm-lib "libvidya.so"))
110+(fs/copy joltmoq-so (fs/path arm-lib "libjoltmoq.so"))
111+;; openh264 is C++ and asks to be linked against libc++_shared.so by name, so
112+;; libjoltmoq carries it as a DT_NEEDED and the APK has to carry the object —
113+;; an app's linker namespace will not hand out the platform's own.
114+(fs/copy (fs/path ndk-bin ".." "sysroot" "usr" "lib" "aarch64-linux-android"
115+ "libc++_shared.so")
116+ (fs/path arm-lib "libc++_shared.so"))
104117 ;; jolt.mvn-http dlopens these by name at first use; beside the app's own
105118 ;; libraries is where an app's namespace will answer for that name.
106119 (doseq [lib ["libssl.so" "libcrypto.so"]]
@@ -108,14 +121,14 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
108121
109122 (p/shell clang "-shared" "-fPIC" "-O2"
110123 "-o" (str (fs/path arm-lib "libjoltapp.so"))
111- (str (fs/path jolt-native "android" "jolt_main.c"))
124+ (str glue-c)
112125 (str (fs/path jolt-build "jolt_boot.o"))
113126 (str "-I" jolt-build)
114- (str "-I" (fs/path jolt-native "crates" "jolt-vidya" "include"))
127+ (str "-I" glue-include)
115128 (str "-L" arm-lib)
116129 (str (fs/path chez "tarm64le" "boot" "tarm64le" "libkernel.a"))
117130 (str (fs/path chez "lz4" "lib" "liblz4.a"))
118- "-lvidya" "-landroid" "-llog" "-lz" "-ldl" "-lm"
131+ "-lvidya" "-ljoltmoq" "-landroid" "-llog" "-lz" "-ldl" "-lm"
119132 "-Wl,--no-undefined")
120133
121134 ;; --- the APK ---------------------------------------------------------------
@@ -133,7 +146,8 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
133146 "--version-name" "0.1.0")
134147 ;; Stored, not deflated: the loader maps these straight out of the APK.
135148 (p/shell {:dir (str stage)} "zip" "-q" "-0" (str unaligned)
136- "lib/arm64-v8a/libvidya.so" "lib/arm64-v8a/libjoltapp.so"
149+ "lib/arm64-v8a/libvidya.so" "lib/arm64-v8a/libjoltmoq.so"
150+ "lib/arm64-v8a/libc++_shared.so" "lib/arm64-v8a/libjoltapp.so"
137151 "lib/arm64-v8a/libssl.so" "lib/arm64-v8a/libcrypto.so")
138152 ;; The dex is read by the runtime rather than mapped, so it may as well deflate.
139153 (p/shell {:dir (str stage)} "zip" "-q" (str unaligned) "classes.dex")
@@ -5,21 +5,24 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
5 5
6 ;; Glue the two halves of the frq Android app into an APK.6 ;; Glue the two halves of the frq Android app into an APK.
7 ;;7 ;;
8-;; libvidya.so the C ABI on Rust/egui, cross-compiled by buck2, and the8+;; libvidya.so the C ABI on Rust/egui, out of the pinned release, and the
9 ;; NativeActivity's own library (it holds android-activity's9 ;; NativeActivity's own library (it holds android-activity's
10 ;; glue, so it owns the event loop)10 ;; glue, so it owns the event loop)
11+;; libjoltmoq.so the AV media plane — MoQ over QUIC, Opus, H.264, Camera2
11 ;; libjoltapp.so jolt-native's android/jolt_main.c plus frq's Jolt boot12 ;; libjoltapp.so jolt-native's android/jolt_main.c plus frq's Jolt boot
12 ;; image, dlopened by the above13 ;; image, dlopened by the above
13-;; classes.dex one Java class, and only because a picture chooser answers14+;; libc++_shared.so the NDK's C++ runtime, which libjoltmoq names
14-;; through onActivityResult and a NativeActivity has nowhere15+;; classes.dex two Java classes: a picture chooser answers through
15-;; to deliver that16+;; onActivityResult and a NativeActivity has nowhere to
17+;; deliver that, and Camera2 has no C API worth the name
16 ;; libssl.so OpenSSL, because the platform's own is not ours to load: an18 ;; libssl.so OpenSSL, because the platform's own is not ours to load: an
17 ;; libcrypto.so app's linker namespace refuses /system/lib64/libssl.so, and19 ;; libcrypto.so app's linker namespace refuses /system/lib64/libssl.so, and
18 ;; without one there is no TLS at all on the phone20 ;; without one there is no TLS at all on the phone
19 ;;21 ;;
20-;; Neither half is built here beyond that last link: the UI library comes from22+;; Neither half is built here beyond that last link: the UI library and the glue
21-;; jolt-native's `just ffi-android` and the boot image from build-jolt-boot.bb.23+;; come out of jolt-native's release, fetched by digest through the DotSlash
22-;; Both native pieces are jolt-native's — only the boot image is frq's.24+;; pins in scripts/, and the boot image from build-jolt-boot.bb. Both native
25+;; pieces are jolt-native's — only the boot image is frq's.
23 ;;26 ;;
24 ;; build-apk.bb [build|install|run|log]27 ;; build-apk.bb [build|install|run|log]
25 (require '[babashka.classpath :as cp])28 (require '[babashka.classpath :as cp])
@@ -31,13 +34,6 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
31 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))34 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
32 (def action (or (first *command-line-args*) "build"))35 (def action (or (first *command-line-args*) "build"))
33 36
34-;; Where jolt-native is, answered the way the justfile answers it: a sibling
35-;; checkout wins, and otherwise it is the clone `just lib` leaves under
36-;; .jolt-native.
37-(def jolt-native (paths/jolt-native root))
38-(when-not (fs/directory? jolt-native)
39- (paths/die (str "no jolt-native at " jolt-native " — run `just lib` to clone it")))
40-
41 (def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))37 (def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
42 (def ndk-home (paths/env "ANDROID_NDK_HOME" (str (fs/path (fs/home) ".local" "share" "android-ndk-r29"))))38 (def ndk-home (paths/env "ANDROID_NDK_HOME" (str (fs/path (fs/home) ".local" "share" "android-ndk-r29"))))
43 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))39 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
@@ -62,12 +58,17 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
62 (fs/path openssl "libssl.so") (fs/path openssl "libcrypto.so")])58 (fs/path openssl "libssl.so") (fs/path openssl "libcrypto.so")])
63 59
64 ;; --- the UI half -----------------------------------------------------------60 ;; --- the UI half -----------------------------------------------------------
65-;; buck2 fetches its own NDK for this, from the pin in jolt-native's61+;; The release's own object, and the glue beside it, both by digest: this build
66-;; scripts/android-ndk.dotslash, so the toolchain above is the only one that62+;; compiles no Rust and needs no jolt-native checkout, exactly as the graph in
67-;; has to be installed by hand.63+;; android/BUCK needs none.
68-(p/shell {:dir jolt-native :out *err*} "just" "ffi-android")64+(def vidya-so (paths/dist root "libvidya-android"))
69-(def vidya-so (fs/path jolt-native "build" "android" "arm64-v8a" "libvidya.so"))65+;; The media plane, out of the same archive. The glue registers its symbols and
70-(paths/require-paths! "library" [vidya-so])66+;; includes its header, so this is not optional beside that jolt_main.c: link
67+;; without it and --no-undefined says so.
68+(def joltmoq-so (paths/dist root "libjoltmoq-android"))
69+(def glue-c (paths/dist root "android-glue"))
70+(def glue-include (fs/path (fs/parent (fs/parent glue-c)) "include"))
71+(paths/require-paths! "library" [vidya-so joltmoq-so glue-c glue-include])
71 72
72 ;; --- the Jolt half ---------------------------------------------------------73 ;; --- the Jolt half ---------------------------------------------------------
73 (p/shell (str (fs/path root "android" "build-jolt-boot.bb")) (str jolt-build))74 (p/shell (str (fs/path root "android" "build-jolt-boot.bb")) (str jolt-build))
@@ -81,19 +82,24 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
81 "jolt.boot" "jolt_boot.o")82 "jolt.boot" "jolt_boot.o")
82 83
83 ;; --- the Java half ---------------------------------------------------------84 ;; --- the Java half ---------------------------------------------------------
84-;; One class: the photo chooser's result has to land somewhere, and native code85+;; Two classes: the photo chooser's result has to land somewhere and native
85-;; is not somewhere. d8 turns it into the classes.dex the runtime loads.86+;; code is not somewhere, and Camera2 has no C API worth the name. d8 turns
87+;; them into the classes.dex the runtime loads.
86 (def java-build (fs/path build "java"))88 (def java-build (fs/path build "java"))
87 (fs/delete-tree java-build)89 (fs/delete-tree java-build)
88 (fs/create-dirs (fs/path java-build "classes"))90 (fs/create-dirs (fs/path java-build "classes"))
89 ;; android.jar on the class path is where every android.* type comes from; the91 ;; android.jar on the class path is where every android.* type comes from; the
90-;; JDK's own java.* is what is left, and this class uses nothing of it that92+;; JDK's own java.* is what is left, and neither class uses anything of it that
91 ;; Android does not have. (`-bootclasspath` would be the stricter way to say93 ;; Android does not have. (`-bootclasspath` would be the stricter way to say
92 ;; that, and javac refuses it for a release this recent.)94 ;; that, and javac refuses it for a release this recent.)
93-(p/shell "javac" "--release" "17"95+;;
94- "--class-path" (str android-jar)96+;; Every class under android/java, the way android/BUCK globs them: naming one
95- "-d" (str (fs/path java-build "classes"))97+;; here left CameraCapture out of the dex, and libjoltmoq looks that class up
96- (str (fs/path root "android" "java" "uk" "nandi" "frq" "FrqActivity.java")))98+;; by name over JNI the moment a call starts the camera.
99+(apply p/shell "javac" "--release" "17"
100+ "--class-path" (str android-jar)
101+ "-d" (str (fs/path java-build "classes"))
102+ (map str (fs/glob (fs/path root "android" "java") "**.java")))
97 (apply p/shell (str (fs/path tools "d8")) "--min-api" api "--output" (str java-build)103 (apply p/shell (str (fs/path tools "d8")) "--min-api" api "--output" (str java-build)
98 (map str (fs/glob (fs/path java-build "classes") "**.class")))104 (map str (fs/glob (fs/path java-build "classes") "**.class")))
99 105
@@ -101,6 +107,13 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
101 (fs/create-dirs arm-lib)107 (fs/create-dirs arm-lib)
102 (fs/copy (fs/path java-build "classes.dex") (fs/path stage "classes.dex"))108 (fs/copy (fs/path java-build "classes.dex") (fs/path stage "classes.dex"))
103 (fs/copy vidya-so (fs/path arm-lib "libvidya.so"))109 (fs/copy vidya-so (fs/path arm-lib "libvidya.so"))
110+(fs/copy joltmoq-so (fs/path arm-lib "libjoltmoq.so"))
111+;; openh264 is C++ and asks to be linked against libc++_shared.so by name, so
112+;; libjoltmoq carries it as a DT_NEEDED and the APK has to carry the object —
113+;; an app's linker namespace will not hand out the platform's own.
114+(fs/copy (fs/path ndk-bin ".." "sysroot" "usr" "lib" "aarch64-linux-android"
115+ "libc++_shared.so")
116+ (fs/path arm-lib "libc++_shared.so"))
104 ;; jolt.mvn-http dlopens these by name at first use; beside the app's own117 ;; jolt.mvn-http dlopens these by name at first use; beside the app's own
105 ;; libraries is where an app's namespace will answer for that name.118 ;; libraries is where an app's namespace will answer for that name.
106 (doseq [lib ["libssl.so" "libcrypto.so"]]119 (doseq [lib ["libssl.so" "libcrypto.so"]]
@@ -108,14 +121,14 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
108 121
109 (p/shell clang "-shared" "-fPIC" "-O2"122 (p/shell clang "-shared" "-fPIC" "-O2"
110 "-o" (str (fs/path arm-lib "libjoltapp.so"))123 "-o" (str (fs/path arm-lib "libjoltapp.so"))
111- (str (fs/path jolt-native "android" "jolt_main.c"))124+ (str glue-c)
112 (str (fs/path jolt-build "jolt_boot.o"))125 (str (fs/path jolt-build "jolt_boot.o"))
113 (str "-I" jolt-build)126 (str "-I" jolt-build)
114- (str "-I" (fs/path jolt-native "crates" "jolt-vidya" "include"))127+ (str "-I" glue-include)
115 (str "-L" arm-lib)128 (str "-L" arm-lib)
116 (str (fs/path chez "tarm64le" "boot" "tarm64le" "libkernel.a"))129 (str (fs/path chez "tarm64le" "boot" "tarm64le" "libkernel.a"))
117 (str (fs/path chez "lz4" "lib" "liblz4.a"))130 (str (fs/path chez "lz4" "lib" "liblz4.a"))
118- "-lvidya" "-landroid" "-llog" "-lz" "-ldl" "-lm"131+ "-lvidya" "-ljoltmoq" "-landroid" "-llog" "-lz" "-ldl" "-lm"
119 "-Wl,--no-undefined")132 "-Wl,--no-undefined")
120 133
121 ;; --- the APK ---------------------------------------------------------------134 ;; --- the APK ---------------------------------------------------------------
@@ -133,7 +146,8 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
133 "--version-name" "0.1.0")146 "--version-name" "0.1.0")
134 ;; Stored, not deflated: the loader maps these straight out of the APK.147 ;; Stored, not deflated: the loader maps these straight out of the APK.
135 (p/shell {:dir (str stage)} "zip" "-q" "-0" (str unaligned)148 (p/shell {:dir (str stage)} "zip" "-q" "-0" (str unaligned)
136- "lib/arm64-v8a/libvidya.so" "lib/arm64-v8a/libjoltapp.so"149+ "lib/arm64-v8a/libvidya.so" "lib/arm64-v8a/libjoltmoq.so"
150+ "lib/arm64-v8a/libc++_shared.so" "lib/arm64-v8a/libjoltapp.so"
137 "lib/arm64-v8a/libssl.so" "lib/arm64-v8a/libcrypto.so")151 "lib/arm64-v8a/libssl.so" "lib/arm64-v8a/libcrypto.so")
138 ;; The dex is read by the runtime rather than mapped, so it may as well deflate.152 ;; The dex is read by the runtime rather than mapped, so it may as well deflate.
139 (p/shell {:dir (str stage)} "zip" "-q" (str unaligned) "classes.dex")153 (p/shell {:dir (str stage)} "zip" "-q" (str unaligned) "classes.dex")
modified android/build-jolt-boot.bb +35 -24
@@ -21,33 +21,9 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
2121 '[clojure.string :as str])
2222
2323 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
24-(def jolt-native (paths/jolt-native root))
2524 (def args *command-line-args*)
2625 (def stamp-only? (= "--stamp" (first args)))
2726
28-(def glimmer
29- (paths/env "GLIMMER"
30- (str (fs/path (fs/home) ".jolt" "gitlibs"
31- "https___gitlab.com_nandithebull_glimmer"
32- (paths/dep-sha root "https://gitlab.com/nandithebull/glimmer")
33- "src"))))
34-
35-;; glimmer-vidya lives inside jolt-native, so a sibling checkout answers for it
36-;; the way it answers for libvidya; the cache is the fallback, at the sha
37-;; deps.edn pins.
38-(def glimmer-vidya
39- (or (paths/env "GLIMMER_VIDYA" nil)
40- (let [in-checkout (fs/path jolt-native "jolt" "glimmer-vidya" "src")]
41- (if (fs/directory? in-checkout)
42- (str in-checkout)
43- (str (fs/path (fs/home) ".jolt" "gitlibs"
44- "https___gitlab.com_nandithebull_jolt-native"
45- (paths/dep-sha root "https://gitlab.com/nandithebull/jolt-native")
46- "jolt" "glimmer-vidya" "src"))))))
47-
48-(paths/require-paths! "Jolt source root" [glimmer glimmer-vidya]
49- "run `jolt -M:frq --help` once to populate the git cache")
50-
5127 ;; The DotSlash-pinned jolt, not whatever is on PATH: an upstream jolt cannot
5228 ;; open a TLS connection on Android — it reads the socket address out of
5329 ;; `struct addrinfo` at glibc's offset, which is Bionic's `ai_canonname` — so a
@@ -67,6 +43,41 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
6743 (paths/out dotslash "--" "fetch" manifest)
6844 (str (fs/path root "scripts" "jolt"))))))
6945
46+;; The two source roots that are not this repo's, asked of jolt rather than
47+;; guessed at. `jolt path` prints what it resolved deps.edn to, which is the
48+;; only thing that knows where a git dependency landed: a plain :git/sha goes
49+;; to one cache layout and one with :deps/root to another, and glimmer and
50+;; glimmer-vidya are one of each.
51+;;
52+;; GLIMMER and GLIMMER_VIDYA name them instead when a caller already knows.
53+;; buck sets the second: the jolt cache cannot be an action input, so that
54+;; build hands over the release archive it fetched by digest, and with both set
55+;; nothing here shells out at all.
56+(def roots
57+ (delay
58+ ;; From this tree, whatever directory the caller was in: deps.edn is what
59+ ;; `path` reads.
60+ (str/split (str/trim (:out (p/shell {:out :string :dir root} jolt "path"))) #":")))
61+
62+(defn root-of [k env pred]
63+ (or (paths/env env nil)
64+ (first (filter pred @roots))
65+ (paths/die (str "jolt resolved no " (name k) " source root")
66+ "check the :deps in deps.edn")))
67+
68+;; Matched by name rather than by shape: a cache path carries the repo, the sha
69+;; and — for a dependency with a :deps/root — the root inside it, and which of
70+;; those it ends with is jolt's business, not this script's.
71+(defn names? [root s] (str/includes? root s))
72+
73+(def glimmer-vidya
74+ (root-of :glimmer-vidya "GLIMMER_VIDYA" #(names? % "glimmer-vidya")))
75+(def glimmer
76+ (root-of :glimmer "GLIMMER" #(and (names? % "glimmer")
77+ (not (names? % "glimmer-vidya")))))
78+
79+(paths/require-paths! "Jolt source root" [glimmer glimmer-vidya])
80+
7081 (def module (paths/env "MODULE" "frq.app"))
7182 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
7283 (def host-scheme (str (fs/path chez "ta6le" "bin" "ta6le" "scheme")))
@@ -21,33 +21,9 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
21 '[clojure.string :as str])21 '[clojure.string :as str])
22 22
23 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))23 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
24-(def jolt-native (paths/jolt-native root))
25 (def args *command-line-args*)24 (def args *command-line-args*)
26 (def stamp-only? (= "--stamp" (first args)))25 (def stamp-only? (= "--stamp" (first args)))
27 26
28-(def glimmer
29- (paths/env "GLIMMER"
30- (str (fs/path (fs/home) ".jolt" "gitlibs"
31- "https___gitlab.com_nandithebull_glimmer"
32- (paths/dep-sha root "https://gitlab.com/nandithebull/glimmer")
33- "src"))))
34-
35-;; glimmer-vidya lives inside jolt-native, so a sibling checkout answers for it
36-;; the way it answers for libvidya; the cache is the fallback, at the sha
37-;; deps.edn pins.
38-(def glimmer-vidya
39- (or (paths/env "GLIMMER_VIDYA" nil)
40- (let [in-checkout (fs/path jolt-native "jolt" "glimmer-vidya" "src")]
41- (if (fs/directory? in-checkout)
42- (str in-checkout)
43- (str (fs/path (fs/home) ".jolt" "gitlibs"
44- "https___gitlab.com_nandithebull_jolt-native"
45- (paths/dep-sha root "https://gitlab.com/nandithebull/jolt-native")
46- "jolt" "glimmer-vidya" "src"))))))
47-
48-(paths/require-paths! "Jolt source root" [glimmer glimmer-vidya]
49- "run `jolt -M:frq --help` once to populate the git cache")
50-
51 ;; The DotSlash-pinned jolt, not whatever is on PATH: an upstream jolt cannot27 ;; The DotSlash-pinned jolt, not whatever is on PATH: an upstream jolt cannot
52 ;; open a TLS connection on Android — it reads the socket address out of28 ;; open a TLS connection on Android — it reads the socket address out of
53 ;; `struct addrinfo` at glibc's offset, which is Bionic's `ai_canonname` — so a29 ;; `struct addrinfo` at glibc's offset, which is Bionic's `ai_canonname` — so a
@@ -67,6 +43,41 @@ exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
67 (paths/out dotslash "--" "fetch" manifest)43 (paths/out dotslash "--" "fetch" manifest)
68 (str (fs/path root "scripts" "jolt"))))))44 (str (fs/path root "scripts" "jolt"))))))
69 45
46+;; The two source roots that are not this repo's, asked of jolt rather than
47+;; guessed at. `jolt path` prints what it resolved deps.edn to, which is the
48+;; only thing that knows where a git dependency landed: a plain :git/sha goes
49+;; to one cache layout and one with :deps/root to another, and glimmer and
50+;; glimmer-vidya are one of each.
51+;;
52+;; GLIMMER and GLIMMER_VIDYA name them instead when a caller already knows.
53+;; buck sets the second: the jolt cache cannot be an action input, so that
54+;; build hands over the release archive it fetched by digest, and with both set
55+;; nothing here shells out at all.
56+(def roots
57+ (delay
58+ ;; From this tree, whatever directory the caller was in: deps.edn is what
59+ ;; `path` reads.
60+ (str/split (str/trim (:out (p/shell {:out :string :dir root} jolt "path"))) #":")))
61+
62+(defn root-of [k env pred]
63+ (or (paths/env env nil)
64+ (first (filter pred @roots))
65+ (paths/die (str "jolt resolved no " (name k) " source root")
66+ "check the :deps in deps.edn")))
67+
68+;; Matched by name rather than by shape: a cache path carries the repo, the sha
69+;; and — for a dependency with a :deps/root — the root inside it, and which of
70+;; those it ends with is jolt's business, not this script's.
71+(defn names? [root s] (str/includes? root s))
72+
73+(def glimmer-vidya
74+ (root-of :glimmer-vidya "GLIMMER_VIDYA" #(names? % "glimmer-vidya")))
75+(def glimmer
76+ (root-of :glimmer "GLIMMER" #(and (names? % "glimmer")
77+ (not (names? % "glimmer-vidya")))))
78+
79+(paths/require-paths! "Jolt source root" [glimmer glimmer-vidya])
80+
70 (def module (paths/env "MODULE" "frq.app"))81 (def module (paths/env "MODULE" "frq.app"))
71 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))82 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
72 (def host-scheme (str (fs/path chez "ta6le" "bin" "ta6le" "scheme")))83 (def host-scheme (str (fs/path chez "ta6le" "bin" "ta6le" "scheme")))
deleted android/defs.bzl +0 -86
deleted file mode 100644
@@ -1,86 +0,0 @@
1-# Where libvidya comes from, which is a question with two answers.
2-#
3-# A BUCK file cannot branch — `if` outside a `def` is not this dialect — and
4-# this is not a `select` either: it does not vary by configuration but by
5-# whether a checkout is sitting next to this one. So it lives in a macro.
6-def libvidya(name):
7- """The Android libvidya: a sibling checkout's, or the pinned release's.
8-
9- Either way the library's bytes are an input to what reads them, which is
10- the part that matters — an action that shelled out to build it would have
11- nothing to invalidate on and would serve the same stale object forever.
12- """
13- if native.read_root_config("frq", "libvidya", "pinned") == "checkout":
14- # Staged by the `buck` recipe out of the sibling jolt-native, so that
15- # anyone working on both repos at once builds what they are editing.
16- native.export_file(
17- name = name,
18- src = "prebuilt/arm64-v8a/libvidya.so",
19- mode = "reference",
20- )
21- else:
22- # The release, fetched by digest. This is what makes an APK buildable
23- # with no jolt-native checkout and no NDK anywhere on the machine.
24- native.genrule(
25- name = name,
26- out = "libvidya.so",
27- cmd = "cp $(location toolchains//dist:libvidya-android)/libvidya.so \"$OUT\"",
28- )
29-
30-def libjoltmoq(name):
31- """The Android libjoltmoq: a sibling checkout's, or the pinned release's.
32-
33- The same two answers as libvidya, and necessarily the same one — the two
34- objects are built together, libjoltapp links both, and pairing one release's
35- media plane with another's UI is a combination nothing has tested. Both
36- macros read the same config key, so they cannot disagree.
37- """
38- if native.read_root_config("frq", "libvidya", "pinned") == "checkout":
39- native.export_file(
40- name = name,
41- src = "prebuilt/arm64-v8a/libjoltmoq.so",
42- mode = "reference",
43- )
44- else:
45- native.genrule(
46- name = name,
47- out = "libjoltmoq.so",
48- cmd = "cp $(location toolchains//dist:libjoltmoq-android)/libjoltmoq.so \"$OUT\"",
49- )
50-
51-def glue(c_name, include_name):
52- """jolt_main.c and the ABI's headers, from wherever libvidya came from.
53-
54- Targets rather than paths, and that is the point: naming a checkout's file
55- by absolute path leaves buck with nothing to notice when it changes, so
56- editing the glue rebuilt nothing and the APK kept the old object. It has to
57- be an input.
58- """
59- if native.read_root_config("frq", "libvidya", "pinned") == "checkout":
60- # Staged by the `buck` recipe, because a cell cannot reach outside its
61- # own root.
62- native.export_file(
63- name = c_name,
64- src = "prebuilt/glue/android/jolt_main.c",
65- mode = "reference",
66- )
67- # A genrule rather than a filegroup: a filegroup keeps each file at
68- # its own path inside the output, so `-I` would have to name the
69- # staging directory again. This hands back a directory of headers.
70- native.genrule(
71- name = include_name,
72- out = "include",
73- srcs = native.glob(["prebuilt/glue/include/*.h"]),
74- cmd = "mkdir -p \"$OUT\" && cp $SRCS \"$OUT\"/",
75- )
76- else:
77- native.genrule(
78- name = c_name,
79- out = "jolt_main.c",
80- cmd = "cp $(location toolchains//dist:android-glue)/android/jolt_main.c \"$OUT\"",
81- )
82- native.genrule(
83- name = include_name,
84- out = "include",
85- cmd = "cp -r $(location toolchains//dist:android-glue)/include \"$OUT\"",
86- )
deleted file mode 100644
@@ -1,86 +0,0 @@
1-# Where libvidya comes from, which is a question with two answers.
2-#
3-# A BUCK file cannot branch — `if` outside a `def` is not this dialect — and
4-# this is not a `select` either: it does not vary by configuration but by
5-# whether a checkout is sitting next to this one. So it lives in a macro.
6-def libvidya(name):
7- """The Android libvidya: a sibling checkout's, or the pinned release's.
8-
9- Either way the library's bytes are an input to what reads them, which is
10- the part that matters — an action that shelled out to build it would have
11- nothing to invalidate on and would serve the same stale object forever.
12- """
13- if native.read_root_config("frq", "libvidya", "pinned") == "checkout":
14- # Staged by the `buck` recipe out of the sibling jolt-native, so that
15- # anyone working on both repos at once builds what they are editing.
16- native.export_file(
17- name = name,
18- src = "prebuilt/arm64-v8a/libvidya.so",
19- mode = "reference",
20- )
21- else:
22- # The release, fetched by digest. This is what makes an APK buildable
23- # with no jolt-native checkout and no NDK anywhere on the machine.
24- native.genrule(
25- name = name,
26- out = "libvidya.so",
27- cmd = "cp $(location toolchains//dist:libvidya-android)/libvidya.so \"$OUT\"",
28- )
29-
30-def libjoltmoq(name):
31- """The Android libjoltmoq: a sibling checkout's, or the pinned release's.
32-
33- The same two answers as libvidya, and necessarily the same one — the two
34- objects are built together, libjoltapp links both, and pairing one release's
35- media plane with another's UI is a combination nothing has tested. Both
36- macros read the same config key, so they cannot disagree.
37- """
38- if native.read_root_config("frq", "libvidya", "pinned") == "checkout":
39- native.export_file(
40- name = name,
41- src = "prebuilt/arm64-v8a/libjoltmoq.so",
42- mode = "reference",
43- )
44- else:
45- native.genrule(
46- name = name,
47- out = "libjoltmoq.so",
48- cmd = "cp $(location toolchains//dist:libjoltmoq-android)/libjoltmoq.so \"$OUT\"",
49- )
50-
51-def glue(c_name, include_name):
52- """jolt_main.c and the ABI's headers, from wherever libvidya came from.
53-
54- Targets rather than paths, and that is the point: naming a checkout's file
55- by absolute path leaves buck with nothing to notice when it changes, so
56- editing the glue rebuilt nothing and the APK kept the old object. It has to
57- be an input.
58- """
59- if native.read_root_config("frq", "libvidya", "pinned") == "checkout":
60- # Staged by the `buck` recipe, because a cell cannot reach outside its
61- # own root.
62- native.export_file(
63- name = c_name,
64- src = "prebuilt/glue/android/jolt_main.c",
65- mode = "reference",
66- )
67- # A genrule rather than a filegroup: a filegroup keeps each file at
68- # its own path inside the output, so `-I` would have to name the
69- # staging directory again. This hands back a directory of headers.
70- native.genrule(
71- name = include_name,
72- out = "include",
73- srcs = native.glob(["prebuilt/glue/include/*.h"]),
74- cmd = "mkdir -p \"$OUT\" && cp $SRCS \"$OUT\"/",
75- )
76- else:
77- native.genrule(
78- name = c_name,
79- out = "jolt_main.c",
80- cmd = "cp $(location toolchains//dist:android-glue)/android/jolt_main.c \"$OUT\"",
81- )
82- native.genrule(
83- name = include_name,
84- out = "include",
85- cmd = "cp -r $(location toolchains//dist:android-glue)/include \"$OUT\"",
86- )
modified deps.edn +1 -1
@@ -13,7 +13,7 @@
1313 :deps {jolt-lang/glimmer {:git/url "https://gitlab.com/nandithebull/glimmer"
1414 :git/sha "399df371c790d690fb6e4560c3d4d7f838502857"}
1515 nandi/glimmer-vidya {:git/url "https://gitlab.com/nandithebull/jolt-native"
16- :git/sha "c71fc595f031aaa5cb461735af1865146f7b42ec"
16+ :git/sha "fd0e21a6c5d745ff9d134f92f909665454a7a1c9"
1717 :deps/root "jolt/glimmer-vidya"}}
1818
1919 ;; Both objects come from gitlab.com/nandithebull/jolt-native, one crate each,
@@ -13,7 +13,7 @@
13 :deps {jolt-lang/glimmer {:git/url "https://gitlab.com/nandithebull/glimmer"13 :deps {jolt-lang/glimmer {:git/url "https://gitlab.com/nandithebull/glimmer"
14 :git/sha "399df371c790d690fb6e4560c3d4d7f838502857"}14 :git/sha "399df371c790d690fb6e4560c3d4d7f838502857"}
15 nandi/glimmer-vidya {:git/url "https://gitlab.com/nandithebull/jolt-native"15 nandi/glimmer-vidya {:git/url "https://gitlab.com/nandithebull/jolt-native"
16- :git/sha "c71fc595f031aaa5cb461735af1865146f7b42ec"16+ :git/sha "fd0e21a6c5d745ff9d134f92f909665454a7a1c9"
17 :deps/root "jolt/glimmer-vidya"}}17 :deps/root "jolt/glimmer-vidya"}}
18 18
19 ;; Both objects come from gitlab.com/nandithebull/jolt-native, one crate each,19 ;; Both objects come from gitlab.com/nandithebull/jolt-native, one crate each,
modified justfile +4 -0
@@ -20,6 +20,10 @@ buck *args:
2020 apk action="build":
2121 scripts/apk.bb {{action}}
2222
23+# Every jolt-native pin — manifests, deps.edn, the buck table — at a release.
24+bump tag="":
25+ scripts/bump-jolt-native.bb {{tag}}
26+
2327 # The archives scripts/*.dotslash pins, as the table buck reads.
2428 sync-dist:
2529 scripts/dotslash-to-buck
@@ -20,6 +20,10 @@ buck *args:
20 apk action="build":20 apk action="build":
21 scripts/apk.bb {{action}}21 scripts/apk.bb {{action}}
22 22
23+# Every jolt-native pin — manifests, deps.edn, the buck table — at a release.
24+bump tag="":
25+ scripts/bump-jolt-native.bb {{tag}}
26+
23 # The archives scripts/*.dotslash pins, as the table buck reads.27 # The archives scripts/*.dotslash pins, as the table buck reads.
24 sync-dist:28 sync-dist:
25 scripts/dotslash-to-buck29 scripts/dotslash-to-buck
modified nix/android.nix +3 -3
@@ -1,9 +1,9 @@
11 # The APK, as derivations rather than as a buck2 graph.
22 #
33 # android/BUCK builds the same five things, and does it better for a person at
4-# a terminal: it is incremental, and it lets a sibling jolt-native checkout win
5-# over the pinned release so that editing the Rust rebuilds the APK. Nothing
6-# here replaces that. What this adds is the other build — from nothing, on a
4+# a terminal: it is incremental, and it fetches jolt-native's release by digest
5+# rather than rebuilding the world. Nothing here replaces that. What this adds
6+# is the other build — from nothing, on a
77 # machine with no Android SDK, no NDK, no hand-built Chez cross target and no
88 # ~/.cache at all:
99 #
@@ -1,9 +1,9 @@
1 # The APK, as derivations rather than as a buck2 graph.1 # The APK, as derivations rather than as a buck2 graph.
2 #2 #
3 # android/BUCK builds the same five things, and does it better for a person at3 # android/BUCK builds the same five things, and does it better for a person at
4-# a terminal: it is incremental, and it lets a sibling jolt-native checkout win4+# a terminal: it is incremental, and it fetches jolt-native's release by digest
5-# over the pinned release so that editing the Rust rebuilds the APK. Nothing5+# rather than rebuilding the world. Nothing here replaces that. What this adds
6-# here replaces that. What this adds is the other build — from nothing, on a6+# is the other build — from nothing, on a
7 # machine with no Android SDK, no NDK, no hand-built Chez cross target and no7 # machine with no Android SDK, no NDK, no hand-built Chez cross target and no
8 # ~/.cache at all:8 # ~/.cache at all:
9 #9 #
modified scripts/buck.bb +3 -39
@@ -15,7 +15,6 @@ exec "$(dirname "$0")/bb" "$0" "$@"
1515 '[babashka.process :as p])
1616
1717 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
18-(def jolt-native (paths/jolt-native root))
1918 (def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
2019 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
2120 (def openssl (paths/env "OPENSSL_ANDROID" (str (fs/path (fs/home) ".cache" "frq-openssl-android" "lib"))))
@@ -26,52 +25,17 @@ exec "$(dirname "$0")/bb" "$0" "$@"
2625 (fs/path chez "boot" "tarm64le" "scheme.boot")
2726 (fs/path openssl "libssl.so")])
2827
29-;; A jolt-native checkout wins over the pinned release, so that anyone working
30-;; on both repos at once builds what they are editing. It is staged into this
31-;; tree because a buck2 cell cannot reach outside its own root, and an action
32-;; that shelled out to the other project would have nothing to invalidate on.
33-;; With no checkout the release answers instead, fetched by digest — see
34-;; toolchains/dist and scripts/libvidya-android.dotslash.
35-(def libvidya
36- (if (fs/directory? (fs/path jolt-native "crates"))
37- (let [prebuilt (fs/path root "android" "prebuilt")]
38- (p/shell {:dir jolt-native :out :string} "just" "ffi-android")
39- (fs/create-dirs (fs/path prebuilt "arm64-v8a"))
40- (fs/copy (fs/path jolt-native "build" "android" "arm64-v8a" "libvidya.so")
41- (fs/path prebuilt "arm64-v8a" "libvidya.so")
42- {:replace-existing true})
43- ;; The media plane, staged the same way. `just ffi-android` builds both.
44- (fs/copy (fs/path jolt-native "build" "android" "arm64-v8a" "libjoltmoq.so")
45- (fs/path prebuilt "arm64-v8a" "libjoltmoq.so")
46- {:replace-existing true})
47- ;; The glue travels with it, for the same reason: editing jolt_main.c
48- ;; should relink libjoltapp, and it cannot if buck only knows a path.
49- (fs/create-dirs (fs/path prebuilt "glue" "android"))
50- (fs/create-dirs (fs/path prebuilt "glue" "include"))
51- (fs/copy (fs/path jolt-native "android" "jolt_main.c")
52- (fs/path prebuilt "glue" "android" "jolt_main.c")
53- {:replace-existing true})
54- ;; Both ABIs' headers: jolt_main.c includes joltmoq.h now, for the
55- ;; symbols it registers and for joltmoq_android_init.
56- (doseq [dir ["jolt-vidya" "jolt-moq"]
57- h (fs/glob (fs/path jolt-native "crates" dir "include") "*.h")]
58- (fs/copy h (fs/path prebuilt "glue" "include" (fs/file-name h))
59- {:replace-existing true}))
60- "checkout")
61- "pinned"))
62-
63-;; The boot image's other source roots are outside this cell too; hash them
64-;; here so the digest reaches the action. See android/BUCK.
28+;; The boot image is compiled from source roots outside this cell — glimmer and
29+;; glimmer-vidya, out of the jolt cache — which cannot be action inputs. Hash
30+;; them here so the digest reaches the action instead. See android/BUCK.
6531 (def boot-stamp
6632 (paths/out (str (fs/path root "android" "build-jolt-boot.bb")) "--stamp"))
6733
6834 (spit (str (fs/path root ".buckconfig.local"))
6935 (str "[frq]\n"
70- " jolt_native = " jolt-native "\n"
7136 " android_home = " android-home "\n"
7237 " chez_android = " chez "\n"
7338 " openssl_android = " openssl "\n"
74- " libvidya = " libvidya "\n"
7539 " boot_stamp = " boot-stamp "\n"))
7640
7741 (System/exit
@@ -15,7 +15,6 @@ exec "$(dirname "$0")/bb" "$0" "$@"
15 '[babashka.process :as p])15 '[babashka.process :as p])
16 16
17 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))17 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
18-(def jolt-native (paths/jolt-native root))
19 (def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))18 (def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
20 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))19 (def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
21 (def openssl (paths/env "OPENSSL_ANDROID" (str (fs/path (fs/home) ".cache" "frq-openssl-android" "lib"))))20 (def openssl (paths/env "OPENSSL_ANDROID" (str (fs/path (fs/home) ".cache" "frq-openssl-android" "lib"))))
@@ -26,52 +25,17 @@ exec "$(dirname "$0")/bb" "$0" "$@"
26 (fs/path chez "boot" "tarm64le" "scheme.boot")25 (fs/path chez "boot" "tarm64le" "scheme.boot")
27 (fs/path openssl "libssl.so")])26 (fs/path openssl "libssl.so")])
28 27
29-;; A jolt-native checkout wins over the pinned release, so that anyone working28+;; The boot image is compiled from source roots outside this cell — glimmer and
30-;; on both repos at once builds what they are editing. It is staged into this29+;; glimmer-vidya, out of the jolt cache — which cannot be action inputs. Hash
31-;; tree because a buck2 cell cannot reach outside its own root, and an action30+;; them here so the digest reaches the action instead. See android/BUCK.
32-;; that shelled out to the other project would have nothing to invalidate on.
33-;; With no checkout the release answers instead, fetched by digest — see
34-;; toolchains/dist and scripts/libvidya-android.dotslash.
35-(def libvidya
36- (if (fs/directory? (fs/path jolt-native "crates"))
37- (let [prebuilt (fs/path root "android" "prebuilt")]
38- (p/shell {:dir jolt-native :out :string} "just" "ffi-android")
39- (fs/create-dirs (fs/path prebuilt "arm64-v8a"))
40- (fs/copy (fs/path jolt-native "build" "android" "arm64-v8a" "libvidya.so")
41- (fs/path prebuilt "arm64-v8a" "libvidya.so")
42- {:replace-existing true})
43- ;; The media plane, staged the same way. `just ffi-android` builds both.
44- (fs/copy (fs/path jolt-native "build" "android" "arm64-v8a" "libjoltmoq.so")
45- (fs/path prebuilt "arm64-v8a" "libjoltmoq.so")
46- {:replace-existing true})
47- ;; The glue travels with it, for the same reason: editing jolt_main.c
48- ;; should relink libjoltapp, and it cannot if buck only knows a path.
49- (fs/create-dirs (fs/path prebuilt "glue" "android"))
50- (fs/create-dirs (fs/path prebuilt "glue" "include"))
51- (fs/copy (fs/path jolt-native "android" "jolt_main.c")
52- (fs/path prebuilt "glue" "android" "jolt_main.c")
53- {:replace-existing true})
54- ;; Both ABIs' headers: jolt_main.c includes joltmoq.h now, for the
55- ;; symbols it registers and for joltmoq_android_init.
56- (doseq [dir ["jolt-vidya" "jolt-moq"]
57- h (fs/glob (fs/path jolt-native "crates" dir "include") "*.h")]
58- (fs/copy h (fs/path prebuilt "glue" "include" (fs/file-name h))
59- {:replace-existing true}))
60- "checkout")
61- "pinned"))
62-
63-;; The boot image's other source roots are outside this cell too; hash them
64-;; here so the digest reaches the action. See android/BUCK.
65 (def boot-stamp31 (def boot-stamp
66 (paths/out (str (fs/path root "android" "build-jolt-boot.bb")) "--stamp"))32 (paths/out (str (fs/path root "android" "build-jolt-boot.bb")) "--stamp"))
67 33
68 (spit (str (fs/path root ".buckconfig.local"))34 (spit (str (fs/path root ".buckconfig.local"))
69 (str "[frq]\n"35 (str "[frq]\n"
70- " jolt_native = " jolt-native "\n"
71 " android_home = " android-home "\n"36 " android_home = " android-home "\n"
72 " chez_android = " chez "\n"37 " chez_android = " chez "\n"
73 " openssl_android = " openssl "\n"38 " openssl_android = " openssl "\n"
74- " libvidya = " libvidya "\n"
75 " boot_stamp = " boot-stamp "\n"))39 " boot_stamp = " boot-stamp "\n"))
76 40
77 (System/exit41 (System/exit
added scripts/bump-jolt-native.bb +158 -0
new file mode 100755
@@ -0,0 +1,158 @@
1+#!/bin/sh
2+#_(
3+exec "$(dirname "$0")/bb" "$0" "$@"
4+)
5+
6+;; Move every jolt-native pin in this tree to a release of it.
7+;;
8+;; scripts/bump-jolt-native.bb # the latest release
9+;; scripts/bump-jolt-native.bb v0.1.3 # a named one
10+;;
11+;; A jolt-native bump is four facts in three places: the tag, the URL, the size
12+;; and the digest of each archive in scripts/*.dotslash, the release's commit in
13+;; deps.edn, and the table buck reads, which is generated from the first. Done
14+;; by hand it is a lot of copying between a browser and a sha256sum, and the
15+;; failure mode is a manifest that still says v0.1.2 while its digest is v0.1.3's
16+;; — which DotSlash catches, but only on the machine that next fetches it.
17+;;
18+;; So: ask GitLab what the release holds, fetch each archive once, weigh it,
19+;; write the manifests back, put the release's commit in deps.edn — which is
20+;; what jolt resolves glimmer-vidya from, and so what the boot image compiles
21+;; against — and re-run dotslash-to-buck.
22+;;
23+;; Nothing here decides whether the new release is a good idea. It only makes
24+;; the tree say one version instead of two.
25+(require '[babashka.classpath :as cp])
26+(cp/add-classpath (str (babashka.fs/parent *file*)))
27+(require '[frq.paths :as paths]
28+ '[babashka.fs :as fs]
29+ '[babashka.process :as p]
30+ '[cheshire.core :as json]
31+ '[clojure.string :as str])
32+
33+(def here (fs/parent (fs/canonicalize *file*)))
34+(def root (str (fs/parent here)))
35+(def project "nandithebull%2Fjolt-native")
36+(def repo "https://gitlab.com/nandithebull/jolt-native")
37+
38+;; The release, as GitLab has it. `?per_page=1` when no tag is asked for: the
39+;; list is newest first, and the newest is what "latest" means here — the
40+;; /releases/permalink/latest endpoint sorts by release date, which is not the
41+;; same thing once a release is edited.
42+(defn release [tag]
43+ (let [url (if tag
44+ (str "https://gitlab.com/api/v4/projects/" project "/releases/" tag)
45+ (str "https://gitlab.com/api/v4/projects/" project "/releases?per_page=1"))
46+ body (json/parse-string (paths/out "curl" "-fsSL" url))]
47+ (if tag
48+ body
49+ (or (first body) (paths/die (str "no releases at all under " repo))))))
50+
51+;; The manifests this tree pins out of jolt-native. Every DotSlash file beside
52+;; this script whose providers point at the repo — rather than a list written
53+;; here, which would be a sixth place to forget.
54+(defn manifests []
55+ (->> (fs/glob here "*.dotslash")
56+ sort
57+ (keep (fn [file]
58+ (let [text (slurp (str file))
59+ json (json/parse-string (subs text (str/index-of text "{")))]
60+ (when (->> (get json "platforms")
61+ vals
62+ (some #(str/starts-with? (get-in % ["providers" 0 "url"]) repo)))
63+ {:file file :text text :json json}))))))
64+
65+;; The archive an entry names, at the new tag. The URL a manifest carries is the
66+;; release permalink — /-/releases/<tag>/downloads/<asset> — so the asset's name
67+;; is its last segment, and the name carries the version too. Both move.
68+(defn retag [url old new]
69+ (-> url
70+ (str/replace (str "/releases/" old "/") (str "/releases/" new "/"))
71+ (str/replace (str "-" old ".") (str "-" new "."))))
72+
73+(defn tag-of [url]
74+ (second (re-find #"/-/releases/([^/]+)/downloads/" url)))
75+
76+;; Fetch once per distinct URL, then weigh it: DotSlash wants the size and the
77+;; sha256 of the archive as downloaded, not of anything inside it.
78+(def weigh
79+ (memoize
80+ (fn [dir url]
81+ (let [file (fs/path dir (last (str/split url #"/")))]
82+ (println (str " fetching " (fs/file-name file)))
83+ (p/shell "curl" "-fsSL" "-o" (str file) url)
84+ {:size (fs/size file)
85+ :digest (first (str/split (paths/out "sha256sum" (str file)) #"\s+"))
86+ :file file}))))
87+
88+;; What the shim will reach for inside the archive. A release that moved a file
89+;; leaves a manifest that fetches and verifies and then cannot resolve, which is
90+;; a worse thing to find out from than this.
91+(defn check-path! [{:keys [file]} path]
92+ (let [names (set (str/split-lines (paths/out "tar" "-tzf" (str file))))]
93+ (when-not (some #(= path (str/replace % #"^\./" "")) names)
94+ (paths/die (str "no " path " in " (fs/file-name file))
95+ "The release moved it; the manifest's `path` needs a hand."))))
96+
97+;; The JSON back out, in the shape it went in: two-space indentation, a value
98+;; after each key, and the `//` comment block above it kept — that block is why
99+;; anyone reading the manifest knows what the object is for.
100+(def pretty
101+ (json/create-pretty-printer
102+ (assoc json/default-pretty-print-options
103+ :indentation " "
104+ :indent-arrays? true
105+ :object-field-value-separator ": ")))
106+
107+(defn rewrite [{:keys [file text json]} tmp tag]
108+ (let [platforms (get json "platforms")
109+ updated
110+ (into (array-map)
111+ (for [[platform entry] platforms
112+ :let [url (retag (get-in entry ["providers" 0 "url"]) (tag-of (get-in entry ["providers" 0 "url"])) tag)
113+ {:keys [size digest] :as got} (weigh tmp url)]]
114+ (do
115+ (check-path! got (get entry "path"))
116+ [platform (-> entry
117+ (assoc "size" size "digest" digest)
118+ (assoc-in ["providers" 0 "url"] url))])))
119+ head (subs text 0 (str/index-of text "{"))
120+ ;; The prose above the JSON names the release too — "from jolt-native's
121+ ;; v0.1.3 release". Left saying the old one it would be a lie the moment
122+ ;; this script succeeds.
123+ head (reduce (fn [h old] (str/replace h old tag))
124+ head
125+ (distinct (keep #(tag-of (get-in % ["providers" 0 "url"])) (vals platforms))))]
126+ (spit (str file) (str head (json/generate-string (assoc json "platforms" updated) {:pretty pretty}) "\n"))
127+ (println (str " " (fs/file-name file)))))
128+
129+;; deps.edn takes glimmer-vidya as a git dependency, and the boot image is
130+;; compiled from the source root jolt resolves that to. Replaced as text rather
131+;; than round-tripped as EDN: the file is mostly comments explaining why each
132+;; pin is where it is, and rewriting it as data would throw all of them away.
133+(defn bump-deps! [commit]
134+ (let [file (fs/path root "deps.edn")
135+ text (slurp (str file))
136+ old (paths/dep-sha root repo)]
137+ (cond
138+ (nil? old) (paths/die (str "no dependency on " repo " in deps.edn"))
139+ (= old commit) (println " deps.edn already at this commit")
140+ :else (do (spit (str file) (str/replace text old commit))
141+ (println (str " deps.edn " (subs old 0 8) " -> " (subs commit 0 8)))))))
142+
143+(let [tag (first *command-line-args*)
144+ rel (release tag)
145+ tag (get rel "tag_name")
146+ commit (get-in rel ["commit" "id"])
147+ files (manifests)
148+ tmp (fs/create-temp-dir {:prefix "jolt-native-"})]
149+ (when (empty? files)
150+ (paths/die (str "no DotSlash manifest in " here " points at " repo)))
151+ (println (str "jolt-native " tag " (" (subs commit 0 8) ")"))
152+ (try
153+ (doseq [m files] (rewrite m tmp tag))
154+ (finally (fs/delete-tree tmp)))
155+ (bump-deps! commit)
156+ (p/shell (str (fs/path here "dotslash-to-buck")))
157+ (println (str "\nNow: git diff, then `just lib` and `just apk` — the pins are "
158+ "written, nothing is built.")))
new file mode 100755
@@ -0,0 +1,158 @@
1+#!/bin/sh
2+#_(
3+exec "$(dirname "$0")/bb" "$0" "$@"
4+)
5+
6+;; Move every jolt-native pin in this tree to a release of it.
7+;;
8+;; scripts/bump-jolt-native.bb # the latest release
9+;; scripts/bump-jolt-native.bb v0.1.3 # a named one
10+;;
11+;; A jolt-native bump is four facts in three places: the tag, the URL, the size
12+;; and the digest of each archive in scripts/*.dotslash, the release's commit in
13+;; deps.edn, and the table buck reads, which is generated from the first. Done
14+;; by hand it is a lot of copying between a browser and a sha256sum, and the
15+;; failure mode is a manifest that still says v0.1.2 while its digest is v0.1.3's
16+;; — which DotSlash catches, but only on the machine that next fetches it.
17+;;
18+;; So: ask GitLab what the release holds, fetch each archive once, weigh it,
19+;; write the manifests back, put the release's commit in deps.edn — which is
20+;; what jolt resolves glimmer-vidya from, and so what the boot image compiles
21+;; against — and re-run dotslash-to-buck.
22+;;
23+;; Nothing here decides whether the new release is a good idea. It only makes
24+;; the tree say one version instead of two.
25+(require '[babashka.classpath :as cp])
26+(cp/add-classpath (str (babashka.fs/parent *file*)))
27+(require '[frq.paths :as paths]
28+ '[babashka.fs :as fs]
29+ '[babashka.process :as p]
30+ '[cheshire.core :as json]
31+ '[clojure.string :as str])
32+
33+(def here (fs/parent (fs/canonicalize *file*)))
34+(def root (str (fs/parent here)))
35+(def project "nandithebull%2Fjolt-native")
36+(def repo "https://gitlab.com/nandithebull/jolt-native")
37+
38+;; The release, as GitLab has it. `?per_page=1` when no tag is asked for: the
39+;; list is newest first, and the newest is what "latest" means here — the
40+;; /releases/permalink/latest endpoint sorts by release date, which is not the
41+;; same thing once a release is edited.
42+(defn release [tag]
43+ (let [url (if tag
44+ (str "https://gitlab.com/api/v4/projects/" project "/releases/" tag)
45+ (str "https://gitlab.com/api/v4/projects/" project "/releases?per_page=1"))
46+ body (json/parse-string (paths/out "curl" "-fsSL" url))]
47+ (if tag
48+ body
49+ (or (first body) (paths/die (str "no releases at all under " repo))))))
50+
51+;; The manifests this tree pins out of jolt-native. Every DotSlash file beside
52+;; this script whose providers point at the repo — rather than a list written
53+;; here, which would be a sixth place to forget.
54+(defn manifests []
55+ (->> (fs/glob here "*.dotslash")
56+ sort
57+ (keep (fn [file]
58+ (let [text (slurp (str file))
59+ json (json/parse-string (subs text (str/index-of text "{")))]
60+ (when (->> (get json "platforms")
61+ vals
62+ (some #(str/starts-with? (get-in % ["providers" 0 "url"]) repo)))
63+ {:file file :text text :json json}))))))
64+
65+;; The archive an entry names, at the new tag. The URL a manifest carries is the
66+;; release permalink — /-/releases/<tag>/downloads/<asset> — so the asset's name
67+;; is its last segment, and the name carries the version too. Both move.
68+(defn retag [url old new]
69+ (-> url
70+ (str/replace (str "/releases/" old "/") (str "/releases/" new "/"))
71+ (str/replace (str "-" old ".") (str "-" new "."))))
72+
73+(defn tag-of [url]
74+ (second (re-find #"/-/releases/([^/]+)/downloads/" url)))
75+
76+;; Fetch once per distinct URL, then weigh it: DotSlash wants the size and the
77+;; sha256 of the archive as downloaded, not of anything inside it.
78+(def weigh
79+ (memoize
80+ (fn [dir url]
81+ (let [file (fs/path dir (last (str/split url #"/")))]
82+ (println (str " fetching " (fs/file-name file)))
83+ (p/shell "curl" "-fsSL" "-o" (str file) url)
84+ {:size (fs/size file)
85+ :digest (first (str/split (paths/out "sha256sum" (str file)) #"\s+"))
86+ :file file}))))
87+
88+;; What the shim will reach for inside the archive. A release that moved a file
89+;; leaves a manifest that fetches and verifies and then cannot resolve, which is
90+;; a worse thing to find out from than this.
91+(defn check-path! [{:keys [file]} path]
92+ (let [names (set (str/split-lines (paths/out "tar" "-tzf" (str file))))]
93+ (when-not (some #(= path (str/replace % #"^\./" "")) names)
94+ (paths/die (str "no " path " in " (fs/file-name file))
95+ "The release moved it; the manifest's `path` needs a hand."))))
96+
97+;; The JSON back out, in the shape it went in: two-space indentation, a value
98+;; after each key, and the `//` comment block above it kept — that block is why
99+;; anyone reading the manifest knows what the object is for.
100+(def pretty
101+ (json/create-pretty-printer
102+ (assoc json/default-pretty-print-options
103+ :indentation " "
104+ :indent-arrays? true
105+ :object-field-value-separator ": ")))
106+
107+(defn rewrite [{:keys [file text json]} tmp tag]
108+ (let [platforms (get json "platforms")
109+ updated
110+ (into (array-map)
111+ (for [[platform entry] platforms
112+ :let [url (retag (get-in entry ["providers" 0 "url"]) (tag-of (get-in entry ["providers" 0 "url"])) tag)
113+ {:keys [size digest] :as got} (weigh tmp url)]]
114+ (do
115+ (check-path! got (get entry "path"))
116+ [platform (-> entry
117+ (assoc "size" size "digest" digest)
118+ (assoc-in ["providers" 0 "url"] url))])))
119+ head (subs text 0 (str/index-of text "{"))
120+ ;; The prose above the JSON names the release too — "from jolt-native's
121+ ;; v0.1.3 release". Left saying the old one it would be a lie the moment
122+ ;; this script succeeds.
123+ head (reduce (fn [h old] (str/replace h old tag))
124+ head
125+ (distinct (keep #(tag-of (get-in % ["providers" 0 "url"])) (vals platforms))))]
126+ (spit (str file) (str head (json/generate-string (assoc json "platforms" updated) {:pretty pretty}) "\n"))
127+ (println (str " " (fs/file-name file)))))
128+
129+;; deps.edn takes glimmer-vidya as a git dependency, and the boot image is
130+;; compiled from the source root jolt resolves that to. Replaced as text rather
131+;; than round-tripped as EDN: the file is mostly comments explaining why each
132+;; pin is where it is, and rewriting it as data would throw all of them away.
133+(defn bump-deps! [commit]
134+ (let [file (fs/path root "deps.edn")
135+ text (slurp (str file))
136+ old (paths/dep-sha root repo)]
137+ (cond
138+ (nil? old) (paths/die (str "no dependency on " repo " in deps.edn"))
139+ (= old commit) (println " deps.edn already at this commit")
140+ :else (do (spit (str file) (str/replace text old commit))
141+ (println (str " deps.edn " (subs old 0 8) " -> " (subs commit 0 8)))))))
142+
143+(let [tag (first *command-line-args*)
144+ rel (release tag)
145+ tag (get rel "tag_name")
146+ commit (get-in rel ["commit" "id"])
147+ files (manifests)
148+ tmp (fs/create-temp-dir {:prefix "jolt-native-"})]
149+ (when (empty? files)
150+ (paths/die (str "no DotSlash manifest in " here " points at " repo)))
151+ (println (str "jolt-native " tag " (" (subs commit 0 8) ")"))
152+ (try
153+ (doseq [m files] (rewrite m tmp tag))
154+ (finally (fs/delete-tree tmp)))
155+ (bump-deps! commit)
156+ (p/shell (str (fs/path here "dotslash-to-buck")))
157+ (println (str "\nNow: git diff, then `just lib` and `just apk` — the pins are "
158+ "written, nothing is built.")))
modified scripts/frq/paths.clj +12 -18
@@ -21,24 +21,18 @@
2121
2222 (defn env [k default] (or (not-empty (System/getenv k)) default))
2323
24-;; The checkout this tree belongs to, which in a git worktree is not this tree:
25-;; the scripts sit under .claude/worktrees/<name>, so "../jolt-native" from
26-;; here is nothing at all. --git-common-dir is the one thing that answers the
27-;; same in a worktree as in the checkout it came from.
28-(defn checkout [root]
29- (str (fs/parent (out "git" "-C" (str root)
30- "rev-parse" "--path-format=absolute" "--git-common-dir"))))
31-
32-;; jolt-native holds both native halves. A sibling checkout wins, so anyone
33-;; working on the two repos together builds what they are editing; everyone
34-;; else gets the clone `just lib` leaves under .jolt-native.
35-(defn jolt-native [root]
36- (or (env "JOLT_NATIVE" nil)
37- (let [c (checkout root)
38- sibling (fs/path (fs/parent c) "jolt-native")]
39- (if (fs/directory? sibling)
40- (str (fs/canonicalize sibling))
41- (str (fs/path c ".jolt-native"))))))
24+;; An archive pinned in scripts/*.dotslash, resolved to the file its manifest
25+;; names. DotSlash downloads it once, verifies the digest and caches it, so
26+;; every script here asks the same question of the same pin and a second
27+;; jolt-native checkout is never part of the answer.
28+;;
29+;; DOTSLASH names the fetcher for a caller that has one but has not got it on
30+;; PATH — buck sets it, because the fetcher is an input to those actions.
31+(defn dist [root name]
32+ (let [manifest (fs/path root "scripts" (str name ".dotslash"))]
33+ (when-not (fs/exists? manifest)
34+ (die (str "no DotSlash manifest: " manifest)))
35+ (out (env "DOTSLASH" "dotslash") "--" "fetch" manifest)))
4236
4337 ;; The sha deps.edn pins for a git url, so a bump there reaches the boot image.
4438 ;; Read as data rather than grepped: it is Clojure, and so is this.
@@ -21,24 +21,18 @@
21 21
22 (defn env [k default] (or (not-empty (System/getenv k)) default))22 (defn env [k default] (or (not-empty (System/getenv k)) default))
23 23
24-;; The checkout this tree belongs to, which in a git worktree is not this tree:24+;; An archive pinned in scripts/*.dotslash, resolved to the file its manifest
25-;; the scripts sit under .claude/worktrees/<name>, so "../jolt-native" from25+;; names. DotSlash downloads it once, verifies the digest and caches it, so
26-;; here is nothing at all. --git-common-dir is the one thing that answers the26+;; every script here asks the same question of the same pin and a second
27-;; same in a worktree as in the checkout it came from.27+;; jolt-native checkout is never part of the answer.
28-(defn checkout [root]28+;;
29- (str (fs/parent (out "git" "-C" (str root)29+;; DOTSLASH names the fetcher for a caller that has one but has not got it on
30- "rev-parse" "--path-format=absolute" "--git-common-dir"))))30+;; PATH — buck sets it, because the fetcher is an input to those actions.
31-31+(defn dist [root name]
32-;; jolt-native holds both native halves. A sibling checkout wins, so anyone32+ (let [manifest (fs/path root "scripts" (str name ".dotslash"))]
33-;; working on the two repos together builds what they are editing; everyone33+ (when-not (fs/exists? manifest)
34-;; else gets the clone `just lib` leaves under .jolt-native.34+ (die (str "no DotSlash manifest: " manifest)))
35-(defn jolt-native [root]35+ (out (env "DOTSLASH" "dotslash") "--" "fetch" manifest)))
36- (or (env "JOLT_NATIVE" nil)
37- (let [c (checkout root)
38- sibling (fs/path (fs/parent c) "jolt-native")]
39- (if (fs/directory? sibling)
40- (str (fs/canonicalize sibling))
41- (str (fs/path c ".jolt-native"))))))
42 36
43 ;; The sha deps.edn pins for a git url, so a bump there reaches the boot image.37 ;; The sha deps.edn pins for a git url, so a bump there reaches the boot image.
44 ;; Read as data rather than grepped: it is Clojure, and so is this.38 ;; Read as data rather than grepped: it is Clojure, and so is this.
modified scripts/glimmer-vidya.dotslash +13 -13
@@ -1,6 +1,6 @@
11 #!/usr/bin/env dotslash
22
3-// The Jolt side that binds the tree ABI, from jolt-native's v0.1.2 release.
3+// The Jolt side that binds the tree ABI, from jolt-native's v0.1.3 release.
44 //
55 // deps.edn takes this as a git dependency, and jolt resolves it into its own
66 // cache. The boot image cannot: a cross compile has no dependency resolution,
@@ -11,50 +11,50 @@
1111 "name": "glimmer-vidya",
1212 "platforms": {
1313 "linux-x86_64": {
14- "size": 18069,
14+ "size": 17988,
1515 "hash": "sha256",
16- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
16+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
1717 "format": "tar.gz",
1818 "path": "glimmer-vidya/deps.edn",
1919 "providers": [
2020 {
21- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"
21+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
2222 }
2323 ]
2424 },
2525 "linux-aarch64": {
26- "size": 18069,
26+ "size": 17988,
2727 "hash": "sha256",
28- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
28+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
2929 "format": "tar.gz",
3030 "path": "glimmer-vidya/deps.edn",
3131 "providers": [
3232 {
33- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"
33+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
3434 }
3535 ]
3636 },
3737 "macos-x86_64": {
38- "size": 18069,
38+ "size": 17988,
3939 "hash": "sha256",
40- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
40+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
4141 "format": "tar.gz",
4242 "path": "glimmer-vidya/deps.edn",
4343 "providers": [
4444 {
45- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"
45+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
4646 }
4747 ]
4848 },
4949 "macos-aarch64": {
50- "size": 18069,
50+ "size": 17988,
5151 "hash": "sha256",
52- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
52+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
5353 "format": "tar.gz",
5454 "path": "glimmer-vidya/deps.edn",
5555 "providers": [
5656 {
57- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"
57+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
5858 }
5959 ]
6060 }
@@ -1,6 +1,6 @@
1 #!/usr/bin/env dotslash1 #!/usr/bin/env dotslash
2 2
3-// The Jolt side that binds the tree ABI, from jolt-native's v0.1.2 release.3+// The Jolt side that binds the tree ABI, from jolt-native's v0.1.3 release.
4 //4 //
5 // deps.edn takes this as a git dependency, and jolt resolves it into its own5 // deps.edn takes this as a git dependency, and jolt resolves it into its own
6 // cache. The boot image cannot: a cross compile has no dependency resolution,6 // cache. The boot image cannot: a cross compile has no dependency resolution,
@@ -11,50 +11,50 @@
11 "name": "glimmer-vidya",11 "name": "glimmer-vidya",
12 "platforms": {12 "platforms": {
13 "linux-x86_64": {13 "linux-x86_64": {
14- "size": 18069,14+ "size": 17988,
15 "hash": "sha256",15 "hash": "sha256",
16- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",16+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
17 "format": "tar.gz",17 "format": "tar.gz",
18 "path": "glimmer-vidya/deps.edn",18 "path": "glimmer-vidya/deps.edn",
19 "providers": [19 "providers": [
20 {20 {
21- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"21+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
22 }22 }
23 ]23 ]
24 },24 },
25 "linux-aarch64": {25 "linux-aarch64": {
26- "size": 18069,26+ "size": 17988,
27 "hash": "sha256",27 "hash": "sha256",
28- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",28+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
29 "format": "tar.gz",29 "format": "tar.gz",
30 "path": "glimmer-vidya/deps.edn",30 "path": "glimmer-vidya/deps.edn",
31 "providers": [31 "providers": [
32 {32 {
33- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"33+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
34 }34 }
35 ]35 ]
36 },36 },
37 "macos-x86_64": {37 "macos-x86_64": {
38- "size": 18069,38+ "size": 17988,
39 "hash": "sha256",39 "hash": "sha256",
40- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",40+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
41 "format": "tar.gz",41 "format": "tar.gz",
42 "path": "glimmer-vidya/deps.edn",42 "path": "glimmer-vidya/deps.edn",
43 "providers": [43 "providers": [
44 {44 {
45- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"45+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
46 }46 }
47 ]47 ]
48 },48 },
49 "macos-aarch64": {49 "macos-aarch64": {
50- "size": 18069,50+ "size": 17988,
51 "hash": "sha256",51 "hash": "sha256",
52- "digest": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",52+ "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
53 "format": "tar.gz",53 "format": "tar.gz",
54 "path": "glimmer-vidya/deps.edn",54 "path": "glimmer-vidya/deps.edn",
55 "providers": [55 "providers": [
56 {56 {
57- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz"57+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
58 }58 }
59 ]59 ]
60 }60 }
modified scripts/lib.bb +50 -16
@@ -3,28 +3,62 @@
33 exec "$(dirname "$0")/bb" "$0" "$@"
44 )
55
6-;; Both native libraries: libvidya (the tree ABI glimmer-vidya binds) and
7-;; libjoltmoq (the AV media plane). One workspace, one target directory.
6+;; Both native libraries, out of jolt-native's release rather than a checkout.
87 ;;
9-;; A sibling jolt-native checkout wins, so anyone working on the two repos
10-;; together builds what they are editing; everyone else gets a clone of the
11-;; gitlab repo under .jolt-native, pinned to the commit deps.edn takes
12-;; glimmer-vidya from — one place to bump, rather than a second sha here.
8+;; libvidya is the tree ABI glimmer-vidya binds; libjoltmoq is the AV media
9+;; plane. They come out of one archive because they are built together, and
10+;; they land in build/lib because a loader wants one directory, which is where
11+;; run.bb points LD_LIBRARY_PATH.
12+;;
13+;; Nothing is compiled here. The pinned bytes are the bytes: this repo used to
14+;; clone jolt-native and cargo-build it, which meant a Rust toolchain, a build
15+;; whose output depended on the machine, and two places — the clone's sha and
16+;; the release digest — that could disagree about which jolt-native frq was
17+;; running against. Bump scripts/*.dotslash instead: see bump-jolt-native.bb.
18+;;
19+;; Linked rather than copied, so a bump reaches a running tree by relinking and
20+;; nothing goes stale in build/ — except for the one object that has to be
21+;; repaired on the way through. See below.
1322 (require '[babashka.classpath :as cp])
1423 (cp/add-classpath (str (babashka.fs/parent *file*)))
1524 (require '[frq.paths :as paths]
1625 '[babashka.fs :as fs]
17- '[babashka.process :as p])
26+ '[clojure.string :as str])
1827
1928 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
20-(def url "https://gitlab.com/nandithebull/jolt-native.git")
21-(def sha (paths/dep-sha root "https://gitlab.com/nandithebull/jolt-native"))
22-(def jolt-native (paths/jolt-native root))
29+(def lib (fs/path root "build" "lib"))
30+
31+;; v0.1.3's desktop libjoltmoq.so has 68 undefined `snd_*` symbols and no
32+;; DT_NEEDED on libasound: cpal's ALSA host is compiled in, and the library it
33+;; calls is not named. It is the defect that release fixed for Android, in the
34+;; place the fix did not reach — buck2 keeps a build script's cfgs and drops
35+;; its link directives, so `cargo:rustc-link-lib=asound` never became a link
36+;; argument. Undefined symbols are legal in a cdylib, so nothing said so until
37+;; something tried to load it.
38+;;
39+;; So the library is named here instead, on a copy: the DotSlash cache holds
40+;; what the release published, and rewriting that in place would make a
41+;; verified digest a lie about the bytes on disk.
42+;;
43+;; This goes away with the release that links it. `patchelf --print-needed`
44+;; below is the test for that — a fixed object is linked, not copied.
45+(def repairs {"libjoltmoq.so" "libasound.so.2"})
2346
24-;; Already here whenever the sibling checkout exists, since that is what
25-;; jolt-native then points at.
26-(when-not (fs/directory? jolt-native)
27- (p/shell "git" "clone" url jolt-native)
28- (p/shell {:dir jolt-native} "git" "checkout" "--detach" sha))
47+(defn needed [file]
48+ (set (str/split-lines (paths/out "patchelf" "--print-needed" file))))
2949
30-(p/shell {:dir jolt-native} "just" "build")
50+(fs/create-dirs lib)
51+(doseq [name ["libvidya-linux" "libjoltmoq-linux"]]
52+ (let [file (paths/dist root name)
53+ base (fs/file-name file)
54+ dest (fs/path lib base)
55+ missing (get repairs base)]
56+ (fs/delete-if-exists dest)
57+ (if (and missing (not (contains? (needed file) missing)))
58+ (do (fs/copy file dest)
59+ ;; Out of the cache read-only, and patchelf writes.
60+ (fs/set-posix-file-permissions dest "rw-r--r--")
61+ (paths/out "patchelf" "--add-needed" missing (str dest))
62+ (println (str (fs/relativize root dest) " <- " file " (+" missing ")")))
63+ (do (fs/create-sym-link dest file)
64+ (println (str (fs/relativize root dest) " -> " file))))))
@@ -3,28 +3,62 @@
3 exec "$(dirname "$0")/bb" "$0" "$@"3 exec "$(dirname "$0")/bb" "$0" "$@"
4 )4 )
5 5
6-;; Both native libraries: libvidya (the tree ABI glimmer-vidya binds) and6+;; Both native libraries, out of jolt-native's release rather than a checkout.
7-;; libjoltmoq (the AV media plane). One workspace, one target directory.
8 ;;7 ;;
9-;; A sibling jolt-native checkout wins, so anyone working on the two repos8+;; libvidya is the tree ABI glimmer-vidya binds; libjoltmoq is the AV media
10-;; together builds what they are editing; everyone else gets a clone of the9+;; plane. They come out of one archive because they are built together, and
11-;; gitlab repo under .jolt-native, pinned to the commit deps.edn takes10+;; they land in build/lib because a loader wants one directory, which is where
12-;; glimmer-vidya from — one place to bump, rather than a second sha here.11+;; run.bb points LD_LIBRARY_PATH.
12+;;
13+;; Nothing is compiled here. The pinned bytes are the bytes: this repo used to
14+;; clone jolt-native and cargo-build it, which meant a Rust toolchain, a build
15+;; whose output depended on the machine, and two places — the clone's sha and
16+;; the release digest — that could disagree about which jolt-native frq was
17+;; running against. Bump scripts/*.dotslash instead: see bump-jolt-native.bb.
18+;;
19+;; Linked rather than copied, so a bump reaches a running tree by relinking and
20+;; nothing goes stale in build/ — except for the one object that has to be
21+;; repaired on the way through. See below.
13 (require '[babashka.classpath :as cp])22 (require '[babashka.classpath :as cp])
14 (cp/add-classpath (str (babashka.fs/parent *file*)))23 (cp/add-classpath (str (babashka.fs/parent *file*)))
15 (require '[frq.paths :as paths]24 (require '[frq.paths :as paths]
16 '[babashka.fs :as fs]25 '[babashka.fs :as fs]
17- '[babashka.process :as p])26+ '[clojure.string :as str])
18 27
19 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))28 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
20-(def url "https://gitlab.com/nandithebull/jolt-native.git")29+(def lib (fs/path root "build" "lib"))
21-(def sha (paths/dep-sha root "https://gitlab.com/nandithebull/jolt-native"))30+
22-(def jolt-native (paths/jolt-native root))31+;; v0.1.3's desktop libjoltmoq.so has 68 undefined `snd_*` symbols and no
32+;; DT_NEEDED on libasound: cpal's ALSA host is compiled in, and the library it
33+;; calls is not named. It is the defect that release fixed for Android, in the
34+;; place the fix did not reach — buck2 keeps a build script's cfgs and drops
35+;; its link directives, so `cargo:rustc-link-lib=asound` never became a link
36+;; argument. Undefined symbols are legal in a cdylib, so nothing said so until
37+;; something tried to load it.
38+;;
39+;; So the library is named here instead, on a copy: the DotSlash cache holds
40+;; what the release published, and rewriting that in place would make a
41+;; verified digest a lie about the bytes on disk.
42+;;
43+;; This goes away with the release that links it. `patchelf --print-needed`
44+;; below is the test for that — a fixed object is linked, not copied.
45+(def repairs {"libjoltmoq.so" "libasound.so.2"})
23 46
24-;; Already here whenever the sibling checkout exists, since that is what47+(defn needed [file]
25-;; jolt-native then points at.48+ (set (str/split-lines (paths/out "patchelf" "--print-needed" file))))
26-(when-not (fs/directory? jolt-native)
27- (p/shell "git" "clone" url jolt-native)
28- (p/shell {:dir jolt-native} "git" "checkout" "--detach" sha))
29 49
30-(p/shell {:dir jolt-native} "just" "build")50+(fs/create-dirs lib)
51+(doseq [name ["libvidya-linux" "libjoltmoq-linux"]]
52+ (let [file (paths/dist root name)
53+ base (fs/file-name file)
54+ dest (fs/path lib base)
55+ missing (get repairs base)]
56+ (fs/delete-if-exists dest)
57+ (if (and missing (not (contains? (needed file) missing)))
58+ (do (fs/copy file dest)
59+ ;; Out of the cache read-only, and patchelf writes.
60+ (fs/set-posix-file-permissions dest "rw-r--r--")
61+ (paths/out "patchelf" "--add-needed" missing (str dest))
62+ (println (str (fs/relativize root dest) " <- " file " (+" missing ")")))
63+ (do (fs/create-sym-link dest file)
64+ (println (str (fs/relativize root dest) " -> " file))))))
modified scripts/libjoltmoq-android.dotslash +1 -1
@@ -11,7 +11,7 @@
1111 // PipeWire, which a phone has neither of. The camera is Camera2 over JNI now
1212 // and the microphone is cpal's AAudio host.
1313 //
14-// A sibling jolt-native checkout still wins over this, the same as libvidya.
14+// The only answer for it, the same as libvidya.
1515 {
1616 "name": "libjoltmoq-android",
1717 "platforms": {
@@ -11,7 +11,7 @@
11 // PipeWire, which a phone has neither of. The camera is Camera2 over JNI now11 // PipeWire, which a phone has neither of. The camera is Camera2 over JNI now
12 // and the microphone is cpal's AAudio host.12 // and the microphone is cpal's AAudio host.
13 //13 //
14-// A sibling jolt-native checkout still wins over this, the same as libvidya.14+// The only answer for it, the same as libvidya.
15 {15 {
16 "name": "libjoltmoq-android",16 "name": "libjoltmoq-android",
17 "platforms": {17 "platforms": {
added scripts/libjoltmoq-linux.dotslash +27 -0
new file mode 100755
@@ -0,0 +1,27 @@
1+#!/usr/bin/env dotslash
2+
3+// The AV media plane for the desktop, from jolt-native's v0.1.3 release.
4+//
5+// MoQ over QUIC, Opus and H.264, with V4L2 and PipeWire at the capture end.
6+// Out of the same archive as libvidya-linux and pinned with it, for the reason
7+// the Android pair gives: the two objects are built together, frq loads both,
8+// and one release's media plane beside another's UI is untested.
9+//
10+// x86_64 only; see libvidya-linux.
11+{
12+ "name": "libjoltmoq-linux",
13+ "platforms": {
14+ "linux-x86_64": {
15+ "size": 14870823,
16+ "hash": "sha256",
17+ "digest": "b49ca39793c0ee3809ba747d0040ac370ee4e6c92e433c53ca5459eaa90def18",
18+ "format": "tar.gz",
19+ "path": "libjoltmoq.so",
20+ "providers": [
21+ {
22+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-linux-x86_64-v0.1.3.tar.gz"
23+ }
24+ ]
25+ }
26+ }
27+}
new file mode 100755
@@ -0,0 +1,27 @@
1+#!/usr/bin/env dotslash
2+
3+// The AV media plane for the desktop, from jolt-native's v0.1.3 release.
4+//
5+// MoQ over QUIC, Opus and H.264, with V4L2 and PipeWire at the capture end.
6+// Out of the same archive as libvidya-linux and pinned with it, for the reason
7+// the Android pair gives: the two objects are built together, frq loads both,
8+// and one release's media plane beside another's UI is untested.
9+//
10+// x86_64 only; see libvidya-linux.
11+{
12+ "name": "libjoltmoq-linux",
13+ "platforms": {
14+ "linux-x86_64": {
15+ "size": 14870823,
16+ "hash": "sha256",
17+ "digest": "b49ca39793c0ee3809ba747d0040ac370ee4e6c92e433c53ca5459eaa90def18",
18+ "format": "tar.gz",
19+ "path": "libjoltmoq.so",
20+ "providers": [
21+ {
22+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-linux-x86_64-v0.1.3.tar.gz"
23+ }
24+ ]
25+ }
26+ }
27+}
modified scripts/libvidya-android.dotslash +4 -3
@@ -6,9 +6,10 @@
66 // same object `just ffi-android` produces there, pinned so that building the
77 // APK needs neither that checkout nor an NDK.
88 //
9-// A sibling jolt-native checkout still wins over this: see the `buck` recipe
10-// in the justfile. Anyone working on both repos at once builds what they are
11-// editing; everyone else gets these bytes.
9+// This is the only answer, and deliberately: a checkout used to win over it,
10+// which meant the APK on a phone depended on which directories happened to sit
11+// beside this one. To build against a jolt-native you are editing, cut a
12+// release of it and point these manifests at it `just bump <tag>`.
1213 {
1314 "name": "libvidya-android",
1415 "platforms": {
@@ -6,9 +6,10 @@
6 // same object `just ffi-android` produces there, pinned so that building the6 // same object `just ffi-android` produces there, pinned so that building the
7 // APK needs neither that checkout nor an NDK.7 // APK needs neither that checkout nor an NDK.
8 //8 //
9-// A sibling jolt-native checkout still wins over this: see the `buck` recipe9+// This is the only answer, and deliberately: a checkout used to win over it,
10-// in the justfile. Anyone working on both repos at once builds what they are10+// which meant the APK on a phone depended on which directories happened to sit
11-// editing; everyone else gets these bytes.11+// beside this one. To build against a jolt-native you are editing, cut a
12+// release of it and point these manifests at it `just bump <tag>`.
12 {13 {
13 "name": "libvidya-android",14 "name": "libvidya-android",
14 "platforms": {15 "platforms": {
added scripts/libvidya-linux.dotslash +27 -0
new file mode 100755
@@ -0,0 +1,27 @@
1+#!/usr/bin/env dotslash
2+
3+// libvidya for the desktop, from jolt-native's v0.1.3 release.
4+//
5+// The retained-tree ABI glimmer-vidya binds, on egui. `just lib` fetches this
6+// and libjoltmoq-linux one archive holds both and links them where `just
7+// run` points the loader.
8+//
9+// x86_64 only, because that is the only desktop asset the release cuts: a
10+// linux-aarch64 or a macOS frq needs jolt-native built by hand for now.
11+{
12+ "name": "libvidya-linux",
13+ "platforms": {
14+ "linux-x86_64": {
15+ "size": 14870823,
16+ "hash": "sha256",
17+ "digest": "b49ca39793c0ee3809ba747d0040ac370ee4e6c92e433c53ca5459eaa90def18",
18+ "format": "tar.gz",
19+ "path": "libvidya.so",
20+ "providers": [
21+ {
22+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-linux-x86_64-v0.1.3.tar.gz"
23+ }
24+ ]
25+ }
26+ }
27+}
new file mode 100755
@@ -0,0 +1,27 @@
1+#!/usr/bin/env dotslash
2+
3+// libvidya for the desktop, from jolt-native's v0.1.3 release.
4+//
5+// The retained-tree ABI glimmer-vidya binds, on egui. `just lib` fetches this
6+// and libjoltmoq-linux one archive holds both and links them where `just
7+// run` points the loader.
8+//
9+// x86_64 only, because that is the only desktop asset the release cuts: a
10+// linux-aarch64 or a macOS frq needs jolt-native built by hand for now.
11+{
12+ "name": "libvidya-linux",
13+ "platforms": {
14+ "linux-x86_64": {
15+ "size": 14870823,
16+ "hash": "sha256",
17+ "digest": "b49ca39793c0ee3809ba747d0040ac370ee4e6c92e433c53ca5459eaa90def18",
18+ "format": "tar.gz",
19+ "path": "libvidya.so",
20+ "providers": [
21+ {
22+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-linux-x86_64-v0.1.3.tar.gz"
23+ }
24+ ]
25+ }
26+ }
27+}
modified scripts/run.bb +5 -7
@@ -3,12 +3,10 @@
33 exec "$(dirname "$0")/bb" "$0" "$@"
44 )
55
6-;; The app. The native libraries are wherever jolt-native is — a sibling
7-;; checkout, or the clone `just lib` leaves under .jolt-native.
8-(require '[babashka.classpath :as cp])
9-(cp/add-classpath (str (babashka.fs/parent *file*)))
10-(require '[frq.paths :as paths]
11- '[babashka.fs :as fs]
6+;; The app, with the native libraries `just lib` linked into build/lib on the
7+;; loader path. Those are jolt-native's release, fetched by digest; nothing
8+;; here looks for a checkout of it.
9+(require '[babashka.fs :as fs]
1210 '[babashka.process :as p])
1311
1412 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
@@ -17,5 +15,5 @@ exec "$(dirname "$0")/bb" "$0" "$@"
1715 (:exit @(apply p/process
1816 {:inherit true
1917 :extra-env {"LD_LIBRARY_PATH"
20- (str (fs/path (paths/jolt-native root) "target" "release"))}}
18+ (str (fs/path root "build" "lib"))}}
2119 "jolt" "-M:frq" *command-line-args*)))
@@ -3,12 +3,10 @@
3 exec "$(dirname "$0")/bb" "$0" "$@"3 exec "$(dirname "$0")/bb" "$0" "$@"
4 )4 )
5 5
6-;; The app. The native libraries are wherever jolt-native is — a sibling6+;; The app, with the native libraries `just lib` linked into build/lib on the
7-;; checkout, or the clone `just lib` leaves under .jolt-native.7+;; loader path. Those are jolt-native's release, fetched by digest; nothing
8-(require '[babashka.classpath :as cp])8+;; here looks for a checkout of it.
9-(cp/add-classpath (str (babashka.fs/parent *file*)))9+(require '[babashka.fs :as fs]
10-(require '[frq.paths :as paths]
11- '[babashka.fs :as fs]
12 '[babashka.process :as p])10 '[babashka.process :as p])
13 11
14 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))12 (def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
@@ -17,5 +15,5 @@ exec "$(dirname "$0")/bb" "$0" "$@"
17 (:exit @(apply p/process15 (:exit @(apply p/process
18 {:inherit true16 {:inherit true
19 :extra-env {"LD_LIBRARY_PATH"17 :extra-env {"LD_LIBRARY_PATH"
20- (str (fs/path (paths/jolt-native root) "target" "release"))}}18+ (str (fs/path root "build" "lib"))}}
21 "jolt" "-M:frq" *command-line-args*)))19 "jolt" "-M:frq" *command-line-args*)))
modified toolchains/dist/generated.bzl +8 -8
@@ -58,26 +58,26 @@ DIST = {
5858 },
5959 "glimmer-vidya": {
6060 "linux-aarch64": {
61- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",
62- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
61+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
62+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
6363 "strip_prefix": "glimmer-vidya",
6464 "type": "tar.gz"
6565 },
6666 "linux-x86_64": {
67- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",
68- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
67+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
68+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
6969 "strip_prefix": "glimmer-vidya",
7070 "type": "tar.gz"
7171 },
7272 "macos-aarch64": {
73- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",
74- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
73+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
74+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
7575 "strip_prefix": "glimmer-vidya",
7676 "type": "tar.gz"
7777 },
7878 "macos-x86_64": {
79- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",
80- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",
79+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
80+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
8181 "strip_prefix": "glimmer-vidya",
8282 "type": "tar.gz"
8383 }
@@ -58,26 +58,26 @@ DIST = {
58 },58 },
59 "glimmer-vidya": {59 "glimmer-vidya": {
60 "linux-aarch64": {60 "linux-aarch64": {
61- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",61+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
62- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",62+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
63 "strip_prefix": "glimmer-vidya",63 "strip_prefix": "glimmer-vidya",
64 "type": "tar.gz"64 "type": "tar.gz"
65 },65 },
66 "linux-x86_64": {66 "linux-x86_64": {
67- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",67+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
68- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",68+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
69 "strip_prefix": "glimmer-vidya",69 "strip_prefix": "glimmer-vidya",
70 "type": "tar.gz"70 "type": "tar.gz"
71 },71 },
72 "macos-aarch64": {72 "macos-aarch64": {
73- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",73+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
74- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",74+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
75 "strip_prefix": "glimmer-vidya",75 "strip_prefix": "glimmer-vidya",
76 "type": "tar.gz"76 "type": "tar.gz"
77 },77 },
78 "macos-x86_64": {78 "macos-x86_64": {
79- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.2/downloads/jolt-native-glimmer-vidya-v0.1.2.tar.gz",79+ "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz",
80- "sha256": "1e544ef9c354e56bbfe280fee72e79e4a8bd6c746fe51a779e0afebb4465917d",80+ "sha256": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
81 "strip_prefix": "glimmer-vidya",81 "strip_prefix": "glimmer-vidya",
82 "type": "tar.gz"82 "type": "tar.gz"
83 }83 }