nandi/frqpublic Fork 0
3bc3aaa
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.

Build the APK as derivations only, and retire the buck2 graph

nix/android.nix already built everything android/BUCK did, and more: the
graph was handed an Android SDK, an NDK, a cross-built Chez and an
OpenSSL as absolute paths and stopped when one was missing, while the
derivations build or fetch every one of them. Two builds of the same APK
where one is a superset of the other is one too many, and the smaller one
was the one with prerequisites.

So buck2 goes, and with it the cells, the platforms, the toolchain table
generated from the DotSlash pins, and the pins that only buck read. The
step-by-step android/build-apk.bb goes too — it was the way to doubt the
graph, and there is no graph now.

`just apk` drives `nix build .#apk` and hands the store path to adb.
FRQ_NIX_STORE builds the whole thing somewhere else, which is the shape
android.nix asks for: with a `builders` entry nix drags androidenv's
3.1 GB NDK back through the local store, so an install copies the one
path back at the end instead.

The half of this that was a real defect: `just bump` rewrote the
manifests, deps.edn and the buck table, and never touched the two
fetchurl pins in nix/android.nix — so a bump moved the desktop libraries
and left the APK building against the release before it, silently. Now
bump-nix! rewrites every fetchurl there pointing at jolt-native, url and
sha256 as one match so the pair cannot half-move.

Getting to a nix on a host that has none was inline in run.bb; apk.bb
needs the same thing, so it is paths/nix now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-02T16:21:46-07:00 Browse files
3bc3aaa parent: 36f6c77
deleted .buckconfig +0 -32
deleted file mode 100644
@@ -1,32 +0,0 @@
1-[cells]
2- root = .
3- prelude = prelude
4- toolchains = toolchains
5- none = none
6-
7-[cell_aliases]
8- config = prelude
9- ovr_config = prelude
10- fbcode = none
11- fbsource = none
12- fbcode_macros = none
13- buck = none
14-
15-# The prelude bundled with the buck2 binary, so the only pinned thing is
16-# scripts/buck2 itself.
17-[external_cells]
18- prelude = bundled
19-
20-# Both of these name the cache-enabled platform, and both are needed: the
21-# second registers it, the first is what actually routes toolchain-owned
22-# actions onto it.
23-[parser]
24- target_platform_detector_spec = target:root//...->root//platforms:cache \
25- target:prelude//...->root//platforms:cache \
26- target:toolchains//...->root//platforms:cache
27-
28-[build]
29- execution_platforms = root//platforms:cache
30-
31-[project]
32- ignore = .git,android/build,build,buck-out
deleted file mode 100644
@@ -1,32 +0,0 @@
1-[cells]
2- root = .
3- prelude = prelude
4- toolchains = toolchains
5- none = none
6-
7-[cell_aliases]
8- config = prelude
9- ovr_config = prelude
10- fbcode = none
11- fbsource = none
12- fbcode_macros = none
13- buck = none
14-
15-# The prelude bundled with the buck2 binary, so the only pinned thing is
16-# scripts/buck2 itself.
17-[external_cells]
18- prelude = bundled
19-
20-# Both of these name the cache-enabled platform, and both are needed: the
21-# second registers it, the first is what actually routes toolchain-owned
22-# actions onto it.
23-[parser]
24- target_platform_detector_spec = target:root//...->root//platforms:cache \
25- target:prelude//...->root//platforms:cache \
26- target:toolchains//...->root//platforms:cache
27-
28-[build]
29- execution_platforms = root//platforms:cache
30-
31-[project]
32- ignore = .git,android/build,build,buck-out
deleted .buckroot +0 -0
deleted file mode 100644
deleted file mode 100644
modified .gitignore +0 -8
@@ -1,14 +1,6 @@
1-# Build outputs: the boot image and the APK.
2-/android/build/
3-
41 # The native libraries `just lib` links out of the DotSlash cache.
52 /build/
63
7-# buck2 output tree.
8-/buck-out
9-# Written by the `buck` recipe: this machine's paths, not a shared setting.
10-/.buckconfig.local
11-
124 # Tool caches.
135 /.cpcache/
146 /.jolt/
@@ -1,14 +1,6 @@
1-# Build outputs: the boot image and the APK.
2-/android/build/
3-
4 # The native libraries `just lib` links out of the DotSlash cache.1 # The native libraries `just lib` links out of the DotSlash cache.
5 /build/2 /build/
6 3
7-# buck2 output tree.
8-/buck-out
9-# Written by the `buck` recipe: this machine's paths, not a shared setting.
10-/.buckconfig.local
11-
12 # Tool caches.4 # Tool caches.
13 /.cpcache/5 /.cpcache/
14 /.jolt/6 /.jolt/
deleted BUCK +0 -15
deleted file mode 100644
@@ -1,15 +0,0 @@
1-# The Jolt sources the boot image is compiled from. Named as a target so that
2-# editing a screen invalidates the image: the compile itself reads the tree
3-# through deps.edn paths rather than through these, but buck only reruns it
4-# when something here changes.
5-filegroup(
6- name = "jolt-sources",
7- srcs = glob(["src/**/*.jolt", "src/**/*.edn"]) + ["deps.edn"],
8- visibility = ["PUBLIC"],
9-)
10-
11-alias(
12- name = "apk",
13- actual = "//android:apk",
14- visibility = ["PUBLIC"],
15-)
deleted file mode 100644
@@ -1,15 +0,0 @@
1-# The Jolt sources the boot image is compiled from. Named as a target so that
2-# editing a screen invalidates the image: the compile itself reads the tree
3-# through deps.edn paths rather than through these, but buck only reruns it
4-# when something here changes.
5-filegroup(
6- name = "jolt-sources",
7- srcs = glob(["src/**/*.jolt", "src/**/*.edn"]) + ["deps.edn"],
8- visibility = ["PUBLIC"],
9-)
10-
11-alias(
12- name = "apk",
13- actual = "//android:apk",
14- visibility = ["PUBLIC"],
15-)
modified README.md +9 -5
@@ -100,13 +100,17 @@ NativeActivity's own library), `libjoltmoq.so` (the media plane) and
100100 `libjoltapp.so` (frq compiled to a Chez boot image, linked against both).
101101
102102 ```bash
103-./android/build-apk.bb run # build, install, launch on a connected device
104-./android/build-apk.bb log # logcat, filtered
103+just apk run # build, install, launch on a connected device
104+just apk log # logcat, filtered
105105 ```
106106
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.
107+Needs nothing on the machine but Nix and an `adb`: the build is
108+[`nix/android.nix`](nix/android.nix), and the SDK, the NDK, the arm64 Chez
109+cross target and the OpenSSL the app carries are all built or fetched there.
110+`nix build .#apk` is the same thing without adb; on a machine with a remote
111+builder, hand it the store rather than a `builders` entry —
112+`FRQ_NIX_STORE=ssh-ng://eu.nixbuild.net just apk`, and see the header of
113+`nix/android.nix` for why.
110114
111115 TLS does not work there: jolt reaches OpenSSL through the dynamic loader, and
112116 Android has no public `libssl` to load. The connect screen falls back to the
@@ -100,13 +100,17 @@ NativeActivity's own library), `libjoltmoq.so` (the media plane) and
100 `libjoltapp.so` (frq compiled to a Chez boot image, linked against both).100 `libjoltapp.so` (frq compiled to a Chez boot image, linked against both).
101 101
102 ```bash102 ```bash
103-./android/build-apk.bb run # build, install, launch on a connected device103+just apk run # build, install, launch on a connected device
104-./android/build-apk.bb log # logcat, filtered104+just apk log # logcat, filtered
105 ```105 ```
106 106
107-Needs an SDK and a cross-built Chez in `~/.cache/vidya-chez-android`; the NDK107+Needs nothing on the machine but Nix and an `adb`: the build is
108-comes down through `scripts/android-ndk.dotslash`. `just apk` builds the same108+[`nix/android.nix`](nix/android.nix), and the SDK, the NDK, the arm64 Chez
109-APK as a buck2 graph, which is the incremental way in.109+cross target and the OpenSSL the app carries are all built or fetched there.
110+`nix build .#apk` is the same thing without adb; on a machine with a remote
111+builder, hand it the store rather than a `builders` entry —
112+`FRQ_NIX_STORE=ssh-ng://eu.nixbuild.net just apk`, and see the header of
113+`nix/android.nix` for why.
110 114
111 TLS does not work there: jolt reaches OpenSSL through the dynamic loader, and115 TLS does not work there: jolt reaches OpenSSL through the dynamic loader, and
112 Android has no public `libssl` to load. The connect screen falls back to the116 Android has no public `libssl` to load. The connect screen falls back to the
deleted android/BUCK +0 -254
deleted file mode 100644
@@ -1,254 +0,0 @@
1-# The APK, as a graph rather than a script.
2-#
3-# 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 the
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.
8-#
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 the
11-# machine; if a path is missing the recipe says which.
12-_ANDROID_HOME = read_root_config("frq", "android_home", "")
13-_CHEZ = read_root_config("frq", "chez_android", "")
14-_OPENSSL = read_root_config("frq", "openssl_android", "")
15-
16-_API = "28"
17-_TOOLS = _ANDROID_HOME + "/build-tools/36.0.0"
18-_ANDROID_JAR = _ANDROID_HOME + "/platforms/android-36/android.jar"
19-# `$(...)` in a genrule cmd is a buck macro, not the shell's substitution, so
20-# everything this file runs at command time uses backticks.
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.
24-_NDK_BIN = "ndk=`$(location //scripts:android-ndk-bin)`"
25-_CC = "$(location //scripts:android-cc)"
26-
27-# An absolute path for $OUT, so a command may cd without losing it. buck has
28-# already made the parent directory. Spelled out step by step because backticks
29-# do not nest.
30-# The archive's top directory is what strip_prefix took off, so `src` is
31-# directly inside it. Absolute, because the script is handed this and does its
32-# own directory changing.
33-_GLIMMER_VIDYA = "GLIMMER_VIDYA=`realpath $(location toolchains//dist:glimmer-vidya)/src` "
34-
35-# jolt_main.c and the ABI's headers, as targets rather than bare paths — see
36-# the rules below.
37-_GLUE_C = "`realpath $(location :glue-c)`"
38-_GLUE_INCLUDE = "`realpath $(location :glue-include)`"
39-
40-_ABS_OUT = 'd=`dirname "$OUT"` && b=`basename "$OUT"` && d=`cd "$d" && pwd` && out="$d/$b"'
41-
42-# Somewhere to assemble in. Removed by the command that made it, on success;
43-# buck's own scratch space is not this.
44-_TMP = 'tmp=`mktemp -d`'
45-
46-# A babashka script, run in place: it loads scripts/frq/paths.clj beside it and
47-# resolves its own interpreter through scripts/bb, the DotSlash pin. Referenced
48-# rather than copied for exactly that reason — the tree around it is part of it.
49-export_file(
50- name = "build-jolt-boot.bb",
51- mode = "reference",
52-)
53-
54-# --- the UI half ------------------------------------------------------------
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-)
74-
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-)
83-
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-)
92-
93-# The C++ runtime, out of the same NDK the glue is compiled with.
94-#
95-# openh264 is C++, and its build script asks to be linked against
96-# `libc++_shared.so` by name — so libjoltmoq carries that as a DT_NEEDED. An
97-# app's linker namespace will not hand out the platform's own copy (there is no
98-# stable one to hand out), so the APK has to carry it, exactly as it carries
99-# OpenSSL below and for the same reason.
100-#
101-# Only when the media plane is packaged: nothing else here is C++.
102-genrule(
103- name = "libcxx",
104- out = "libc++_shared.so",
105- cmd = _ABS_OUT + " && " + _NDK_BIN + " && " +
106- "cp \"$ndk\"/../sysroot/usr/lib/aarch64-linux-android/libc++_shared.so \"$out\"",
107-)
108-
109-# --- the Jolt half ----------------------------------------------------------
110-# The boot image: frq's Scheme, cross-compiled to arm64 by Chez. The sources
111-# are an input so that editing one rebuilds this; the compile itself reads them
112-# through the deps.edn the script writes.
113-# The sources here are frq's own. The other two roots the image is compiled
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
116-# jolt itself. None of them can be an input, so the `buck` recipe hashes them
117-# and writes the digest below; naming it in the command is what puts them in
118-# this action's identity.
119-# jolt reaches this action as a manifest and a fetcher rather than as a
120-# program: both are inputs, so nothing here depends on what is installed where
121-# the compile runs, and a remote worker resolves the same pin — by the same
122-# digest — from the same place this machine would.
123-genrule(
124- name = "jolt-boot",
125- out = "boot",
126- srcs = ["//:jolt-sources"],
127- cmd = "# sources outside this cell: " + read_root_config("frq", "boot_stamp", "unknown") + "\n" +
128- "DOTSLASH=$(location toolchains//dist:dotslash)/dotslash " +
129- "JOLT_MANIFEST=$(location //scripts:jolt) " +
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.
133- _GLIMMER_VIDYA +
134- "$(location :build-jolt-boot.bb) \"$OUT\" >&2",
135-)
136-
137-# The image travels as a blob in an object file's data section; the
138-# _binary_jolt_boot_{start,end} symbols jolt_main.c reads are named after the
139-# input *path*, which is why this copies the file somewhere it can be called
140-# exactly `jolt.boot` before converting it.
141-genrule(
142- name = "jolt-boot-obj",
143- out = "jolt_boot.o",
144- cmd = _ABS_OUT + " && " +
145- _TMP + " && " + _NDK_BIN + " && " +
146- "cp $(location :jolt-boot)/jolt.boot \"$tmp/jolt.boot\" && " +
147- "( cd \"$tmp\" && \"$ndk\"/llvm-objcopy " +
148- "--input-target=binary --output-target=elf64-littleaarch64 " +
149- "--binary-architecture=aarch64 jolt.boot jolt_boot.o ) && " +
150- "cp \"$tmp/jolt_boot.o\" \"$out\" && rm -rf \"$tmp\"",
151-)
152-
153-# The glue: jolt-native's android/jolt_main.c over the boot image, linked
154-# against libvidya by name. --no-undefined is what makes a symbol the Scheme
155-# side registers but the ABI no longer exports a build failure here rather than
156-# a crash on the phone.
157-genrule(
158- name = "libjoltapp",
159- out = "libjoltapp.so",
160- cmd = _ABS_OUT + " && lib=`mktemp -d` && " +
161- "cp $(location :libvidya) \"$lib/libvidya.so\" && " +
162- "cp $(location :libjoltmoq) \"$lib/libjoltmoq.so\" && " +
163- _CC + " -shared -fPIC -O2 -o \"$out\" " +
164- _GLUE_C + " " +
165- "$(location :jolt-boot-obj) " +
166- "-I$(location :jolt-boot) " +
167- "-I" + _GLUE_INCLUDE + " " +
168- "-L\"$lib\" " +
169- _CHEZ + "/tarm64le/boot/tarm64le/libkernel.a " +
170- _CHEZ + "/lz4/lib/liblz4.a " +
171- "-lvidya -ljoltmoq -landroid -llog -lz -ldl -lm -Wl,--no-undefined && " +
172- "rm -rf \"$lib\"",
173-)
174-
175-# --- the Java half ----------------------------------------------------------
176-# Two classes: the photo chooser's result has to land somewhere and native code
177-# is not somewhere, and Camera2 has no C API worth the name — CameraCapture
178-# opens the camera in Java and pushes NV12 planes down to libjoltmoq over JNI.
179-# android.jar on the class path is where every android.* type comes from; the
180-# JDK's own java.* is what is left.
181-genrule(
182- name = "classes-dex",
183- out = "classes.dex",
184- srcs = glob(["java/**/*.java"]),
185- cmd = _ABS_OUT + " && " + _TMP + " && " +
186- "javac --release 17 --class-path " + _ANDROID_JAR + " -d \"$tmp/classes\" $SRCS && " +
187- "classes=`find \"$tmp/classes\" -name '*.class'` && " +
188- _TOOLS + "/d8 --min-api " + _API + " --output \"$tmp\" $classes && " +
189- "cp \"$tmp/classes.dex\" \"$out\" && rm -rf \"$tmp\"",
190-)
191-
192-# --- the package ------------------------------------------------------------
193-# The libraries are stored rather than deflated: the loader maps them straight
194-# out of the APK. The dex is read rather than mapped, so it may as well
195-# compress. OpenSSL travels with the app because the platform's own is not ours
196-# to load — an app's linker namespace refuses /system/lib64/libssl.so, and
197-# without one there is no TLS on the phone at all.
198-genrule(
199- name = "apk-unsigned",
200- out = "frq-unsigned.apk",
201- srcs = ["AndroidManifest.xml"],
202- cmd = _ABS_OUT + " && stage=`mktemp -d` && " +
203- "mkdir -p \"$stage/lib/arm64-v8a\" && " +
204- "cp $(location :libvidya) \"$stage/lib/arm64-v8a/libvidya.so\" && " +
205- "cp $(location :libjoltapp) \"$stage/lib/arm64-v8a/libjoltapp.so\" && " +
206- "cp $(location :libjoltmoq) \"$stage/lib/arm64-v8a/libjoltmoq.so\" && " +
207- "cp $(location :libcxx) \"$stage/lib/arm64-v8a/libc++_shared.so\" && " +
208- "cp " + _OPENSSL + "/libssl.so " + _OPENSSL + "/libcrypto.so \"$stage/lib/arm64-v8a/\" && " +
209- "cp $(location :classes-dex) \"$stage/classes.dex\" && " +
210- _TOOLS + "/aapt2 link -o \"$out\" -I " + _ANDROID_JAR + " " +
211- "--manifest $SRCS --min-sdk-version " + _API + " --target-sdk-version 36 " +
212- "--version-code 1 --version-name 0.1.0 >&2 && " +
213- "( cd \"$stage\" && zip -q -0 \"$out\" lib/arm64-v8a/libvidya.so " +
214- "lib/arm64-v8a/libjoltmoq.so lib/arm64-v8a/libc++_shared.so " +
215- "lib/arm64-v8a/libjoltapp.so lib/arm64-v8a/libssl.so lib/arm64-v8a/libcrypto.so && " +
216- "zip -q \"$out\" classes.dex ) && rm -rf \"$stage\"",
217-)
218-
219-# Aligned and signed with the debug key, which is generated on first use the
220-# way the SDK's own tools generate it.
221-genrule(
222- name = "apk",
223- out = "frq.apk",
224- cmd = _ABS_OUT + " && " + _TMP + " && " +
225- "ks=\"$HOME/.android/debug.keystore\" && " +
226- "if [ ! -f \"$ks\" ]; then mkdir -p \"$HOME/.android\" && " +
227- "keytool -genkeypair -v -keystore \"$ks\" -storepass android -keypass android " +
228- "-alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 " +
229- "-dname 'CN=Android Debug,O=Android,C=US' >&2; fi && " +
230- _TOOLS + "/zipalign -f -p 4 $(location :apk-unsigned) \"$tmp/aligned.apk\" && " +
231- _TOOLS + "/apksigner sign --ks \"$ks\" --ks-key-alias androiddebugkey " +
232- "--ks-pass pass:android --key-pass pass:android --out \"$out\" \"$tmp/aligned.apk\" && " +
233- _TOOLS + "/apksigner verify \"$out\" >/dev/null && rm -rf \"$tmp\"",
234- visibility = ["PUBLIC"],
235-)
236-
237-# Does the pin resolve where the action runs, and does what it resolves to run
238-# there? Nothing depends on this; it is here to be asked by hand.
239-#
240-# buck2 build //android:jolt-fetch-check --remote-only --materializations=all \
241-# -c build.execution_platforms=root//platforms:remote -c "parser...->root//platforms:remote"
242-#
243-# It is what found the glibc floor: jolt needs 2.38, and the rbe-ubuntu22-04
244-# image this platform used to name ships 2.35, so the fetch succeeded and the
245-# binary would not start. The answer was the newer image, not a different pin.
246-genrule(
247- name = "jolt-fetch-check",
248- out = "report",
249- cmd = "jolt=`$(location toolchains//dist:dotslash)/dotslash -- fetch $(location //scripts:jolt)`; " +
250- "{ echo \"fetched: $jolt\"; " +
251- "cat /etc/os-release 2>/dev/null | head -1 || true; " +
252- "ldd --version 2>&1 | head -1 || true; " +
253- "echo '--- run ---'; \"$jolt\" --version; echo \"rc=$?\"; } > \"$OUT\" 2>&1 || true",
254-)
deleted file mode 100644
@@ -1,254 +0,0 @@
1-# The APK, as a graph rather than a script.
2-#
3-# 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 the
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.
8-#
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 the
11-# machine; if a path is missing the recipe says which.
12-_ANDROID_HOME = read_root_config("frq", "android_home", "")
13-_CHEZ = read_root_config("frq", "chez_android", "")
14-_OPENSSL = read_root_config("frq", "openssl_android", "")
15-
16-_API = "28"
17-_TOOLS = _ANDROID_HOME + "/build-tools/36.0.0"
18-_ANDROID_JAR = _ANDROID_HOME + "/platforms/android-36/android.jar"
19-# `$(...)` in a genrule cmd is a buck macro, not the shell's substitution, so
20-# everything this file runs at command time uses backticks.
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.
24-_NDK_BIN = "ndk=`$(location //scripts:android-ndk-bin)`"
25-_CC = "$(location //scripts:android-cc)"
26-
27-# An absolute path for $OUT, so a command may cd without losing it. buck has
28-# already made the parent directory. Spelled out step by step because backticks
29-# do not nest.
30-# The archive's top directory is what strip_prefix took off, so `src` is
31-# directly inside it. Absolute, because the script is handed this and does its
32-# own directory changing.
33-_GLIMMER_VIDYA = "GLIMMER_VIDYA=`realpath $(location toolchains//dist:glimmer-vidya)/src` "
34-
35-# jolt_main.c and the ABI's headers, as targets rather than bare paths — see
36-# the rules below.
37-_GLUE_C = "`realpath $(location :glue-c)`"
38-_GLUE_INCLUDE = "`realpath $(location :glue-include)`"
39-
40-_ABS_OUT = 'd=`dirname "$OUT"` && b=`basename "$OUT"` && d=`cd "$d" && pwd` && out="$d/$b"'
41-
42-# Somewhere to assemble in. Removed by the command that made it, on success;
43-# buck's own scratch space is not this.
44-_TMP = 'tmp=`mktemp -d`'
45-
46-# A babashka script, run in place: it loads scripts/frq/paths.clj beside it and
47-# resolves its own interpreter through scripts/bb, the DotSlash pin. Referenced
48-# rather than copied for exactly that reason — the tree around it is part of it.
49-export_file(
50- name = "build-jolt-boot.bb",
51- mode = "reference",
52-)
53-
54-# --- the UI half ------------------------------------------------------------
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-)
74-
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-)
83-
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-)
92-
93-# The C++ runtime, out of the same NDK the glue is compiled with.
94-#
95-# openh264 is C++, and its build script asks to be linked against
96-# `libc++_shared.so` by name — so libjoltmoq carries that as a DT_NEEDED. An
97-# app's linker namespace will not hand out the platform's own copy (there is no
98-# stable one to hand out), so the APK has to carry it, exactly as it carries
99-# OpenSSL below and for the same reason.
100-#
101-# Only when the media plane is packaged: nothing else here is C++.
102-genrule(
103- name = "libcxx",
104- out = "libc++_shared.so",
105- cmd = _ABS_OUT + " && " + _NDK_BIN + " && " +
106- "cp \"$ndk\"/../sysroot/usr/lib/aarch64-linux-android/libc++_shared.so \"$out\"",
107-)
108-
109-# --- the Jolt half ----------------------------------------------------------
110-# The boot image: frq's Scheme, cross-compiled to arm64 by Chez. The sources
111-# are an input so that editing one rebuilds this; the compile itself reads them
112-# through the deps.edn the script writes.
113-# The sources here are frq's own. The other two roots the image is compiled
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
116-# jolt itself. None of them can be an input, so the `buck` recipe hashes them
117-# and writes the digest below; naming it in the command is what puts them in
118-# this action's identity.
119-# jolt reaches this action as a manifest and a fetcher rather than as a
120-# program: both are inputs, so nothing here depends on what is installed where
121-# the compile runs, and a remote worker resolves the same pin — by the same
122-# digest — from the same place this machine would.
123-genrule(
124- name = "jolt-boot",
125- out = "boot",
126- srcs = ["//:jolt-sources"],
127- cmd = "# sources outside this cell: " + read_root_config("frq", "boot_stamp", "unknown") + "\n" +
128- "DOTSLASH=$(location toolchains//dist:dotslash)/dotslash " +
129- "JOLT_MANIFEST=$(location //scripts:jolt) " +
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.
133- _GLIMMER_VIDYA +
134- "$(location :build-jolt-boot.bb) \"$OUT\" >&2",
135-)
136-
137-# The image travels as a blob in an object file's data section; the
138-# _binary_jolt_boot_{start,end} symbols jolt_main.c reads are named after the
139-# input *path*, which is why this copies the file somewhere it can be called
140-# exactly `jolt.boot` before converting it.
141-genrule(
142- name = "jolt-boot-obj",
143- out = "jolt_boot.o",
144- cmd = _ABS_OUT + " && " +
145- _TMP + " && " + _NDK_BIN + " && " +
146- "cp $(location :jolt-boot)/jolt.boot \"$tmp/jolt.boot\" && " +
147- "( cd \"$tmp\" && \"$ndk\"/llvm-objcopy " +
148- "--input-target=binary --output-target=elf64-littleaarch64 " +
149- "--binary-architecture=aarch64 jolt.boot jolt_boot.o ) && " +
150- "cp \"$tmp/jolt_boot.o\" \"$out\" && rm -rf \"$tmp\"",
151-)
152-
153-# The glue: jolt-native's android/jolt_main.c over the boot image, linked
154-# against libvidya by name. --no-undefined is what makes a symbol the Scheme
155-# side registers but the ABI no longer exports a build failure here rather than
156-# a crash on the phone.
157-genrule(
158- name = "libjoltapp",
159- out = "libjoltapp.so",
160- cmd = _ABS_OUT + " && lib=`mktemp -d` && " +
161- "cp $(location :libvidya) \"$lib/libvidya.so\" && " +
162- "cp $(location :libjoltmoq) \"$lib/libjoltmoq.so\" && " +
163- _CC + " -shared -fPIC -O2 -o \"$out\" " +
164- _GLUE_C + " " +
165- "$(location :jolt-boot-obj) " +
166- "-I$(location :jolt-boot) " +
167- "-I" + _GLUE_INCLUDE + " " +
168- "-L\"$lib\" " +
169- _CHEZ + "/tarm64le/boot/tarm64le/libkernel.a " +
170- _CHEZ + "/lz4/lib/liblz4.a " +
171- "-lvidya -ljoltmoq -landroid -llog -lz -ldl -lm -Wl,--no-undefined && " +
172- "rm -rf \"$lib\"",
173-)
174-
175-# --- the Java half ----------------------------------------------------------
176-# Two classes: the photo chooser's result has to land somewhere and native code
177-# is not somewhere, and Camera2 has no C API worth the name — CameraCapture
178-# opens the camera in Java and pushes NV12 planes down to libjoltmoq over JNI.
179-# android.jar on the class path is where every android.* type comes from; the
180-# JDK's own java.* is what is left.
181-genrule(
182- name = "classes-dex",
183- out = "classes.dex",
184- srcs = glob(["java/**/*.java"]),
185- cmd = _ABS_OUT + " && " + _TMP + " && " +
186- "javac --release 17 --class-path " + _ANDROID_JAR + " -d \"$tmp/classes\" $SRCS && " +
187- "classes=`find \"$tmp/classes\" -name '*.class'` && " +
188- _TOOLS + "/d8 --min-api " + _API + " --output \"$tmp\" $classes && " +
189- "cp \"$tmp/classes.dex\" \"$out\" && rm -rf \"$tmp\"",
190-)
191-
192-# --- the package ------------------------------------------------------------
193-# The libraries are stored rather than deflated: the loader maps them straight
194-# out of the APK. The dex is read rather than mapped, so it may as well
195-# compress. OpenSSL travels with the app because the platform's own is not ours
196-# to load — an app's linker namespace refuses /system/lib64/libssl.so, and
197-# without one there is no TLS on the phone at all.
198-genrule(
199- name = "apk-unsigned",
200- out = "frq-unsigned.apk",
201- srcs = ["AndroidManifest.xml"],
202- cmd = _ABS_OUT + " && stage=`mktemp -d` && " +
203- "mkdir -p \"$stage/lib/arm64-v8a\" && " +
204- "cp $(location :libvidya) \"$stage/lib/arm64-v8a/libvidya.so\" && " +
205- "cp $(location :libjoltapp) \"$stage/lib/arm64-v8a/libjoltapp.so\" && " +
206- "cp $(location :libjoltmoq) \"$stage/lib/arm64-v8a/libjoltmoq.so\" && " +
207- "cp $(location :libcxx) \"$stage/lib/arm64-v8a/libc++_shared.so\" && " +
208- "cp " + _OPENSSL + "/libssl.so " + _OPENSSL + "/libcrypto.so \"$stage/lib/arm64-v8a/\" && " +
209- "cp $(location :classes-dex) \"$stage/classes.dex\" && " +
210- _TOOLS + "/aapt2 link -o \"$out\" -I " + _ANDROID_JAR + " " +
211- "--manifest $SRCS --min-sdk-version " + _API + " --target-sdk-version 36 " +
212- "--version-code 1 --version-name 0.1.0 >&2 && " +
213- "( cd \"$stage\" && zip -q -0 \"$out\" lib/arm64-v8a/libvidya.so " +
214- "lib/arm64-v8a/libjoltmoq.so lib/arm64-v8a/libc++_shared.so " +
215- "lib/arm64-v8a/libjoltapp.so lib/arm64-v8a/libssl.so lib/arm64-v8a/libcrypto.so && " +
216- "zip -q \"$out\" classes.dex ) && rm -rf \"$stage\"",
217-)
218-
219-# Aligned and signed with the debug key, which is generated on first use the
220-# way the SDK's own tools generate it.
221-genrule(
222- name = "apk",
223- out = "frq.apk",
224- cmd = _ABS_OUT + " && " + _TMP + " && " +
225- "ks=\"$HOME/.android/debug.keystore\" && " +
226- "if [ ! -f \"$ks\" ]; then mkdir -p \"$HOME/.android\" && " +
227- "keytool -genkeypair -v -keystore \"$ks\" -storepass android -keypass android " +
228- "-alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 " +
229- "-dname 'CN=Android Debug,O=Android,C=US' >&2; fi && " +
230- _TOOLS + "/zipalign -f -p 4 $(location :apk-unsigned) \"$tmp/aligned.apk\" && " +
231- _TOOLS + "/apksigner sign --ks \"$ks\" --ks-key-alias androiddebugkey " +
232- "--ks-pass pass:android --key-pass pass:android --out \"$out\" \"$tmp/aligned.apk\" && " +
233- _TOOLS + "/apksigner verify \"$out\" >/dev/null && rm -rf \"$tmp\"",
234- visibility = ["PUBLIC"],
235-)
236-
237-# Does the pin resolve where the action runs, and does what it resolves to run
238-# there? Nothing depends on this; it is here to be asked by hand.
239-#
240-# buck2 build //android:jolt-fetch-check --remote-only --materializations=all \
241-# -c build.execution_platforms=root//platforms:remote -c "parser...->root//platforms:remote"
242-#
243-# It is what found the glibc floor: jolt needs 2.38, and the rbe-ubuntu22-04
244-# image this platform used to name ships 2.35, so the fetch succeeded and the
245-# binary would not start. The answer was the newer image, not a different pin.
246-genrule(
247- name = "jolt-fetch-check",
248- out = "report",
249- cmd = "jolt=`$(location toolchains//dist:dotslash)/dotslash -- fetch $(location //scripts:jolt)`; " +
250- "{ echo \"fetched: $jolt\"; " +
251- "cat /etc/os-release 2>/dev/null | head -1 || true; " +
252- "ldd --version 2>&1 | head -1 || true; " +
253- "echo '--- run ---'; \"$jolt\" --version; echo \"rc=$?\"; } > \"$OUT\" 2>&1 || true",
254-)
deleted android/build-apk.bb +0 -177
deleted file mode 100755
@@ -1,177 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
4-)
5-
6-;; Glue the two halves of the frq Android app into an APK.
7-;;
8-;; libvidya.so the C ABI on Rust/egui, out of the pinned release, and the
9-;; NativeActivity's own library (it holds android-activity's
10-;; glue, so it owns the event loop)
11-;; libjoltmoq.so the AV media plane — MoQ over QUIC, Opus, H.264, Camera2
12-;; libjoltapp.so jolt-native's android/jolt_main.c plus frq's Jolt boot
13-;; image, dlopened by the above
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
18-;; libssl.so OpenSSL, because the platform's own is not ours to load: an
19-;; libcrypto.so app's linker namespace refuses /system/lib64/libssl.so, and
20-;; without one there is no TLS at all on the phone
21-;;
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.
26-;;
27-;; build-apk.bb [build|install|run|log]
28-(require '[babashka.classpath :as cp])
29-(cp/add-classpath (str (babashka.fs/path (babashka.fs/parent *file*) ".." "scripts")))
30-(require '[frq.paths :as paths]
31- '[babashka.fs :as fs]
32- '[babashka.process :as p])
33-
34-(def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
35-(def action (or (first *command-line-args*) "build"))
36-
37-(def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
38-(def ndk-home (paths/env "ANDROID_NDK_HOME" (str (fs/path (fs/home) ".local" "share" "android-ndk-r29"))))
39-(def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
40-(def openssl (paths/env "OPENSSL_ANDROID" (str (fs/path (fs/home) ".cache" "frq-openssl-android" "lib"))))
41-(def build (fs/path root "android" "build"))
42-(def jolt-build (fs/path build "jolt"))
43-(def stage (fs/path build "stage"))
44-(def tools (fs/path android-home "build-tools" "36.0.0"))
45-(def android-jar (fs/path android-home "platforms" "android-36" "android.jar"))
46-(def adb (paths/env "ADB" (str (fs/path android-home "platform-tools" "adb"))))
47-(def ndk-bin (fs/path ndk-home "toolchains" "llvm" "prebuilt" "linux-x86_64" "bin"))
48-(def package "uk.nandi.frq")
49-(def activity (str package "/.FrqActivity"))
50-(def api "28")
51-(def clang (str (fs/path ndk-bin (str "aarch64-linux-android" api "-clang"))))
52-(def arm-lib (fs/path stage "lib" "arm64-v8a"))
53-
54-(paths/require-paths! "Android tool"
55- [clang android-jar
56- (fs/path tools "aapt2") (fs/path tools "zipalign")
57- (fs/path tools "apksigner") (fs/path tools "d8")
58- (fs/path openssl "libssl.so") (fs/path openssl "libcrypto.so")])
59-
60-;; --- the UI half -----------------------------------------------------------
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])
72-
73-;; --- the Jolt half ---------------------------------------------------------
74-(p/shell (str (fs/path root "android" "build-jolt-boot.bb")) (str jolt-build))
75-;; The boot image travels as a blob in the object file's data section; the
76-;; _binary_jolt_boot_{start,end} symbols jolt_main.c reads come from this.
77-(p/shell {:dir (str jolt-build)}
78- (str (fs/path ndk-bin "llvm-objcopy"))
79- "--input-target=binary"
80- "--output-target=elf64-littleaarch64"
81- "--binary-architecture=aarch64"
82- "jolt.boot" "jolt_boot.o")
83-
84-;; --- the Java half ---------------------------------------------------------
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.
88-(def java-build (fs/path build "java"))
89-(fs/delete-tree java-build)
90-(fs/create-dirs (fs/path java-build "classes"))
91-;; android.jar on the class path is where every android.* type comes from; the
92-;; JDK's own java.* is what is left, and neither class uses anything of it that
93-;; Android does not have. (`-bootclasspath` would be the stricter way to say
94-;; that, and javac refuses it for a release this recent.)
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")))
103-(apply p/shell (str (fs/path tools "d8")) "--min-api" api "--output" (str java-build)
104- (map str (fs/glob (fs/path java-build "classes") "**.class")))
105-
106-(fs/delete-tree stage)
107-(fs/create-dirs arm-lib)
108-(fs/copy (fs/path java-build "classes.dex") (fs/path stage "classes.dex"))
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"))
117-;; jolt.mvn-http dlopens these by name at first use; beside the app's own
118-;; libraries is where an app's namespace will answer for that name.
119-(doseq [lib ["libssl.so" "libcrypto.so"]]
120- (fs/copy (fs/path openssl lib) (fs/path arm-lib lib)))
121-
122-(p/shell clang "-shared" "-fPIC" "-O2"
123- "-o" (str (fs/path arm-lib "libjoltapp.so"))
124- (str glue-c)
125- (str (fs/path jolt-build "jolt_boot.o"))
126- (str "-I" jolt-build)
127- (str "-I" glue-include)
128- (str "-L" arm-lib)
129- (str (fs/path chez "tarm64le" "boot" "tarm64le" "libkernel.a"))
130- (str (fs/path chez "lz4" "lib" "liblz4.a"))
131- "-lvidya" "-ljoltmoq" "-landroid" "-llog" "-lz" "-ldl" "-lm"
132- "-Wl,--no-undefined")
133-
134-;; --- the APK ---------------------------------------------------------------
135-(def unaligned (fs/path build "frq-unaligned.apk"))
136-(def aligned (fs/path build "frq-aligned.apk"))
137-(def apk (fs/path build "frq.apk"))
138-(run! fs/delete-if-exists [unaligned aligned apk])
139-(p/shell (str (fs/path tools "aapt2")) "link"
140- "-o" (str unaligned)
141- "-I" (str android-jar)
142- "--manifest" (str (fs/path root "android" "AndroidManifest.xml"))
143- "--min-sdk-version" api
144- "--target-sdk-version" "36"
145- "--version-code" "1"
146- "--version-name" "0.1.0")
147-;; Stored, not deflated: the loader maps these straight out of the APK.
148-(p/shell {:dir (str stage)} "zip" "-q" "-0" (str unaligned)
149- "lib/arm64-v8a/libvidya.so" "lib/arm64-v8a/libjoltmoq.so"
150- "lib/arm64-v8a/libc++_shared.so" "lib/arm64-v8a/libjoltapp.so"
151- "lib/arm64-v8a/libssl.so" "lib/arm64-v8a/libcrypto.so")
152-;; The dex is read by the runtime rather than mapped, so it may as well deflate.
153-(p/shell {:dir (str stage)} "zip" "-q" (str unaligned) "classes.dex")
154-(p/shell (str (fs/path tools "zipalign")) "-f" "-p" "4" (str unaligned) (str aligned))
155-
156-(def keystore (fs/path (fs/home) ".android" "debug.keystore"))
157-(when-not (fs/exists? keystore)
158- (fs/create-dirs (fs/parent keystore))
159- (p/shell "keytool" "-genkeypair" "-v"
160- "-keystore" (str keystore) "-storepass" "android" "-keypass" "android"
161- "-alias" "androiddebugkey" "-keyalg" "RSA" "-keysize" "2048"
162- "-validity" "10000"
163- "-dname" "CN=Android Debug,O=Android,C=US"))
164-(p/shell (str (fs/path tools "apksigner")) "sign"
165- "--ks" (str keystore) "--ks-key-alias" "androiddebugkey"
166- "--ks-pass" "pass:android" "--key-pass" "pass:android"
167- "--out" (str apk) (str aligned))
168-(p/shell {:out :string} (str (fs/path tools "apksigner")) "verify" (str apk))
169-
170-(case action
171- "build" (println (str apk))
172- "install" (p/shell adb "install" "-r" (str apk))
173- "run" (do (p/shell adb "install" "-r" (str apk))
174- (p/shell adb "shell" "am" "force-stop" package)
175- (p/shell adb "shell" "am" "start" "-n" activity))
176- "log" (p/shell adb "logcat" "-s" "VidyaJolt" "Vidya")
177- (paths/die "usage: build-apk.bb [build|install|run|log]"))
deleted file mode 100755
@@ -1,177 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
4-)
5-
6-;; Glue the two halves of the frq Android app into an APK.
7-;;
8-;; libvidya.so the C ABI on Rust/egui, out of the pinned release, and the
9-;; NativeActivity's own library (it holds android-activity's
10-;; glue, so it owns the event loop)
11-;; libjoltmoq.so the AV media plane — MoQ over QUIC, Opus, H.264, Camera2
12-;; libjoltapp.so jolt-native's android/jolt_main.c plus frq's Jolt boot
13-;; image, dlopened by the above
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
18-;; libssl.so OpenSSL, because the platform's own is not ours to load: an
19-;; libcrypto.so app's linker namespace refuses /system/lib64/libssl.so, and
20-;; without one there is no TLS at all on the phone
21-;;
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.
26-;;
27-;; build-apk.bb [build|install|run|log]
28-(require '[babashka.classpath :as cp])
29-(cp/add-classpath (str (babashka.fs/path (babashka.fs/parent *file*) ".." "scripts")))
30-(require '[frq.paths :as paths]
31- '[babashka.fs :as fs]
32- '[babashka.process :as p])
33-
34-(def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
35-(def action (or (first *command-line-args*) "build"))
36-
37-(def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
38-(def ndk-home (paths/env "ANDROID_NDK_HOME" (str (fs/path (fs/home) ".local" "share" "android-ndk-r29"))))
39-(def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
40-(def openssl (paths/env "OPENSSL_ANDROID" (str (fs/path (fs/home) ".cache" "frq-openssl-android" "lib"))))
41-(def build (fs/path root "android" "build"))
42-(def jolt-build (fs/path build "jolt"))
43-(def stage (fs/path build "stage"))
44-(def tools (fs/path android-home "build-tools" "36.0.0"))
45-(def android-jar (fs/path android-home "platforms" "android-36" "android.jar"))
46-(def adb (paths/env "ADB" (str (fs/path android-home "platform-tools" "adb"))))
47-(def ndk-bin (fs/path ndk-home "toolchains" "llvm" "prebuilt" "linux-x86_64" "bin"))
48-(def package "uk.nandi.frq")
49-(def activity (str package "/.FrqActivity"))
50-(def api "28")
51-(def clang (str (fs/path ndk-bin (str "aarch64-linux-android" api "-clang"))))
52-(def arm-lib (fs/path stage "lib" "arm64-v8a"))
53-
54-(paths/require-paths! "Android tool"
55- [clang android-jar
56- (fs/path tools "aapt2") (fs/path tools "zipalign")
57- (fs/path tools "apksigner") (fs/path tools "d8")
58- (fs/path openssl "libssl.so") (fs/path openssl "libcrypto.so")])
59-
60-;; --- the UI half -----------------------------------------------------------
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])
72-
73-;; --- the Jolt half ---------------------------------------------------------
74-(p/shell (str (fs/path root "android" "build-jolt-boot.bb")) (str jolt-build))
75-;; The boot image travels as a blob in the object file's data section; the
76-;; _binary_jolt_boot_{start,end} symbols jolt_main.c reads come from this.
77-(p/shell {:dir (str jolt-build)}
78- (str (fs/path ndk-bin "llvm-objcopy"))
79- "--input-target=binary"
80- "--output-target=elf64-littleaarch64"
81- "--binary-architecture=aarch64"
82- "jolt.boot" "jolt_boot.o")
83-
84-;; --- the Java half ---------------------------------------------------------
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.
88-(def java-build (fs/path build "java"))
89-(fs/delete-tree java-build)
90-(fs/create-dirs (fs/path java-build "classes"))
91-;; android.jar on the class path is where every android.* type comes from; the
92-;; JDK's own java.* is what is left, and neither class uses anything of it that
93-;; Android does not have. (`-bootclasspath` would be the stricter way to say
94-;; that, and javac refuses it for a release this recent.)
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")))
103-(apply p/shell (str (fs/path tools "d8")) "--min-api" api "--output" (str java-build)
104- (map str (fs/glob (fs/path java-build "classes") "**.class")))
105-
106-(fs/delete-tree stage)
107-(fs/create-dirs arm-lib)
108-(fs/copy (fs/path java-build "classes.dex") (fs/path stage "classes.dex"))
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"))
117-;; jolt.mvn-http dlopens these by name at first use; beside the app's own
118-;; libraries is where an app's namespace will answer for that name.
119-(doseq [lib ["libssl.so" "libcrypto.so"]]
120- (fs/copy (fs/path openssl lib) (fs/path arm-lib lib)))
121-
122-(p/shell clang "-shared" "-fPIC" "-O2"
123- "-o" (str (fs/path arm-lib "libjoltapp.so"))
124- (str glue-c)
125- (str (fs/path jolt-build "jolt_boot.o"))
126- (str "-I" jolt-build)
127- (str "-I" glue-include)
128- (str "-L" arm-lib)
129- (str (fs/path chez "tarm64le" "boot" "tarm64le" "libkernel.a"))
130- (str (fs/path chez "lz4" "lib" "liblz4.a"))
131- "-lvidya" "-ljoltmoq" "-landroid" "-llog" "-lz" "-ldl" "-lm"
132- "-Wl,--no-undefined")
133-
134-;; --- the APK ---------------------------------------------------------------
135-(def unaligned (fs/path build "frq-unaligned.apk"))
136-(def aligned (fs/path build "frq-aligned.apk"))
137-(def apk (fs/path build "frq.apk"))
138-(run! fs/delete-if-exists [unaligned aligned apk])
139-(p/shell (str (fs/path tools "aapt2")) "link"
140- "-o" (str unaligned)
141- "-I" (str android-jar)
142- "--manifest" (str (fs/path root "android" "AndroidManifest.xml"))
143- "--min-sdk-version" api
144- "--target-sdk-version" "36"
145- "--version-code" "1"
146- "--version-name" "0.1.0")
147-;; Stored, not deflated: the loader maps these straight out of the APK.
148-(p/shell {:dir (str stage)} "zip" "-q" "-0" (str unaligned)
149- "lib/arm64-v8a/libvidya.so" "lib/arm64-v8a/libjoltmoq.so"
150- "lib/arm64-v8a/libc++_shared.so" "lib/arm64-v8a/libjoltapp.so"
151- "lib/arm64-v8a/libssl.so" "lib/arm64-v8a/libcrypto.so")
152-;; The dex is read by the runtime rather than mapped, so it may as well deflate.
153-(p/shell {:dir (str stage)} "zip" "-q" (str unaligned) "classes.dex")
154-(p/shell (str (fs/path tools "zipalign")) "-f" "-p" "4" (str unaligned) (str aligned))
155-
156-(def keystore (fs/path (fs/home) ".android" "debug.keystore"))
157-(when-not (fs/exists? keystore)
158- (fs/create-dirs (fs/parent keystore))
159- (p/shell "keytool" "-genkeypair" "-v"
160- "-keystore" (str keystore) "-storepass" "android" "-keypass" "android"
161- "-alias" "androiddebugkey" "-keyalg" "RSA" "-keysize" "2048"
162- "-validity" "10000"
163- "-dname" "CN=Android Debug,O=Android,C=US"))
164-(p/shell (str (fs/path tools "apksigner")) "sign"
165- "--ks" (str keystore) "--ks-key-alias" "androiddebugkey"
166- "--ks-pass" "pass:android" "--key-pass" "pass:android"
167- "--out" (str apk) (str aligned))
168-(p/shell {:out :string} (str (fs/path tools "apksigner")) "verify" (str apk))
169-
170-(case action
171- "build" (println (str apk))
172- "install" (p/shell adb "install" "-r" (str apk))
173- "run" (do (p/shell adb "install" "-r" (str apk))
174- (p/shell adb "shell" "am" "force-stop" package)
175- (p/shell adb "shell" "am" "start" "-n" activity))
176- "log" (p/shell adb "logcat" "-s" "VidyaJolt" "Vidya")
177- (paths/die "usage: build-apk.bb [build|install|run|log]"))
deleted android/build-jolt-boot.bb +0 -180
deleted file mode 100755
@@ -1,180 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
4-)
5-
6-;; frq's Scheme, cross-compiled to an arm64 Chez boot image.
7-;;
8-;; build-jolt-boot.bb OUTPUT_DIRECTORY build the image
9-;; build-jolt-boot.bb --stamp print what it would be built from
10-;;
11-;; The image is built from :paths alone — there is no dependency resolution
12-;; inside a cross compile — so every source root deps.edn would have resolved
13-;; is named here instead. Two of them are git dependencies, which means the
14-;; jolt cache rather than a checkout; the shas come out of deps.edn so there is
15-;; one place to bump them.
16-(require '[babashka.classpath :as cp])
17-(cp/add-classpath (str (babashka.fs/path (babashka.fs/parent *file*) ".." "scripts")))
18-(require '[frq.paths :as paths]
19- '[babashka.fs :as fs]
20- '[babashka.process :as p]
21- '[clojure.string :as str])
22-
23-(def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
24-(def args *command-line-args*)
25-(def stamp-only? (= "--stamp" (first args)))
26-
27-;; The DotSlash-pinned jolt, not whatever is on PATH: an upstream jolt cannot
28-;; open a TLS connection on Android — it reads the socket address out of
29-;; `struct addrinfo` at glibc's offset, which is Bionic's `ai_canonname` — so a
30-;; build made with one produces an APK that cannot sign in or send a picture.
31-;; Override with JOLT= to use another.
32-;;
33-;; DOTSLASH and JOLT_MANIFEST are set when buck runs this: the manifest and the
34-;; fetcher are inputs to that action, so the machine running it needs neither
35-;; jolt nor DotSlash installed, and a remote worker resolves the same pin
36-;; against the same digest. Without them the shim beside this script answers,
37-;; which is what a person at a terminal gets.
38-(def jolt
39- (or (paths/env "JOLT" nil)
40- (let [dotslash (paths/env "DOTSLASH" nil)
41- manifest (paths/env "JOLT_MANIFEST" nil)]
42- (if (and dotslash manifest)
43- (paths/out dotslash "--" "fetch" manifest)
44- (str (fs/path root "scripts" "jolt"))))))
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-
81-(def module (paths/env "MODULE" "frq.app"))
82-(def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
83-(def host-scheme (str (fs/path chez "ta6le" "bin" "ta6le" "scheme")))
84-(def target-boot (fs/path chez "boot" "tarm64le"))
85-(def xpatch (str (fs/path chez "xc-tarm64le" "s" "xpatch")))
86-
87-(paths/require-paths! "Android Chez artifact"
88- [host-scheme (fs/path target-boot "petite.boot")
89- (fs/path target-boot "scheme.boot")
90- (fs/path target-boot "scheme.h") xpatch]
91- "Build Chez's tarm64le cross target first.")
92-
93-(when-not (or (fs/executable? jolt) (fs/which jolt))
94- (paths/die (str "Jolt executable not found: " jolt)))
95-
96-;; The boot image is a pure function of the Scheme sources, the module name,
97-;; the flat-split flag and Chez's own boot files — all static. Hash them, and
98-;; skip the whole thing when the stamp still matches: a Rust-only APK rebuild
99-;; has no reason to spend fifteen single-threaded seconds recompiling Scheme.
100-;;
101-;; The flag is part of the stamp on purpose. JOLT_NO_FLAT_SPLIT changes the
102-;; shape of what `jolt build` emits, so an app.build/ left by an ordinary build
103-;; is not reusable here; a stamp miss wipes the tree below, which is what the
104-;; unconditional delete used to be defending against.
105-
106-;; The hash itself. Every input is hashed here rather than shelled out to
107-;; sha256sum, so the stamp is one function to read.
108-(defn sha256 [^bytes bs]
109- (->> (.digest (java.security.MessageDigest/getInstance "SHA-256") bs)
110- (map #(format "%02x" (bit-and % 0xff)))
111- (apply str)))
112-
113-(defn file-line [f]
114- (str (sha256 (fs/read-all-bytes (str f))) " " f))
115-
116-(defn stamp []
117- (let [sources (->> [(fs/path root "src") glimmer glimmer-vidya]
118- (mapcat #(fs/glob % "**.{jolt,edn}"))
119- (map str)
120- sort)
121- lines (concat [module "JOLT_NO_FLAT_SPLIT=1"
122- (try (paths/out jolt "--version") (catch Exception _ ""))]
123- (map file-line sources)
124- (map file-line [(fs/path target-boot "petite.boot")
125- (fs/path target-boot "scheme.boot")
126- xpatch]))]
127- (sha256 (.getBytes (str/join "\n" lines) "UTF-8"))))
128-
129-;; buck needs this before the work rather than after: the sources it hashes
130-;; live in the jolt cache and in jolt-native, outside this cell, so nothing
131-;; else makes them reach an action's digest. See the `buck` recipe in the
132-;; justfile.
133-(when stamp-only?
134- (println (stamp))
135- (System/exit 0))
136-
137-(def out-dir (or (first args)
138- (paths/die "usage: build-jolt-boot.bb OUTPUT_DIRECTORY | --stamp")))
139-(def stamp-file (fs/path out-dir "jolt.boot.stamp"))
140-(def want (stamp))
141-
142-(when (and (fs/exists? (fs/path out-dir "jolt.boot"))
143- (fs/exists? (fs/path out-dir "scheme.h"))
144- (fs/exists? stamp-file)
145- (= want (str/trim (slurp (str stamp-file)))))
146- (binding [*out* *err*] (println "jolt boot image up to date"))
147- (System/exit 0))
148-
149-(fs/delete-if-exists stamp-file)
150-(fs/delete-tree (fs/path out-dir "project"))
151-(fs/delete-tree (fs/path out-dir "cross"))
152-(fs/create-dirs (fs/path out-dir "project"))
153-(fs/create-dirs (fs/path out-dir "cross"))
154-(spit (str (fs/path out-dir "project" "deps.edn"))
155- (str "{:paths [\"" (fs/path root "src") "\" \"" glimmer "\" \"" glimmer-vidya "\"]}\n"))
156-
157-(p/shell {:dir (str (fs/path out-dir "project"))
158- :extra-env {"JOLT_NO_FLAT_SPLIT" "1"}}
159- jolt "build" "-m" module "-o" "app")
160-
161-(spit (str (fs/path out-dir "cross" "compile.ss"))
162- (str "(import (chezscheme))\n"
163- "(load \"" xpatch "\")\n"
164- "(optimize-level 2)\n"
165- "(generate-inspector-information #f)\n"
166- "(compile-file \"" (fs/path out-dir "project" "app.build" "flat.ss") "\""
167- " \"" (fs/path out-dir "cross" "flat.so") "\")\n"
168- "(make-boot-file \"" (fs/path out-dir "jolt.boot") "\" '()\n"
169- " \"" (fs/path target-boot "petite.boot") "\"\n"
170- " \"" (fs/path target-boot "scheme.boot") "\"\n"
171- " \"" (fs/path out-dir "cross" "flat.so") "\")\n"))
172-
173-(p/shell {:extra-env {"SCHEMEHEAPDIRS" (str (fs/path chez "ta6le" "boot" "ta6le"))}}
174- host-scheme "--script" (str (fs/path out-dir "cross" "compile.ss")))
175-
176-(fs/copy (fs/path target-boot "scheme.h") (fs/path out-dir "scheme.h")
177- {:replace-existing true})
178-
179-;; Last, so an interrupted build leaves no stamp and the next run redoes it.
180-(spit (str stamp-file) (str want "\n"))
deleted file mode 100755
@@ -1,180 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/../scripts/bb" "$0" "$@"
4-)
5-
6-;; frq's Scheme, cross-compiled to an arm64 Chez boot image.
7-;;
8-;; build-jolt-boot.bb OUTPUT_DIRECTORY build the image
9-;; build-jolt-boot.bb --stamp print what it would be built from
10-;;
11-;; The image is built from :paths alone — there is no dependency resolution
12-;; inside a cross compile — so every source root deps.edn would have resolved
13-;; is named here instead. Two of them are git dependencies, which means the
14-;; jolt cache rather than a checkout; the shas come out of deps.edn so there is
15-;; one place to bump them.
16-(require '[babashka.classpath :as cp])
17-(cp/add-classpath (str (babashka.fs/path (babashka.fs/parent *file*) ".." "scripts")))
18-(require '[frq.paths :as paths]
19- '[babashka.fs :as fs]
20- '[babashka.process :as p]
21- '[clojure.string :as str])
22-
23-(def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
24-(def args *command-line-args*)
25-(def stamp-only? (= "--stamp" (first args)))
26-
27-;; The DotSlash-pinned jolt, not whatever is on PATH: an upstream jolt cannot
28-;; open a TLS connection on Android — it reads the socket address out of
29-;; `struct addrinfo` at glibc's offset, which is Bionic's `ai_canonname` — so a
30-;; build made with one produces an APK that cannot sign in or send a picture.
31-;; Override with JOLT= to use another.
32-;;
33-;; DOTSLASH and JOLT_MANIFEST are set when buck runs this: the manifest and the
34-;; fetcher are inputs to that action, so the machine running it needs neither
35-;; jolt nor DotSlash installed, and a remote worker resolves the same pin
36-;; against the same digest. Without them the shim beside this script answers,
37-;; which is what a person at a terminal gets.
38-(def jolt
39- (or (paths/env "JOLT" nil)
40- (let [dotslash (paths/env "DOTSLASH" nil)
41- manifest (paths/env "JOLT_MANIFEST" nil)]
42- (if (and dotslash manifest)
43- (paths/out dotslash "--" "fetch" manifest)
44- (str (fs/path root "scripts" "jolt"))))))
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-
81-(def module (paths/env "MODULE" "frq.app"))
82-(def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
83-(def host-scheme (str (fs/path chez "ta6le" "bin" "ta6le" "scheme")))
84-(def target-boot (fs/path chez "boot" "tarm64le"))
85-(def xpatch (str (fs/path chez "xc-tarm64le" "s" "xpatch")))
86-
87-(paths/require-paths! "Android Chez artifact"
88- [host-scheme (fs/path target-boot "petite.boot")
89- (fs/path target-boot "scheme.boot")
90- (fs/path target-boot "scheme.h") xpatch]
91- "Build Chez's tarm64le cross target first.")
92-
93-(when-not (or (fs/executable? jolt) (fs/which jolt))
94- (paths/die (str "Jolt executable not found: " jolt)))
95-
96-;; The boot image is a pure function of the Scheme sources, the module name,
97-;; the flat-split flag and Chez's own boot files — all static. Hash them, and
98-;; skip the whole thing when the stamp still matches: a Rust-only APK rebuild
99-;; has no reason to spend fifteen single-threaded seconds recompiling Scheme.
100-;;
101-;; The flag is part of the stamp on purpose. JOLT_NO_FLAT_SPLIT changes the
102-;; shape of what `jolt build` emits, so an app.build/ left by an ordinary build
103-;; is not reusable here; a stamp miss wipes the tree below, which is what the
104-;; unconditional delete used to be defending against.
105-
106-;; The hash itself. Every input is hashed here rather than shelled out to
107-;; sha256sum, so the stamp is one function to read.
108-(defn sha256 [^bytes bs]
109- (->> (.digest (java.security.MessageDigest/getInstance "SHA-256") bs)
110- (map #(format "%02x" (bit-and % 0xff)))
111- (apply str)))
112-
113-(defn file-line [f]
114- (str (sha256 (fs/read-all-bytes (str f))) " " f))
115-
116-(defn stamp []
117- (let [sources (->> [(fs/path root "src") glimmer glimmer-vidya]
118- (mapcat #(fs/glob % "**.{jolt,edn}"))
119- (map str)
120- sort)
121- lines (concat [module "JOLT_NO_FLAT_SPLIT=1"
122- (try (paths/out jolt "--version") (catch Exception _ ""))]
123- (map file-line sources)
124- (map file-line [(fs/path target-boot "petite.boot")
125- (fs/path target-boot "scheme.boot")
126- xpatch]))]
127- (sha256 (.getBytes (str/join "\n" lines) "UTF-8"))))
128-
129-;; buck needs this before the work rather than after: the sources it hashes
130-;; live in the jolt cache and in jolt-native, outside this cell, so nothing
131-;; else makes them reach an action's digest. See the `buck` recipe in the
132-;; justfile.
133-(when stamp-only?
134- (println (stamp))
135- (System/exit 0))
136-
137-(def out-dir (or (first args)
138- (paths/die "usage: build-jolt-boot.bb OUTPUT_DIRECTORY | --stamp")))
139-(def stamp-file (fs/path out-dir "jolt.boot.stamp"))
140-(def want (stamp))
141-
142-(when (and (fs/exists? (fs/path out-dir "jolt.boot"))
143- (fs/exists? (fs/path out-dir "scheme.h"))
144- (fs/exists? stamp-file)
145- (= want (str/trim (slurp (str stamp-file)))))
146- (binding [*out* *err*] (println "jolt boot image up to date"))
147- (System/exit 0))
148-
149-(fs/delete-if-exists stamp-file)
150-(fs/delete-tree (fs/path out-dir "project"))
151-(fs/delete-tree (fs/path out-dir "cross"))
152-(fs/create-dirs (fs/path out-dir "project"))
153-(fs/create-dirs (fs/path out-dir "cross"))
154-(spit (str (fs/path out-dir "project" "deps.edn"))
155- (str "{:paths [\"" (fs/path root "src") "\" \"" glimmer "\" \"" glimmer-vidya "\"]}\n"))
156-
157-(p/shell {:dir (str (fs/path out-dir "project"))
158- :extra-env {"JOLT_NO_FLAT_SPLIT" "1"}}
159- jolt "build" "-m" module "-o" "app")
160-
161-(spit (str (fs/path out-dir "cross" "compile.ss"))
162- (str "(import (chezscheme))\n"
163- "(load \"" xpatch "\")\n"
164- "(optimize-level 2)\n"
165- "(generate-inspector-information #f)\n"
166- "(compile-file \"" (fs/path out-dir "project" "app.build" "flat.ss") "\""
167- " \"" (fs/path out-dir "cross" "flat.so") "\")\n"
168- "(make-boot-file \"" (fs/path out-dir "jolt.boot") "\" '()\n"
169- " \"" (fs/path target-boot "petite.boot") "\"\n"
170- " \"" (fs/path target-boot "scheme.boot") "\"\n"
171- " \"" (fs/path out-dir "cross" "flat.so") "\")\n"))
172-
173-(p/shell {:extra-env {"SCHEMEHEAPDIRS" (str (fs/path chez "ta6le" "boot" "ta6le"))}}
174- host-scheme "--script" (str (fs/path out-dir "cross" "compile.ss")))
175-
176-(fs/copy (fs/path target-boot "scheme.h") (fs/path out-dir "scheme.h")
177- {:replace-existing true})
178-
179-;; Last, so an interrupted build leaves no stamp and the next run redoes it.
180-(spit (str stamp-file) (str want "\n"))
modified flake.nix +2 -2
@@ -274,8 +274,8 @@
274274 # `legacyPackages` everything above uses. Confined to the Android
275275 # outputs: `nix build` of frq itself never evaluates it.
276276 #
277- # The NDK here is r29, which is the version scripts/android-ndk.dotslash
278- # pins and the one the pinned libvidya was built with.
277+ # The NDK here is r29, which is the one the pinned libvidya was
278+ # built with.
279279 androidPkgs = import nixpkgs {
280280 inherit (pkgs.stdenv.hostPlatform) system;
281281 config = {
@@ -274,8 +274,8 @@
274 # `legacyPackages` everything above uses. Confined to the Android274 # `legacyPackages` everything above uses. Confined to the Android
275 # outputs: `nix build` of frq itself never evaluates it.275 # outputs: `nix build` of frq itself never evaluates it.
276 #276 #
277- # The NDK here is r29, which is the version scripts/android-ndk.dotslash277+ # The NDK here is r29, which is the one the pinned libvidya was
278- # pins and the one the pinned libvidya was built with.278+ # built with.
279 androidPkgs = import nixpkgs {279 androidPkgs = import nixpkgs {
280 inherit (pkgs.stdenv.hostPlatform) system;280 inherit (pkgs.stdenv.hostPlatform) system;
281 config = {281 config = {
modified justfile +3 -12
@@ -1,7 +1,6 @@
11 # Every recipe here is one line, because the work is in scripts/ — babashka
22 # scripts, run through the pin in scripts/bb. A recipe body is a shell script
3-# nobody can run on its own; a script in scripts/ is a script, and buck runs
4-# two of them as actions.
3+# nobody can run on its own; a script in scripts/ is a script.
54
65 set shell := ["bash", "-euo", "pipefail", "-c"]
76
@@ -12,22 +11,14 @@ default:
1211 lib:
1312 scripts/lib.bb
1413
15-# buck2, with the machine's paths written where the BUCK files can read them.
16-buck *args:
17- scripts/buck.bb {{args}}
18-
19-# The APK. `just apk install` puts it on the device.
14+# The APK, out of the flake. `just apk install` puts it on the device.
2015 apk action="build":
2116 scripts/apk.bb {{action}}
2217
23-# Every jolt-native pin — manifests, deps.edn, the buck table — at a release.
18+# Every jolt-native pin — the manifests, deps.edn, nix/android.nix — at a release.
2419 bump tag="":
2520 scripts/bump-jolt-native.bb {{tag}}
2621
27-# The archives scripts/*.dotslash pins, as the table buck reads.
28-sync-dist:
29- scripts/dotslash-to-buck
30-
3122 # The app: this tree's source on the flake's everything-else, in the dev shell.
3223 run *args:
3324 scripts/run.bb {{args}}
@@ -1,7 +1,6 @@
1 # Every recipe here is one line, because the work is in scripts/ — babashka1 # Every recipe here is one line, because the work is in scripts/ — babashka
2 # scripts, run through the pin in scripts/bb. A recipe body is a shell script2 # scripts, run through the pin in scripts/bb. A recipe body is a shell script
3-# nobody can run on its own; a script in scripts/ is a script, and buck runs3+# nobody can run on its own; a script in scripts/ is a script.
4-# two of them as actions.
5 4
6 set shell := ["bash", "-euo", "pipefail", "-c"]5 set shell := ["bash", "-euo", "pipefail", "-c"]
7 6
@@ -12,22 +11,14 @@ default:
12 lib:11 lib:
13 scripts/lib.bb12 scripts/lib.bb
14 13
15-# buck2, with the machine's paths written where the BUCK files can read them.14+# The APK, out of the flake. `just apk install` puts it on the device.
16-buck *args:
17- scripts/buck.bb {{args}}
18-
19-# The APK. `just apk install` puts it on the device.
20 apk action="build":15 apk action="build":
21 scripts/apk.bb {{action}}16 scripts/apk.bb {{action}}
22 17
23-# Every jolt-native pin — manifests, deps.edn, the buck table — at a release.18+# Every jolt-native pin — the manifests, deps.edn, nix/android.nix — at a release.
24 bump tag="":19 bump tag="":
25 scripts/bump-jolt-native.bb {{tag}}20 scripts/bump-jolt-native.bb {{tag}}
26 21
27-# The archives scripts/*.dotslash pins, as the table buck reads.
28-sync-dist:
29- scripts/dotslash-to-buck
30-
31 # The app: this tree's source on the flake's everything-else, in the dev shell.22 # The app: this tree's source on the flake's everything-else, in the dev shell.
32 run *args:23 run *args:
33 scripts/run.bb {{args}}24 scripts/run.bb {{args}}
modified nix/android.nix +24 -18
@@ -1,14 +1,16 @@
1-# The APK, as derivations rather than as a buck2 graph.
1+# The APK, as derivations.
22 #
3-# android/BUCK builds the same things, and does it better for a person at
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
7-# machine with no Android SDK, no NDK, no hand-built Chez cross target and no
8-# ~/.cache at all:
3+# The only APK build there is: this replaced a buck2 graph and the script
4+# before it, both of which named an Android SDK, an NDK, a hand-built Chez
5+# cross target and an OpenSSL by absolute path and stopped when one was
6+# missing. Every one of those is built or fetched here instead, so this works
7+# from nothing on a machine with none of them and no ~/.cache at all:
98 #
109 # nix build .#apk
1110 #
11+# `just apk` is the same build with the store path handed to adb afterwards;
12+# see scripts/apk.bb.
13+#
1214 # On a machine with a remote builder configured, prefer
1315 #
1416 # nix build .#apk --store ssh-ng://eu.nixbuild.net --eval-store auto
@@ -20,9 +22,9 @@
2022 # whole graph stays there, only .drv files go up, and the builder fetches
2123 # Google's zip over its own link.
2224 #
23-# Every path .buckconfig.local answers for is answered here by the store
24-# instead. The steps are in the same order and do the same work; where a
25-# genrule read `read_root_config`, a derivation takes an argument.
25+# The steps are the ones the graph before it ran, in the same order; where a
26+# genrule read a path out of `read_root_config`, a derivation takes an
27+# argument.
2628 { pkgs, lib, self, chez-src, jolt-native, glimmer, joltAndroid, androidSdk, ndk }:
2729
2830 let
@@ -45,9 +47,12 @@ let
4547 ndkBin = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/bin";
4648 cc = "${ndkBin}/aarch64-linux-android${apiLevel}-clang";
4749
48- # What comes out of jolt-native's releases, by the digests scripts/*.dotslash
49- # pin. Same bytes buck fetches; DotSlash's `digest` is over the archive,
50- # which is what fetchurl hashes too.
50+ # What comes out of jolt-native's releases. These two pins are the Android
51+ # half of what `just bump` moves — the desktop half stays in
52+ # scripts/*.dotslash, and the tag written here is the one written there, so
53+ # a phone and a laptop run the same release. Do not edit them by hand:
54+ # bump-jolt-native.bb fetches each archive, weighs it, and writes both the
55+ # url and the digest below.
5156 #
5257 # One archive, two libraries: libvidya (the retained-tree UI) and libjoltmoq
5358 # (the AV media plane). They are built together and only make sense together
@@ -170,10 +175,10 @@ let
170175 xpatch = "${chezAndroid}/xc-tarm64le/s/xpatch";
171176
172177 # --- the Jolt half --------------------------------------------------------
173- # frq's Scheme, cross-compiled to an arm64 boot image. android/build-jolt-boot.bb
174- # does this by hand-writing a deps.edn of :paths and then driving Chez; so
175- # does this, for the same reason — there is no dependency resolution inside a
176- # cross compile, so every source root deps.edn would have resolved is named.
178+ # frq's Scheme, cross-compiled to an arm64 boot image. The deps.edn below is
179+ # written out by hand rather than resolved: there is no dependency resolution
180+ # inside a cross compile, so every source root deps.edn would have resolved is
181+ # named as a :path instead.
177182 #
178183 # The jolt that runs it is the fork, not upstream and not the one the desktop
179184 # package builds: upstream reads the socket address out of `struct addrinfo`
@@ -374,7 +379,8 @@ let
374379
375380 # Aligned and signed with a debug key. The key is generated here rather than
376381 # read from ~/.android, which is the one place this build is deliberately
377- # not the buck one: a keystore outside the store would make the output
382+ # not what the builds before it did: a keystore outside the store would make
383+ # the output
378384 # depend on the machine, and a release key has no business in the store at
379385 # all. So this output is installable and not reproducible — keytool stamps
380386 # the certificate with the time — and anything meant for a store should be
@@ -1,14 +1,16 @@
1-# The APK, as derivations rather than as a buck2 graph.1+# The APK, as derivations.
2 #2 #
3-# android/BUCK builds the same things, and does it better for a person at3+# The only APK build there is: this replaced a buck2 graph and the script
4-# a terminal: it is incremental, and it fetches jolt-native's release by digest4+# before it, both of which named an Android SDK, an NDK, a hand-built Chez
5-# rather than rebuilding the world. Nothing here replaces that. What this adds5+# cross target and an OpenSSL by absolute path and stopped when one was
6-# is the other build — from nothing, on a6+# missing. Every one of those is built or fetched here instead, so this works
7-# machine with no Android SDK, no NDK, no hand-built Chez cross target and no7+# from nothing on a machine with none of them and no ~/.cache at all:
8-# ~/.cache at all:
9 #8 #
10 # nix build .#apk9 # nix build .#apk
11 #10 #
11+# `just apk` is the same build with the store path handed to adb afterwards;
12+# see scripts/apk.bb.
13+#
12 # On a machine with a remote builder configured, prefer14 # On a machine with a remote builder configured, prefer
13 #15 #
14 # nix build .#apk --store ssh-ng://eu.nixbuild.net --eval-store auto16 # nix build .#apk --store ssh-ng://eu.nixbuild.net --eval-store auto
@@ -20,9 +22,9 @@
20 # whole graph stays there, only .drv files go up, and the builder fetches22 # whole graph stays there, only .drv files go up, and the builder fetches
21 # Google's zip over its own link.23 # Google's zip over its own link.
22 #24 #
23-# Every path .buckconfig.local answers for is answered here by the store25+# The steps are the ones the graph before it ran, in the same order; where a
24-# instead. The steps are in the same order and do the same work; where a26+# genrule read a path out of `read_root_config`, a derivation takes an
25-# genrule read `read_root_config`, a derivation takes an argument.27+# argument.
26 { pkgs, lib, self, chez-src, jolt-native, glimmer, joltAndroid, androidSdk, ndk }:28 { pkgs, lib, self, chez-src, jolt-native, glimmer, joltAndroid, androidSdk, ndk }:
27 29
28 let30 let
@@ -45,9 +47,12 @@ let
45 ndkBin = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/bin";47 ndkBin = "${ndkRoot}/toolchains/llvm/prebuilt/linux-x86_64/bin";
46 cc = "${ndkBin}/aarch64-linux-android${apiLevel}-clang";48 cc = "${ndkBin}/aarch64-linux-android${apiLevel}-clang";
47 49
48- # What comes out of jolt-native's releases, by the digests scripts/*.dotslash50+ # What comes out of jolt-native's releases. These two pins are the Android
49- # pin. Same bytes buck fetches; DotSlash's `digest` is over the archive,51+ # half of what `just bump` moves — the desktop half stays in
50- # which is what fetchurl hashes too.52+ # scripts/*.dotslash, and the tag written here is the one written there, so
53+ # a phone and a laptop run the same release. Do not edit them by hand:
54+ # bump-jolt-native.bb fetches each archive, weighs it, and writes both the
55+ # url and the digest below.
51 #56 #
52 # One archive, two libraries: libvidya (the retained-tree UI) and libjoltmoq57 # One archive, two libraries: libvidya (the retained-tree UI) and libjoltmoq
53 # (the AV media plane). They are built together and only make sense together58 # (the AV media plane). They are built together and only make sense together
@@ -170,10 +175,10 @@ let
170 xpatch = "${chezAndroid}/xc-tarm64le/s/xpatch";175 xpatch = "${chezAndroid}/xc-tarm64le/s/xpatch";
171 176
172 # --- the Jolt half --------------------------------------------------------177 # --- the Jolt half --------------------------------------------------------
173- # frq's Scheme, cross-compiled to an arm64 boot image. android/build-jolt-boot.bb178+ # frq's Scheme, cross-compiled to an arm64 boot image. The deps.edn below is
174- # does this by hand-writing a deps.edn of :paths and then driving Chez; so179+ # written out by hand rather than resolved: there is no dependency resolution
175- # does this, for the same reason — there is no dependency resolution inside a180+ # inside a cross compile, so every source root deps.edn would have resolved is
176- # cross compile, so every source root deps.edn would have resolved is named.181+ # named as a :path instead.
177 #182 #
178 # The jolt that runs it is the fork, not upstream and not the one the desktop183 # The jolt that runs it is the fork, not upstream and not the one the desktop
179 # package builds: upstream reads the socket address out of `struct addrinfo`184 # package builds: upstream reads the socket address out of `struct addrinfo`
@@ -374,7 +379,8 @@ let
374 379
375 # Aligned and signed with a debug key. The key is generated here rather than380 # Aligned and signed with a debug key. The key is generated here rather than
376 # read from ~/.android, which is the one place this build is deliberately381 # read from ~/.android, which is the one place this build is deliberately
377- # not the buck one: a keystore outside the store would make the output382+ # not what the builds before it did: a keystore outside the store would make
383+ # the output
378 # depend on the machine, and a release key has no business in the store at384 # depend on the machine, and a release key has no business in the store at
379 # all. So this output is installable and not reproducible — keytool stamps385 # all. So this output is installable and not reproducible — keytool stamps
380 # the certificate with the time — and anything meant for a store should be386 # the certificate with the time — and anything meant for a store should be
deleted platforms/BUCK +0 -33
deleted file mode 100644
@@ -1,33 +0,0 @@
1-load("@prelude//platforms:defs.bzl", "host_configuration")
2-load(":defs.bzl", "execution_platform")
3-
4-# Where every action runs: locally, against the BuildBuddy cache. The same
5-# arrangement jolt-native uses, and registered the same two ways — `[build]
6-# execution_platforms` in .buckconfig and `[parser] target_platform_detector_spec`
7-# there too, since setting only the first leaves toolchain-owned actions on the
8-# prelude's uncached default.
9-execution_platform(
10- name = "cache",
11- cpu_configuration = host_configuration.cpu,
12- os_configuration = host_configuration.os,
13- use_windows_path_separators = host_info().os.is_windows,
14- visibility = ["PUBLIC"],
15-)
16-
17-# The same platform, allowed to dispatch. Most of this graph cannot use it: the
18-# packaging steps name an Android SDK, a Chez cross build and an OpenSSL by
19-# absolute path, and a worker has none of them. The boot image compile is the
20-# one that could, which is why jolt reaches it through a manifest rather than a
21-# path — see android/BUCK.
22-execution_platform(
23- name = "remote",
24- cpu_configuration = host_configuration.cpu,
25- os_configuration = host_configuration.os,
26- remote_enabled = True,
27- remote_execution_properties = {
28- "OSFamily": "Linux",
29- "container-image": "docker://gcr.io/flame-public/rbe-ubuntu24-04:latest",
30- },
31- use_windows_path_separators = host_info().os.is_windows,
32- visibility = ["PUBLIC"],
33-)
deleted file mode 100644
@@ -1,33 +0,0 @@
1-load("@prelude//platforms:defs.bzl", "host_configuration")
2-load(":defs.bzl", "execution_platform")
3-
4-# Where every action runs: locally, against the BuildBuddy cache. The same
5-# arrangement jolt-native uses, and registered the same two ways — `[build]
6-# execution_platforms` in .buckconfig and `[parser] target_platform_detector_spec`
7-# there too, since setting only the first leaves toolchain-owned actions on the
8-# prelude's uncached default.
9-execution_platform(
10- name = "cache",
11- cpu_configuration = host_configuration.cpu,
12- os_configuration = host_configuration.os,
13- use_windows_path_separators = host_info().os.is_windows,
14- visibility = ["PUBLIC"],
15-)
16-
17-# The same platform, allowed to dispatch. Most of this graph cannot use it: the
18-# packaging steps name an Android SDK, a Chez cross build and an OpenSSL by
19-# absolute path, and a worker has none of them. The boot image compile is the
20-# one that could, which is why jolt reaches it through a manifest rather than a
21-# path — see android/BUCK.
22-execution_platform(
23- name = "remote",
24- cpu_configuration = host_configuration.cpu,
25- os_configuration = host_configuration.os,
26- remote_enabled = True,
27- remote_execution_properties = {
28- "OSFamily": "Linux",
29- "container-image": "docker://gcr.io/flame-public/rbe-ubuntu24-04:latest",
30- },
31- use_windows_path_separators = host_info().os.is_windows,
32- visibility = ["PUBLIC"],
33-)
deleted platforms/defs.bzl +0 -55
deleted file mode 100644
@@ -1,55 +0,0 @@
1-# The stock prelude//platforms:default with its cache switches flipped on.
2-#
3-# The prelude's own `execution_platform` rule is static Starlark — there is no
4-# buckconfig key that turns caching on for it — so the rule is copied here and
5-# its CommandExecutorConfig changed. Everything else mirrors the original
6-# exactly, so this platform stays configuration-identical to the default.
7-#
8-# Whether actions may run on a worker is an attribute now rather than a
9-# constant. It was false because it had to be: the toolchain named absolute
10-# paths inside this checkout, which no worker would have. Both compilers are
11-# dependencies now, so there is something to ship.
12-load("@prelude//cfg/exec_platform:marker.bzl", "get_exec_platform_marker")
13-
14-def _execution_platform_impl(ctx: AnalysisContext) -> list[Provider]:
15- constraints = dict()
16- constraints.update(ctx.attrs.cpu_configuration[ConfigurationInfo].constraints)
17- constraints.update(ctx.attrs.os_configuration[ConfigurationInfo].constraints)
18- cfg = ConfigurationInfo(constraints = constraints, values = {})
19-
20- name = ctx.label.raw_target()
21- platform = ExecutionPlatformInfo(
22- label = name,
23- configuration = cfg,
24- executor_config = CommandExecutorConfig(
25- local_enabled = ctx.attrs.local_enabled,
26- remote_enabled = ctx.attrs.remote_enabled,
27- remote_cache_enabled = True,
28- allow_cache_uploads = True,
29- remote_execution_properties = ctx.attrs.remote_execution_properties,
30- remote_execution_use_case = "buck2-default",
31- use_windows_path_separators = ctx.attrs.use_windows_path_separators,
32- ),
33- )
34-
35- return [
36- DefaultInfo(),
37- platform,
38- PlatformInfo(label = str(name), configuration = cfg),
39- ExecutionPlatformRegistrationInfo(
40- platforms = [platform],
41- exec_marker_constraint = get_exec_platform_marker(),
42- ),
43- ]
44-
45-execution_platform = rule(
46- impl = _execution_platform_impl,
47- attrs = {
48- "cpu_configuration": attrs.dep(providers = [ConfigurationInfo]),
49- "local_enabled": attrs.bool(default = True),
50- "remote_enabled": attrs.bool(default = False),
51- "remote_execution_properties": attrs.dict(attrs.string(), attrs.string(), default = {}),
52- "os_configuration": attrs.dep(providers = [ConfigurationInfo]),
53- "use_windows_path_separators": attrs.bool(),
54- },
55-)
deleted file mode 100644
@@ -1,55 +0,0 @@
1-# The stock prelude//platforms:default with its cache switches flipped on.
2-#
3-# The prelude's own `execution_platform` rule is static Starlark — there is no
4-# buckconfig key that turns caching on for it — so the rule is copied here and
5-# its CommandExecutorConfig changed. Everything else mirrors the original
6-# exactly, so this platform stays configuration-identical to the default.
7-#
8-# Whether actions may run on a worker is an attribute now rather than a
9-# constant. It was false because it had to be: the toolchain named absolute
10-# paths inside this checkout, which no worker would have. Both compilers are
11-# dependencies now, so there is something to ship.
12-load("@prelude//cfg/exec_platform:marker.bzl", "get_exec_platform_marker")
13-
14-def _execution_platform_impl(ctx: AnalysisContext) -> list[Provider]:
15- constraints = dict()
16- constraints.update(ctx.attrs.cpu_configuration[ConfigurationInfo].constraints)
17- constraints.update(ctx.attrs.os_configuration[ConfigurationInfo].constraints)
18- cfg = ConfigurationInfo(constraints = constraints, values = {})
19-
20- name = ctx.label.raw_target()
21- platform = ExecutionPlatformInfo(
22- label = name,
23- configuration = cfg,
24- executor_config = CommandExecutorConfig(
25- local_enabled = ctx.attrs.local_enabled,
26- remote_enabled = ctx.attrs.remote_enabled,
27- remote_cache_enabled = True,
28- allow_cache_uploads = True,
29- remote_execution_properties = ctx.attrs.remote_execution_properties,
30- remote_execution_use_case = "buck2-default",
31- use_windows_path_separators = ctx.attrs.use_windows_path_separators,
32- ),
33- )
34-
35- return [
36- DefaultInfo(),
37- platform,
38- PlatformInfo(label = str(name), configuration = cfg),
39- ExecutionPlatformRegistrationInfo(
40- platforms = [platform],
41- exec_marker_constraint = get_exec_platform_marker(),
42- ),
43- ]
44-
45-execution_platform = rule(
46- impl = _execution_platform_impl,
47- attrs = {
48- "cpu_configuration": attrs.dep(providers = [ConfigurationInfo]),
49- "local_enabled": attrs.bool(default = True),
50- "remote_enabled": attrs.bool(default = False),
51- "remote_execution_properties": attrs.dict(attrs.string(), attrs.string(), default = {}),
52- "os_configuration": attrs.dep(providers = [ConfigurationInfo]),
53- "use_windows_path_separators": attrs.bool(),
54- },
55-)
deleted scripts/BUCK +0 -33
deleted file mode 100644
@@ -1,33 +0,0 @@
1-# The pins, as artifacts.
2-#
3-# A manifest a build action resolves has to be an input to that action, so that
4-# bumping the version it names invalidates what was built with the old one.
5-# android/BUCK hands this one to the boot image compile along with a DotSlash
6-# to read it with.
7-export_file(
8- name = "jolt",
9- mode = "reference",
10- visibility = ["PUBLIC"],
11-)
12-
13-# The NDK lookup, and the driver that uses it. Inputs, so what links the glue
14-# is named by this repo rather than found next door: the APK's own link step
15-# needs a clang and an llvm-objcopy, and jolt-native is no longer required to
16-# be on the machine for that.
17-export_file(
18- name = "android-ndk-bin",
19- mode = "reference",
20- visibility = ["PUBLIC"],
21-)
22-
23-export_file(
24- name = "android-cc",
25- mode = "reference",
26- visibility = ["PUBLIC"],
27-)
28-
29-export_file(
30- name = "android-ndk.dotslash",
31- mode = "reference",
32- visibility = ["PUBLIC"],
33-)
deleted file mode 100644
@@ -1,33 +0,0 @@
1-# The pins, as artifacts.
2-#
3-# A manifest a build action resolves has to be an input to that action, so that
4-# bumping the version it names invalidates what was built with the old one.
5-# android/BUCK hands this one to the boot image compile along with a DotSlash
6-# to read it with.
7-export_file(
8- name = "jolt",
9- mode = "reference",
10- visibility = ["PUBLIC"],
11-)
12-
13-# The NDK lookup, and the driver that uses it. Inputs, so what links the glue
14-# is named by this repo rather than found next door: the APK's own link step
15-# needs a clang and an llvm-objcopy, and jolt-native is no longer required to
16-# be on the machine for that.
17-export_file(
18- name = "android-ndk-bin",
19- mode = "reference",
20- visibility = ["PUBLIC"],
21-)
22-
23-export_file(
24- name = "android-cc",
25- mode = "reference",
26- visibility = ["PUBLIC"],
27-)
28-
29-export_file(
30- name = "android-ndk.dotslash",
31- mode = "reference",
32- visibility = ["PUBLIC"],
33-)
deleted scripts/android-cc +0 -32
deleted file mode 100755
@@ -1,32 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; The NDK's clang, as the linker rustc runs for an Android target.
7-;;
8-;; The buck-side twin of this is toolchains/ndk.sh, which the C toolchain gets
9-;; as a dependency; both resolve the same archive, pinned in one place
10-;; android-ndk.dotslash beside this script. rustc reaches it through a shim
11-;; instead because -Clinker takes a plain string: rustc_flags cannot carry an
12-;; artifact path, so the linker has to be something with a stable name. The cfg
13-;; in toolchains/BUCK is what keeps two NDKs from sharing a cache entry.
14-;;
15-;; ANDROID_NDK_HOME wins if it is set, so a machine that already has an NDK
16-;; skips the download.
17-(require '[babashka.fs :as fs]
18- '[babashka.process :as p]
19- '[clojure.string :as str])
20-
21-(def here (fs/parent (fs/canonicalize *file*)))
22-(def api (or (not-empty (str (System/getenv "JOLT_ANDROID_API"))) "28"))
23-(def target (or (not-empty (str (System/getenv "JOLT_ANDROID_TARGET"))) "aarch64-linux-android"))
24-
25-;; android-ndk-bin is where the lookup lives, because an APK build wants the
26-;; other binaries out of the same archive.
27-(def bin (str/trim (:out (p/shell {:out :string} (str (fs/path here "android-ndk-bin"))))))
28-
29-(System/exit
30- (:exit @(apply p/process {:inherit true}
31- (str (fs/path bin "clang")) (str "--target=" target api)
32- *command-line-args*)))
deleted file mode 100755
@@ -1,32 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; The NDK's clang, as the linker rustc runs for an Android target.
7-;;
8-;; The buck-side twin of this is toolchains/ndk.sh, which the C toolchain gets
9-;; as a dependency; both resolve the same archive, pinned in one place
10-;; android-ndk.dotslash beside this script. rustc reaches it through a shim
11-;; instead because -Clinker takes a plain string: rustc_flags cannot carry an
12-;; artifact path, so the linker has to be something with a stable name. The cfg
13-;; in toolchains/BUCK is what keeps two NDKs from sharing a cache entry.
14-;;
15-;; ANDROID_NDK_HOME wins if it is set, so a machine that already has an NDK
16-;; skips the download.
17-(require '[babashka.fs :as fs]
18- '[babashka.process :as p]
19- '[clojure.string :as str])
20-
21-(def here (fs/parent (fs/canonicalize *file*)))
22-(def api (or (not-empty (str (System/getenv "JOLT_ANDROID_API"))) "28"))
23-(def target (or (not-empty (str (System/getenv "JOLT_ANDROID_TARGET"))) "aarch64-linux-android"))
24-
25-;; android-ndk-bin is where the lookup lives, because an APK build wants the
26-;; other binaries out of the same archive.
27-(def bin (str/trim (:out (p/shell {:out :string} (str (fs/path here "android-ndk-bin"))))))
28-
29-(System/exit
30- (:exit @(apply p/process {:inherit true}
31- (str (fs/path bin "clang")) (str "--target=" target api)
32- *command-line-args*)))
deleted scripts/android-glue.dotslash +0 -66
deleted file mode 100644
@@ -1,66 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The NativeActivity glue and the ABI's headers, from jolt-native's v0.1.3
4-// release.
5-//
6-// jolt_main.c is what libvidya's android_main dlopens: it boots Chez over the
7-// Jolt image this repo builds and registers every Vidya symbol by hand, since
8-// the loader will not answer for a symbol living in a different shared object.
9-// The headers beside it are what it includes. Both are jolt-native's; only the
10-// boot image is frq's.
11-//
12-// Source, not a binary, and pinned for the same reason the library is: an APK
13-// should not need a second checkout to build.
14-{
15- "name": "android-glue",
16- "platforms": {
17- "linux-x86_64": {
18- "size": 10652,
19- "hash": "sha256",
20- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
21- "format": "tar.gz",
22- "path": "jolt-native-android-glue/android/jolt_main.c",
23- "providers": [
24- {
25- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
26- }
27- ]
28- },
29- "linux-aarch64": {
30- "size": 10652,
31- "hash": "sha256",
32- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
33- "format": "tar.gz",
34- "path": "jolt-native-android-glue/android/jolt_main.c",
35- "providers": [
36- {
37- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
38- }
39- ]
40- },
41- "macos-x86_64": {
42- "size": 10652,
43- "hash": "sha256",
44- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
45- "format": "tar.gz",
46- "path": "jolt-native-android-glue/android/jolt_main.c",
47- "providers": [
48- {
49- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
50- }
51- ]
52- },
53- "macos-aarch64": {
54- "size": 10652,
55- "hash": "sha256",
56- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
57- "format": "tar.gz",
58- "path": "jolt-native-android-glue/android/jolt_main.c",
59- "providers": [
60- {
61- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
62- }
63- ]
64- }
65- }
66-}
deleted file mode 100644
@@ -1,66 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The NativeActivity glue and the ABI's headers, from jolt-native's v0.1.3
4-// release.
5-//
6-// jolt_main.c is what libvidya's android_main dlopens: it boots Chez over the
7-// Jolt image this repo builds and registers every Vidya symbol by hand, since
8-// the loader will not answer for a symbol living in a different shared object.
9-// The headers beside it are what it includes. Both are jolt-native's; only the
10-// boot image is frq's.
11-//
12-// Source, not a binary, and pinned for the same reason the library is: an APK
13-// should not need a second checkout to build.
14-{
15- "name": "android-glue",
16- "platforms": {
17- "linux-x86_64": {
18- "size": 10652,
19- "hash": "sha256",
20- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
21- "format": "tar.gz",
22- "path": "jolt-native-android-glue/android/jolt_main.c",
23- "providers": [
24- {
25- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
26- }
27- ]
28- },
29- "linux-aarch64": {
30- "size": 10652,
31- "hash": "sha256",
32- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
33- "format": "tar.gz",
34- "path": "jolt-native-android-glue/android/jolt_main.c",
35- "providers": [
36- {
37- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
38- }
39- ]
40- },
41- "macos-x86_64": {
42- "size": 10652,
43- "hash": "sha256",
44- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
45- "format": "tar.gz",
46- "path": "jolt-native-android-glue/android/jolt_main.c",
47- "providers": [
48- {
49- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
50- }
51- ]
52- },
53- "macos-aarch64": {
54- "size": 10652,
55- "hash": "sha256",
56- "digest": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
57- "format": "tar.gz",
58- "path": "jolt-native-android-glue/android/jolt_main.c",
59- "providers": [
60- {
61- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz"
62- }
63- ]
64- }
65- }
66-}
deleted scripts/android-ndk-bin +0 -32
deleted file mode 100755
@@ -1,32 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; Print the directory holding the NDK's clang and LLVM binutils.
7-;;
8-;; android-cc needs one of those binaries and an APK build needs others
9-;; llvm-objcopy, for the boot image blob so the lookup is here rather than
10-;; duplicated at each caller. ANDROID_NDK_HOME wins if it is set; otherwise the
11-;; pin in android-ndk.dotslash beside this script answers, downloading once.
12-(require '[babashka.fs :as fs]
13- '[babashka.process :as p]
14- '[clojure.string :as str])
15-
16-(def here (fs/parent (fs/canonicalize *file*)))
17-(def ndk (or (not-empty (str (System/getenv "ANDROID_NDK_HOME")))
18- (not-empty (str (System/getenv "ANDROID_NDK_ROOT")))))
19-
20-(if ndk
21- (if-let [bin (->> ["linux-x86_64" "darwin-x86_64"]
22- (map #(fs/path ndk "toolchains" "llvm" "prebuilt" % "bin"))
23- (filter fs/directory?)
24- first)]
25- (println (str bin))
26- (binding [*out* *err*]
27- (println (str "scripts/android-ndk-bin: no llvm prebuilt under " ndk))
28- (System/exit 1)))
29- (println (str (fs/parent
30- (str/trim (:out (p/shell {:out :string}
31- "dotslash" "--" "fetch"
32- (str (fs/path here "android-ndk.dotslash")))))))))
deleted file mode 100755
@@ -1,32 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; Print the directory holding the NDK's clang and LLVM binutils.
7-;;
8-;; android-cc needs one of those binaries and an APK build needs others
9-;; llvm-objcopy, for the boot image blob so the lookup is here rather than
10-;; duplicated at each caller. ANDROID_NDK_HOME wins if it is set; otherwise the
11-;; pin in android-ndk.dotslash beside this script answers, downloading once.
12-(require '[babashka.fs :as fs]
13- '[babashka.process :as p]
14- '[clojure.string :as str])
15-
16-(def here (fs/parent (fs/canonicalize *file*)))
17-(def ndk (or (not-empty (str (System/getenv "ANDROID_NDK_HOME")))
18- (not-empty (str (System/getenv "ANDROID_NDK_ROOT")))))
19-
20-(if ndk
21- (if-let [bin (->> ["linux-x86_64" "darwin-x86_64"]
22- (map #(fs/path ndk "toolchains" "llvm" "prebuilt" % "bin"))
23- (filter fs/directory?)
24- first)]
25- (println (str bin))
26- (binding [*out* *err*]
27- (println (str "scripts/android-ndk-bin: no llvm prebuilt under " ndk))
28- (System/exit 1)))
29- (println (str (fs/parent
30- (str/trim (:out (p/shell {:out :string}
31- "dotslash" "--" "fetch"
32- (str (fs/path here "android-ndk.dotslash")))))))))
deleted scripts/android-ndk.dotslash +0 -55
deleted file mode 100755
@@ -1,55 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The NDK, pinned the way every other tool here is.
4-//
5-// bin/clang is the path named, but the whole archive is what matters: the
6-// driver finds its sysroot, its resource directory and the rest of the LLVM
7-// binaries relative to itself, so the tree has to travel intact. The name is
8-// only what makes this a runnable shim as well as a manifest.
9-//
10-// Google publishes SHA-1 for these and nothing else, so the digests below were
11-// taken from the archives and checked against the SHA-1 in repository2-3.xml.
12-//
13-// There is no Linux/arm64 NDK. Both macOS entries are the x86_64 prebuilt,
14-// which is what Google ships an arm64 host runs it under Rosetta.
15-{
16- "name": "android-ndk-r29",
17- "platforms": {
18- "linux-x86_64": {
19- "size": 783549481,
20- "hash": "sha256",
21- "digest": "4abbbcdc842f3d4879206e9695d52709603e52dd68d3c1fff04b3b5e7a308ecf",
22- "format": "zip",
23- "path": "android-ndk-r29/toolchains/llvm/prebuilt/linux-x86_64/bin/clang",
24- "providers": [
25- {
26- "url": "https://dl.google.com/android/repository/android-ndk-r29-linux.zip"
27- }
28- ]
29- },
30- "macos-x86_64": {
31- "size": 1049519838,
32- "hash": "sha256",
33- "digest": "ce5e4b100ec5fe5be4eb3edcb2c02528824ff9cda3860f5304619be6c3da34d3",
34- "format": "zip",
35- "path": "android-ndk-r29/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang",
36- "providers": [
37- {
38- "url": "https://dl.google.com/android/repository/android-ndk-r29-darwin.zip"
39- }
40- ]
41- },
42- "macos-aarch64": {
43- "size": 1049519838,
44- "hash": "sha256",
45- "digest": "ce5e4b100ec5fe5be4eb3edcb2c02528824ff9cda3860f5304619be6c3da34d3",
46- "format": "zip",
47- "path": "android-ndk-r29/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang",
48- "providers": [
49- {
50- "url": "https://dl.google.com/android/repository/android-ndk-r29-darwin.zip"
51- }
52- ]
53- }
54- }
55-}
deleted file mode 100755
@@ -1,55 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The NDK, pinned the way every other tool here is.
4-//
5-// bin/clang is the path named, but the whole archive is what matters: the
6-// driver finds its sysroot, its resource directory and the rest of the LLVM
7-// binaries relative to itself, so the tree has to travel intact. The name is
8-// only what makes this a runnable shim as well as a manifest.
9-//
10-// Google publishes SHA-1 for these and nothing else, so the digests below were
11-// taken from the archives and checked against the SHA-1 in repository2-3.xml.
12-//
13-// There is no Linux/arm64 NDK. Both macOS entries are the x86_64 prebuilt,
14-// which is what Google ships an arm64 host runs it under Rosetta.
15-{
16- "name": "android-ndk-r29",
17- "platforms": {
18- "linux-x86_64": {
19- "size": 783549481,
20- "hash": "sha256",
21- "digest": "4abbbcdc842f3d4879206e9695d52709603e52dd68d3c1fff04b3b5e7a308ecf",
22- "format": "zip",
23- "path": "android-ndk-r29/toolchains/llvm/prebuilt/linux-x86_64/bin/clang",
24- "providers": [
25- {
26- "url": "https://dl.google.com/android/repository/android-ndk-r29-linux.zip"
27- }
28- ]
29- },
30- "macos-x86_64": {
31- "size": 1049519838,
32- "hash": "sha256",
33- "digest": "ce5e4b100ec5fe5be4eb3edcb2c02528824ff9cda3860f5304619be6c3da34d3",
34- "format": "zip",
35- "path": "android-ndk-r29/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang",
36- "providers": [
37- {
38- "url": "https://dl.google.com/android/repository/android-ndk-r29-darwin.zip"
39- }
40- ]
41- },
42- "macos-aarch64": {
43- "size": 1049519838,
44- "hash": "sha256",
45- "digest": "ce5e4b100ec5fe5be4eb3edcb2c02528824ff9cda3860f5304619be6c3da34d3",
46- "format": "zip",
47- "path": "android-ndk-r29/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang",
48- "providers": [
49- {
50- "url": "https://dl.google.com/android/repository/android-ndk-r29-darwin.zip"
51- }
52- ]
53- }
54- }
55-}
modified scripts/apk.bb +55 -13
@@ -3,13 +3,31 @@
33 exec "$(dirname "$0")/bb" "$0" "$@"
44 )
55
6-;; The APK, built as a graph.
6+;; The APK, out of the flake.
77 ;;
88 ;; apk.bb [build|install|run|log]
99 ;;
10-;; The build itself is android/BUCK; this only asks buck for the file and then
11-;; does what was asked with it. android/build-apk.bb is the same APK built step
12-;; by step instead, for when the graph is what is being doubted.
10+;; The build itself is nix/android.nix, reached as `.#apk`; this only asks nix
11+;; for the file and then does what was asked with it. Nothing here names an
12+;; Android SDK, an NDK, a Chez cross target or an OpenSSL: the derivation
13+;; builds or fetches every one of them, which is the difference between this
14+;; and the buck2 graph it replaces — that one was handed four hand-built paths
15+;; from the machine and stopped if any was missing.
16+;;
17+;; The APK is signed with a debug key generated inside the derivation, so the
18+;; output is installable and not reproducible; anything meant for a store gets
19+;; signed from `.#apk-unsigned` instead. See nix/android.nix.
20+;;
21+;; FRQ_NIX_STORE builds the whole graph somewhere else rather than here —
22+;;
23+;; FRQ_NIX_STORE=ssh-ng://eu.nixbuild.net scripts/apk.bb
24+;;
25+;; which is the shape android.nix asks for: with a `builders` entry instead,
26+;; nix copies every remotely-built output back, and androidenv's NDK is both
27+;; `preferLocalBuild` and absent from cache.nixos.org, so 3.1 GB of toolchain
28+;; is built here and uploaded. With the remote as the *store* only .drv files
29+;; go up. An install then needs the file here, so it is fetched back at the
30+;; end — one APK rather than the closure that made it.
1331 (require '[babashka.classpath :as cp])
1432 (cp/add-classpath (str (babashka.fs/parent *file*)))
1533 (require '[frq.paths :as paths]
@@ -23,17 +41,41 @@ exec "$(dirname "$0")/bb" "$0" "$@"
2341 "platform-tools" "adb"))))
2442 (def package "uk.nandi.frq")
2543
26-(defn apk []
27- (->> (paths/out (str (fs/path root "scripts" "buck.bb"))
28- "build" "--show-output" "//:apk")
29- str/split-lines
30- (some #(when (str/includes? % "frq.apk") (second (str/split % #"\s+"))))
31- (str root "/")))
44+;; --eval-store auto goes with a remote store and only with one: evaluation
45+;; wants this tree, which is here.
46+(def store
47+ (when-let [s (paths/env "FRQ_NIX_STORE" nil)]
48+ ["--store" s "--eval-store" "auto"]))
49+
50+;; Built without a `result` symlink: the path is what the caller wants, and a
51+;; symlink into a store that may not be this one is not a useful thing to leave
52+;; in the tree.
53+(defn build []
54+ (let [out (->> (paths/nix root (concat ["nix" "build" (str root "#apk")
55+ "--no-link" "--print-out-paths"]
56+ store))
57+ (apply paths/out)
58+ str/split-lines
59+ (filter #(str/starts-with? % "/nix/store/"))
60+ last)]
61+ (when-not out
62+ (paths/die "nix build printed no store path"))
63+ out))
64+
65+;; Off a remote store the path names a file on the builder, so adb has nothing
66+;; to open. `nix copy --no-check-sigs --from` brings just that one path here.
67+(defn local-file []
68+ (let [out (build)]
69+ (when store
70+ (apply p/shell (paths/nix root (concat ["nix" "copy" "--no-check-sigs"
71+ "--from" (paths/env "FRQ_NIX_STORE" nil)
72+ out]))))
73+ out))
3274
3375 (case action
34- "build" (println (apk))
35- "install" (p/shell adb "install" "-r" (apk))
36- "run" (let [file (apk)]
76+ "build" (println (build))
77+ "install" (p/shell adb "install" "-r" (local-file))
78+ "run" (let [file (local-file)]
3779 (p/shell adb "install" "-r" file)
3880 (p/shell adb "shell" "am" "force-stop" package)
3981 (p/shell adb "shell" "am" "start" "-n" (str package "/.FrqActivity")))
@@ -3,13 +3,31 @@
3 exec "$(dirname "$0")/bb" "$0" "$@"3 exec "$(dirname "$0")/bb" "$0" "$@"
4 )4 )
5 5
6-;; The APK, built as a graph.6+;; The APK, out of the flake.
7 ;;7 ;;
8 ;; apk.bb [build|install|run|log]8 ;; apk.bb [build|install|run|log]
9 ;;9 ;;
10-;; The build itself is android/BUCK; this only asks buck for the file and then10+;; The build itself is nix/android.nix, reached as `.#apk`; this only asks nix
11-;; does what was asked with it. android/build-apk.bb is the same APK built step11+;; for the file and then does what was asked with it. Nothing here names an
12-;; by step instead, for when the graph is what is being doubted.12+;; Android SDK, an NDK, a Chez cross target or an OpenSSL: the derivation
13+;; builds or fetches every one of them, which is the difference between this
14+;; and the buck2 graph it replaces — that one was handed four hand-built paths
15+;; from the machine and stopped if any was missing.
16+;;
17+;; The APK is signed with a debug key generated inside the derivation, so the
18+;; output is installable and not reproducible; anything meant for a store gets
19+;; signed from `.#apk-unsigned` instead. See nix/android.nix.
20+;;
21+;; FRQ_NIX_STORE builds the whole graph somewhere else rather than here —
22+;;
23+;; FRQ_NIX_STORE=ssh-ng://eu.nixbuild.net scripts/apk.bb
24+;;
25+;; which is the shape android.nix asks for: with a `builders` entry instead,
26+;; nix copies every remotely-built output back, and androidenv's NDK is both
27+;; `preferLocalBuild` and absent from cache.nixos.org, so 3.1 GB of toolchain
28+;; is built here and uploaded. With the remote as the *store* only .drv files
29+;; go up. An install then needs the file here, so it is fetched back at the
30+;; end — one APK rather than the closure that made it.
13 (require '[babashka.classpath :as cp])31 (require '[babashka.classpath :as cp])
14 (cp/add-classpath (str (babashka.fs/parent *file*)))32 (cp/add-classpath (str (babashka.fs/parent *file*)))
15 (require '[frq.paths :as paths]33 (require '[frq.paths :as paths]
@@ -23,17 +41,41 @@ exec "$(dirname "$0")/bb" "$0" "$@"
23 "platform-tools" "adb"))))41 "platform-tools" "adb"))))
24 (def package "uk.nandi.frq")42 (def package "uk.nandi.frq")
25 43
26-(defn apk []44+;; --eval-store auto goes with a remote store and only with one: evaluation
27- (->> (paths/out (str (fs/path root "scripts" "buck.bb"))45+;; wants this tree, which is here.
28- "build" "--show-output" "//:apk")46+(def store
29- str/split-lines47+ (when-let [s (paths/env "FRQ_NIX_STORE" nil)]
30- (some #(when (str/includes? % "frq.apk") (second (str/split % #"\s+"))))48+ ["--store" s "--eval-store" "auto"]))
31- (str root "/")))49+
50+;; Built without a `result` symlink: the path is what the caller wants, and a
51+;; symlink into a store that may not be this one is not a useful thing to leave
52+;; in the tree.
53+(defn build []
54+ (let [out (->> (paths/nix root (concat ["nix" "build" (str root "#apk")
55+ "--no-link" "--print-out-paths"]
56+ store))
57+ (apply paths/out)
58+ str/split-lines
59+ (filter #(str/starts-with? % "/nix/store/"))
60+ last)]
61+ (when-not out
62+ (paths/die "nix build printed no store path"))
63+ out))
64+
65+;; Off a remote store the path names a file on the builder, so adb has nothing
66+;; to open. `nix copy --no-check-sigs --from` brings just that one path here.
67+(defn local-file []
68+ (let [out (build)]
69+ (when store
70+ (apply p/shell (paths/nix root (concat ["nix" "copy" "--no-check-sigs"
71+ "--from" (paths/env "FRQ_NIX_STORE" nil)
72+ out]))))
73+ out))
32 74
33 (case action75 (case action
34- "build" (println (apk))76+ "build" (println (build))
35- "install" (p/shell adb "install" "-r" (apk))77+ "install" (p/shell adb "install" "-r" (local-file))
36- "run" (let [file (apk)]78+ "run" (let [file (local-file)]
37 (p/shell adb "install" "-r" file)79 (p/shell adb "install" "-r" file)
38 (p/shell adb "shell" "am" "force-stop" package)80 (p/shell adb "shell" "am" "force-stop" package)
39 (p/shell adb "shell" "am" "start" "-n" (str package "/.FrqActivity")))81 (p/shell adb "shell" "am" "start" "-n" (str package "/.FrqActivity")))
deleted scripts/buck.bb +0 -43
deleted file mode 100755
@@ -1,43 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; buck2, with the machine's paths written where the BUCK files can read them.
7-;;
8-;; The same arrangement jolt-native uses, and for the same reason: a BUCK file
9-;; may not look around the machine, and these answers differ on every one.
10-;; Generated rather than committed, so no checkout carries another's paths.
11-(require '[babashka.classpath :as cp])
12-(cp/add-classpath (str (babashka.fs/parent *file*)))
13-(require '[frq.paths :as paths]
14- '[babashka.fs :as fs]
15- '[babashka.process :as p])
16-
17-(def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
18-(def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
19-(def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
20-(def openssl (paths/env "OPENSSL_ANDROID" (str (fs/path (fs/home) ".cache" "frq-openssl-android" "lib"))))
21-
22-(paths/require-paths! "path"
23- [(fs/path android-home "build-tools" "36.0.0" "aapt2")
24- (fs/path android-home "platforms" "android-36" "android.jar")
25- (fs/path chez "boot" "tarm64le" "scheme.boot")
26- (fs/path openssl "libssl.so")])
27-
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.
31-(def boot-stamp
32- (paths/out (str (fs/path root "android" "build-jolt-boot.bb")) "--stamp"))
33-
34-(spit (str (fs/path root ".buckconfig.local"))
35- (str "[frq]\n"
36- " android_home = " android-home "\n"
37- " chez_android = " chez "\n"
38- " openssl_android = " openssl "\n"
39- " boot_stamp = " boot-stamp "\n"))
40-
41-(System/exit
42- (:exit @(apply p/process {:inherit true :dir root}
43- (str (fs/path root "scripts" "buck2")) *command-line-args*)))
deleted file mode 100755
@@ -1,43 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; buck2, with the machine's paths written where the BUCK files can read them.
7-;;
8-;; The same arrangement jolt-native uses, and for the same reason: a BUCK file
9-;; may not look around the machine, and these answers differ on every one.
10-;; Generated rather than committed, so no checkout carries another's paths.
11-(require '[babashka.classpath :as cp])
12-(cp/add-classpath (str (babashka.fs/parent *file*)))
13-(require '[frq.paths :as paths]
14- '[babashka.fs :as fs]
15- '[babashka.process :as p])
16-
17-(def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
18-(def android-home (paths/env "ANDROID_HOME" (str (fs/path (fs/home) ".local" "share" "android-sdk"))))
19-(def chez (paths/env "CHEZ_ANDROID" (str (fs/path (fs/home) ".cache" "vidya-chez-android"))))
20-(def openssl (paths/env "OPENSSL_ANDROID" (str (fs/path (fs/home) ".cache" "frq-openssl-android" "lib"))))
21-
22-(paths/require-paths! "path"
23- [(fs/path android-home "build-tools" "36.0.0" "aapt2")
24- (fs/path android-home "platforms" "android-36" "android.jar")
25- (fs/path chez "boot" "tarm64le" "scheme.boot")
26- (fs/path openssl "libssl.so")])
27-
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.
31-(def boot-stamp
32- (paths/out (str (fs/path root "android" "build-jolt-boot.bb")) "--stamp"))
33-
34-(spit (str (fs/path root ".buckconfig.local"))
35- (str "[frq]\n"
36- " android_home = " android-home "\n"
37- " chez_android = " chez "\n"
38- " openssl_android = " openssl "\n"
39- " boot_stamp = " boot-stamp "\n"))
40-
41-(System/exit
42- (:exit @(apply p/process {:inherit true :dir root}
43- (str (fs/path root "scripts" "buck2")) *command-line-args*)))
deleted scripts/buck2 +0 -67
deleted file mode 100755
@@ -1,67 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-{
4- "name": "buck2",
5- "platforms": {
6- "linux-x86_64": {
7- "size": 39303524,
8- "hash": "blake3",
9- "digest": "afff180bc257de220f393ed4551693d877849cda012ac39cf9d4f7a27693848e",
10- "format": "zst",
11- "path": "buck2",
12- "providers": [
13- {
14- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-x86_64-unknown-linux-musl.zst"
15- }
16- ]
17- },
18- "linux-aarch64": {
19- "size": 37790120,
20- "hash": "blake3",
21- "digest": "52e2182d65630a0b68bb33ca9ae72b64c028668e5d02fe5fd46d8fcb3c361918",
22- "format": "zst",
23- "path": "buck2",
24- "providers": [
25- {
26- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-aarch64-unknown-linux-musl.zst"
27- }
28- ]
29- },
30- "macos-x86_64": {
31- "size": 36655230,
32- "hash": "blake3",
33- "digest": "1959b2f85dbba714f5d1f7824e813b0fca81224117a51cec7db17b8ae9fc1012",
34- "format": "zst",
35- "path": "buck2",
36- "providers": [
37- {
38- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-x86_64-apple-darwin.zst"
39- }
40- ]
41- },
42- "macos-aarch64": {
43- "size": 34435267,
44- "hash": "blake3",
45- "digest": "15ff15f1c10b8ddb3e8b3d43ca73964dec3719a514d805119c5e5963257daefe",
46- "format": "zst",
47- "path": "buck2",
48- "providers": [
49- {
50- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-aarch64-apple-darwin.zst"
51- }
52- ]
53- },
54- "windows-x86_64": {
55- "size": 31803375,
56- "hash": "blake3",
57- "digest": "ab36fa3ee1b4fe2e597b8bf0bfa27f815b64ff3f520b6456fe67cb48b24f85e6",
58- "format": "zst",
59- "path": "buck2.exe",
60- "providers": [
61- {
62- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-x86_64-pc-windows-msvc.exe.zst"
63- }
64- ]
65- }
66- }
67-}
deleted file mode 100755
@@ -1,67 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-{
4- "name": "buck2",
5- "platforms": {
6- "linux-x86_64": {
7- "size": 39303524,
8- "hash": "blake3",
9- "digest": "afff180bc257de220f393ed4551693d877849cda012ac39cf9d4f7a27693848e",
10- "format": "zst",
11- "path": "buck2",
12- "providers": [
13- {
14- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-x86_64-unknown-linux-musl.zst"
15- }
16- ]
17- },
18- "linux-aarch64": {
19- "size": 37790120,
20- "hash": "blake3",
21- "digest": "52e2182d65630a0b68bb33ca9ae72b64c028668e5d02fe5fd46d8fcb3c361918",
22- "format": "zst",
23- "path": "buck2",
24- "providers": [
25- {
26- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-aarch64-unknown-linux-musl.zst"
27- }
28- ]
29- },
30- "macos-x86_64": {
31- "size": 36655230,
32- "hash": "blake3",
33- "digest": "1959b2f85dbba714f5d1f7824e813b0fca81224117a51cec7db17b8ae9fc1012",
34- "format": "zst",
35- "path": "buck2",
36- "providers": [
37- {
38- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-x86_64-apple-darwin.zst"
39- }
40- ]
41- },
42- "macos-aarch64": {
43- "size": 34435267,
44- "hash": "blake3",
45- "digest": "15ff15f1c10b8ddb3e8b3d43ca73964dec3719a514d805119c5e5963257daefe",
46- "format": "zst",
47- "path": "buck2",
48- "providers": [
49- {
50- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-aarch64-apple-darwin.zst"
51- }
52- ]
53- },
54- "windows-x86_64": {
55- "size": 31803375,
56- "hash": "blake3",
57- "digest": "ab36fa3ee1b4fe2e597b8bf0bfa27f815b64ff3f520b6456fe67cb48b24f85e6",
58- "format": "zst",
59- "path": "buck2.exe",
60- "providers": [
61- {
62- "url": "https://github.com/facebook/buck2/releases/download/2026-08-22/buck2-x86_64-pc-windows-msvc.exe.zst"
63- }
64- ]
65- }
66- }
67-}
modified scripts/bump-jolt-native.bb +47 -9
@@ -9,16 +9,23 @@ exec "$(dirname "$0")/bb" "$0" "$@"
99 ;; scripts/bump-jolt-native.bb v0.1.3 # a named one
1010 ;;
1111 ;; 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.
12+;; and the digest of each archive in scripts/*.dotslash, the same URL and digest
13+;; for the Android archives in nix/android.nix, and the release's commit in
14+;; deps.edn. Done by hand it is a lot of copying between a browser and a
15+;; sha256sum, and the failure mode is a pin that still says v0.1.2 while its
16+;; digest is v0.1.3's — which DotSlash catches, but only on the machine that
17+;; next fetches it, and which fetchurl catches at build time and no sooner.
18+;;
19+;; The two places exist because the two builds fetch differently and neither can
20+;; read the other's pin: `just lib` and a released-halves run resolve DotSlash
21+;; manifests, and the APK is a nix derivation, whose inputs have to be fetchurl.
22+;; The digests are the same bytes either way — DotSlash's `digest` is over the
23+;; archive, which is what fetchurl hashes too.
1724 ;;
1825 ;; 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.
26+;; write the manifests and nix/android.nix back, and put the release's commit in
27+;; deps.edn — which is what jolt resolves glimmer-vidya from, and so what the
28+;; boot image compiles against.
2229 ;;
2330 ;; Nothing here decides whether the new release is a good idea. It only makes
2431 ;; the tree say one version instead of two.
@@ -126,6 +133,37 @@ exec "$(dirname "$0")/bb" "$0" "$@"
126133 (spit (str file) (str head (json/generate-string (assoc json "platforms" updated) {:pretty pretty}) "\n"))
127134 (println (str " " (fs/file-name file)))))
128135
136+;; nix/android.nix fetches two of the same archives as `pkgs.fetchurl`, because
137+;; a derivation cannot resolve a DotSlash manifest: the fetch is the input, and
138+;; an input has to be a fixed-output derivation with the digest written down.
139+;; Rewritten as text for the same reason deps.edn is — the file is mostly the
140+;; comments explaining each step, and there is no round-tripping Nix as data
141+;; here anyway.
142+;;
143+;; Every fetchurl whose url points at the repo, whatever it is called: a third
144+;; archive appearing in android.nix should move with the other two rather than
145+;; be remembered about.
146+(defn bump-nix! [tmp tag]
147+ (let [file (fs/path root "nix" "android.nix")
148+ text (slurp (str file))
149+ ;; url and sha256 as one match, so the pair moves together. Anything
150+ ;; between them — a comment, another attribute — would not match, and
151+ ;; not matching is the safe direction: it leaves the pin alone and says
152+ ;; nothing was written.
153+ pattern (re-pattern (str "(url\\s*=\\s*\")(" (java.util.regex.Pattern/quote repo)
154+ "[^\"]*)(\";\\s*\n\\s*sha256\\s*=\\s*\")([^\"]*)(\")"))
155+ seen (atom [])
156+ updated (str/replace text pattern
157+ (fn [[_ head url mid _ tail]]
158+ (let [new-url (retag url (tag-of url) tag)
159+ {:keys [digest]} (weigh tmp new-url)]
160+ (swap! seen conj (last (str/split new-url #"/")))
161+ (str head new-url mid digest tail))))]
162+ (when (empty? @seen)
163+ (paths/die (str "no fetchurl in " file " points at " repo)))
164+ (spit (str file) updated)
165+ (doseq [name @seen] (println (str " nix/android.nix " name)))))
166+
129167 ;; deps.edn takes glimmer-vidya as a git dependency, and the boot image is
130168 ;; compiled from the source root jolt resolves that to. Replaced as text rather
131169 ;; than round-tripped as EDN: the file is mostly comments explaining why each
@@ -152,7 +190,7 @@ exec "$(dirname "$0")/bb" "$0" "$@"
152190 (try
153191 (doseq [m files] (rewrite m tmp tag))
154192 (finally (fs/delete-tree tmp)))
193+ (bump-nix! tmp tag)
155194 (bump-deps! commit)
156- (p/shell (str (fs/path here "dotslash-to-buck")))
157195 (println (str "\nNow: git diff, then `just lib` and `just apk` — the pins are "
158196 "written, nothing is built.")))
@@ -9,16 +9,23 @@ exec "$(dirname "$0")/bb" "$0" "$@"
9 ;; scripts/bump-jolt-native.bb v0.1.3 # a named one9 ;; scripts/bump-jolt-native.bb v0.1.3 # a named one
10 ;;10 ;;
11 ;; A jolt-native bump is four facts in three places: the tag, the URL, the size11 ;; 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 in12+;; and the digest of each archive in scripts/*.dotslash, the same URL and digest
13-;; deps.edn, and the table buck reads, which is generated from the first. Done13+;; for the Android archives in nix/android.nix, and the release's commit in
14-;; by hand it is a lot of copying between a browser and a sha256sum, and the14+;; deps.edn. Done by hand it is a lot of copying between a browser and a
15-;; failure mode is a manifest that still says v0.1.2 while its digest is v0.1.3's15+;; sha256sum, and the failure mode is a pin that still says v0.1.2 while its
16-;; — which DotSlash catches, but only on the machine that next fetches it.16+;; digest is v0.1.3's — which DotSlash catches, but only on the machine that
17+;; next fetches it, and which fetchurl catches at build time and no sooner.
18+;;
19+;; The two places exist because the two builds fetch differently and neither can
20+;; read the other's pin: `just lib` and a released-halves run resolve DotSlash
21+;; manifests, and the APK is a nix derivation, whose inputs have to be fetchurl.
22+;; The digests are the same bytes either way — DotSlash's `digest` is over the
23+;; archive, which is what fetchurl hashes too.
17 ;;24 ;;
18 ;; So: ask GitLab what the release holds, fetch each archive once, weigh it,25 ;; 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 is26+;; write the manifests and nix/android.nix back, and put the release's commit in
20-;; what jolt resolves glimmer-vidya from, and so what the boot image compiles27+;; deps.edn — which is what jolt resolves glimmer-vidya from, and so what the
21-;; against — and re-run dotslash-to-buck.28+;; boot image compiles against.
22 ;;29 ;;
23 ;; Nothing here decides whether the new release is a good idea. It only makes30 ;; Nothing here decides whether the new release is a good idea. It only makes
24 ;; the tree say one version instead of two.31 ;; the tree say one version instead of two.
@@ -126,6 +133,37 @@ exec "$(dirname "$0")/bb" "$0" "$@"
126 (spit (str file) (str head (json/generate-string (assoc json "platforms" updated) {:pretty pretty}) "\n"))133 (spit (str file) (str head (json/generate-string (assoc json "platforms" updated) {:pretty pretty}) "\n"))
127 (println (str " " (fs/file-name file)))))134 (println (str " " (fs/file-name file)))))
128 135
136+;; nix/android.nix fetches two of the same archives as `pkgs.fetchurl`, because
137+;; a derivation cannot resolve a DotSlash manifest: the fetch is the input, and
138+;; an input has to be a fixed-output derivation with the digest written down.
139+;; Rewritten as text for the same reason deps.edn is — the file is mostly the
140+;; comments explaining each step, and there is no round-tripping Nix as data
141+;; here anyway.
142+;;
143+;; Every fetchurl whose url points at the repo, whatever it is called: a third
144+;; archive appearing in android.nix should move with the other two rather than
145+;; be remembered about.
146+(defn bump-nix! [tmp tag]
147+ (let [file (fs/path root "nix" "android.nix")
148+ text (slurp (str file))
149+ ;; url and sha256 as one match, so the pair moves together. Anything
150+ ;; between them — a comment, another attribute — would not match, and
151+ ;; not matching is the safe direction: it leaves the pin alone and says
152+ ;; nothing was written.
153+ pattern (re-pattern (str "(url\\s*=\\s*\")(" (java.util.regex.Pattern/quote repo)
154+ "[^\"]*)(\";\\s*\n\\s*sha256\\s*=\\s*\")([^\"]*)(\")"))
155+ seen (atom [])
156+ updated (str/replace text pattern
157+ (fn [[_ head url mid _ tail]]
158+ (let [new-url (retag url (tag-of url) tag)
159+ {:keys [digest]} (weigh tmp new-url)]
160+ (swap! seen conj (last (str/split new-url #"/")))
161+ (str head new-url mid digest tail))))]
162+ (when (empty? @seen)
163+ (paths/die (str "no fetchurl in " file " points at " repo)))
164+ (spit (str file) updated)
165+ (doseq [name @seen] (println (str " nix/android.nix " name)))))
166+
129 ;; deps.edn takes glimmer-vidya as a git dependency, and the boot image is167 ;; 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 rather168 ;; 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 each169 ;; than round-tripped as EDN: the file is mostly comments explaining why each
@@ -152,7 +190,7 @@ exec "$(dirname "$0")/bb" "$0" "$@"
152 (try190 (try
153 (doseq [m files] (rewrite m tmp tag))191 (doseq [m files] (rewrite m tmp tag))
154 (finally (fs/delete-tree tmp)))192 (finally (fs/delete-tree tmp)))
193+ (bump-nix! tmp tag)
155 (bump-deps! commit)194 (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 "195 (println (str "\nNow: git diff, then `just lib` and `just apk` — the pins are "
158 "written, nothing is built.")))196 "written, nothing is built.")))
deleted scripts/dotslash-to-buck +0 -92
deleted file mode 100755
@@ -1,92 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; Generate buck2 http_archive data from the DotSlash files beside this script.
7-;;
8-;; DotSlash is where a tool's version, URL and digest are written down. buck
9-;; needs the same three facts to fetch that tool itself it cannot use the
10-;; shim, which resolves on the machine at run time and so is neither an action
11-;; input nor anything a remote worker could be given. Rather than write them
12-;; twice and let them drift, this reads the manifests and emits the table buck
13-;; reads.
14-;;
15-;; just sync-dist # after editing any scripts/*.dotslash
16-;;
17-;; The DotSlash format is JSON with a `//` shebang line on top: one entry per
18-;; platform, each with a url, a size, a digest and the path of the binary
19-;; inside the archive. Only the archive itself is wanted here; the path inside
20-;; it is the shim's business, and the toolchain rules name what they need.
21-(require '[babashka.fs :as fs]
22- '[cheshire.core :as json]
23- '[clojure.string :as str])
24-
25-(def here (fs/parent (fs/canonicalize *file*)))
26-(def out-file (fs/path (fs/parent here) "toolchains" "dist" "generated.bzl"))
27-
28-;; The tools buck fetches for itself. buck2 is not among them: it is the thing
29-;; doing the fetching. jolt is not either it is fetched by DotSlash on the
30-;; machine that runs the boot image compile, which may not be this one.
31-(def tools
32- [;; DotSlash itself, so an action can fetch what it needs where it runs
33- ;; rather than being handed it from here. See android/BUCK.
34- "dotslash"
35- ;; jolt-native's release, so the APK's UI half and the Jolt side of the
36- ;; tree ABI are fetched rather than built out of a second checkout.
37- "libvidya-android"
38- ;; The media plane, out of the same tarball as libvidya see its manifest
39- ;; for why the two are pinned together rather than independently.
40- "libjoltmoq-android"
41- "glimmer-vidya"
42- "android-glue"])
43-
44-(defn load-manifest [stem]
45- (let [candidate (->> [(fs/path here (str stem ".dotslash")) (fs/path here stem)]
46- (filter fs/exists?)
47- first)]
48- (when-not candidate
49- (binding [*out* *err*] (println (str "no DotSlash manifest for " stem)))
50- (System/exit 1))
51- (let [text (slurp (str candidate))]
52- (json/parse-string (subs text (str/index-of text "{"))))))
53-
54-(defn platform-entry [entry]
55- (let [;; The path of the binary inside the archive starts with the directory
56- ;; the tarball unpacks into, which is what to strip. A flat archive
57- ;; one binary, no directory around it has nothing to strip, and
58- ;; naming the binary would strip the whole payload.
59- [head rest] (str/split (get entry "path") #"/" 2)]
60- (array-map "url" (get-in entry ["providers" 0 "url"])
61- "sha256" (get entry "digest")
62- "strip_prefix" (if rest head "")
63- "type" (get entry "format"))))
64-
65-(def dist
66- (into (array-map)
67- (for [stem (sort tools)]
68- [stem (into (array-map)
69- (for [[platform entry] (sort-by key (get (load-manifest stem) "platforms"))
70- ;; http_archive takes sha256 and nothing else.
71- :when (= "sha256" (get entry "hash"))]
72- [platform (platform-entry entry)]))])))
73-
74-;; Four-space indentation, like the Starlark around it: this file is read by
75-;; people as often as by buck.
76-(def pretty
77- (json/create-pretty-printer
78- (assoc json/default-pretty-print-options
79- :indentation " "
80- :object-field-value-separator ": ")))
81-
82-(fs/create-dirs (fs/parent out-file))
83-(spit (str out-file)
84- (str/join "\n"
85- ["# @generated by scripts/dotslash-to-buck — do not edit."
86- "#"
87- "# The same archives scripts/*.dotslash pins, as facts buck can act on."
88- "# Bump the DotSlash file and run `just sync-dist`."
89- ""
90- (str "DIST = " (json/generate-string dist {:pretty pretty}))
91- ""]))
92-(println (str "wrote " (fs/relativize (fs/parent here) out-file)))
deleted file mode 100755
@@ -1,92 +0,0 @@
1-#!/bin/sh
2-#_(
3-exec "$(dirname "$0")/bb" "$0" "$@"
4-)
5-
6-;; Generate buck2 http_archive data from the DotSlash files beside this script.
7-;;
8-;; DotSlash is where a tool's version, URL and digest are written down. buck
9-;; needs the same three facts to fetch that tool itself it cannot use the
10-;; shim, which resolves on the machine at run time and so is neither an action
11-;; input nor anything a remote worker could be given. Rather than write them
12-;; twice and let them drift, this reads the manifests and emits the table buck
13-;; reads.
14-;;
15-;; just sync-dist # after editing any scripts/*.dotslash
16-;;
17-;; The DotSlash format is JSON with a `//` shebang line on top: one entry per
18-;; platform, each with a url, a size, a digest and the path of the binary
19-;; inside the archive. Only the archive itself is wanted here; the path inside
20-;; it is the shim's business, and the toolchain rules name what they need.
21-(require '[babashka.fs :as fs]
22- '[cheshire.core :as json]
23- '[clojure.string :as str])
24-
25-(def here (fs/parent (fs/canonicalize *file*)))
26-(def out-file (fs/path (fs/parent here) "toolchains" "dist" "generated.bzl"))
27-
28-;; The tools buck fetches for itself. buck2 is not among them: it is the thing
29-;; doing the fetching. jolt is not either it is fetched by DotSlash on the
30-;; machine that runs the boot image compile, which may not be this one.
31-(def tools
32- [;; DotSlash itself, so an action can fetch what it needs where it runs
33- ;; rather than being handed it from here. See android/BUCK.
34- "dotslash"
35- ;; jolt-native's release, so the APK's UI half and the Jolt side of the
36- ;; tree ABI are fetched rather than built out of a second checkout.
37- "libvidya-android"
38- ;; The media plane, out of the same tarball as libvidya see its manifest
39- ;; for why the two are pinned together rather than independently.
40- "libjoltmoq-android"
41- "glimmer-vidya"
42- "android-glue"])
43-
44-(defn load-manifest [stem]
45- (let [candidate (->> [(fs/path here (str stem ".dotslash")) (fs/path here stem)]
46- (filter fs/exists?)
47- first)]
48- (when-not candidate
49- (binding [*out* *err*] (println (str "no DotSlash manifest for " stem)))
50- (System/exit 1))
51- (let [text (slurp (str candidate))]
52- (json/parse-string (subs text (str/index-of text "{"))))))
53-
54-(defn platform-entry [entry]
55- (let [;; The path of the binary inside the archive starts with the directory
56- ;; the tarball unpacks into, which is what to strip. A flat archive
57- ;; one binary, no directory around it has nothing to strip, and
58- ;; naming the binary would strip the whole payload.
59- [head rest] (str/split (get entry "path") #"/" 2)]
60- (array-map "url" (get-in entry ["providers" 0 "url"])
61- "sha256" (get entry "digest")
62- "strip_prefix" (if rest head "")
63- "type" (get entry "format"))))
64-
65-(def dist
66- (into (array-map)
67- (for [stem (sort tools)]
68- [stem (into (array-map)
69- (for [[platform entry] (sort-by key (get (load-manifest stem) "platforms"))
70- ;; http_archive takes sha256 and nothing else.
71- :when (= "sha256" (get entry "hash"))]
72- [platform (platform-entry entry)]))])))
73-
74-;; Four-space indentation, like the Starlark around it: this file is read by
75-;; people as often as by buck.
76-(def pretty
77- (json/create-pretty-printer
78- (assoc json/default-pretty-print-options
79- :indentation " "
80- :object-field-value-separator ": ")))
81-
82-(fs/create-dirs (fs/parent out-file))
83-(spit (str out-file)
84- (str/join "\n"
85- ["# @generated by scripts/dotslash-to-buck — do not edit."
86- "#"
87- "# The same archives scripts/*.dotslash pins, as facts buck can act on."
88- "# Bump the DotSlash file and run `just sync-dist`."
89- ""
90- (str "DIST = " (json/generate-string dist {:pretty pretty}))
91- ""]))
92-(println (str "wrote " (fs/relativize (fs/parent here) out-file)))
deleted scripts/dotslash.dotslash +0 -66
deleted file mode 100644
@@ -1,66 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// DotSlash itself, so that a remote worker can fetch a toolchain the way this
4-// machine does.
5-//
6-// The other manifests here are pins buck reads and then fetches for itself.
7-// This one is different: it is fetched so that it can do the fetching. An NDK
8-// is three gigabytes unpacked, and shipping that to a worker as an action
9-// input means uploading it to the CAS first; a worker that runs this instead
10-// downloads the same pinned archive, by the same digest, from Google.
11-//
12-// Not runnable as a shim, and nothing tries: a DotSlash file cannot bootstrap
13-// the program that reads it.
14-{
15- "name": "dotslash",
16- "platforms": {
17- "linux-x86_64": {
18- "size": 842816,
19- "hash": "sha256",
20- "digest": "4c75c6eb7890ae35993b962073f6d9bbe78b42b81a5691303ad70f63bfbf7196",
21- "format": "tar.gz",
22- "path": "dotslash",
23- "providers": [
24- {
25- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.x86_64.v0.5.9.tar.gz"
26- }
27- ]
28- },
29- "linux-aarch64": {
30- "size": 754251,
31- "hash": "sha256",
32- "digest": "e58374446dacd4a228388cd275d974bbd8f946916b513cf0eb86bdff5d9d675e",
33- "format": "tar.gz",
34- "path": "dotslash",
35- "providers": [
36- {
37- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.arm64.v0.5.9.tar.gz"
38- }
39- ]
40- },
41- "macos-x86_64": {
42- "size": 716580,
43- "hash": "sha256",
44- "digest": "51446593596ffe4cd22bc43a0fe6d82dd367758eb53cb4ade36d6a684ed08469",
45- "format": "tar.gz",
46- "path": "dotslash",
47- "providers": [
48- {
49- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-amd64.v0.5.9.tar.gz"
50- }
51- ]
52- },
53- "macos-aarch64": {
54- "size": 600404,
55- "hash": "sha256",
56- "digest": "eef15be1b554de7b1409cb0c69c24f2cd04f19c0f101ad69fcdf9d66d4d51639",
57- "format": "tar.gz",
58- "path": "dotslash",
59- "providers": [
60- {
61- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-arm64.v0.5.9.tar.gz"
62- }
63- ]
64- }
65- }
66-}
deleted file mode 100644
@@ -1,66 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// DotSlash itself, so that a remote worker can fetch a toolchain the way this
4-// machine does.
5-//
6-// The other manifests here are pins buck reads and then fetches for itself.
7-// This one is different: it is fetched so that it can do the fetching. An NDK
8-// is three gigabytes unpacked, and shipping that to a worker as an action
9-// input means uploading it to the CAS first; a worker that runs this instead
10-// downloads the same pinned archive, by the same digest, from Google.
11-//
12-// Not runnable as a shim, and nothing tries: a DotSlash file cannot bootstrap
13-// the program that reads it.
14-{
15- "name": "dotslash",
16- "platforms": {
17- "linux-x86_64": {
18- "size": 842816,
19- "hash": "sha256",
20- "digest": "4c75c6eb7890ae35993b962073f6d9bbe78b42b81a5691303ad70f63bfbf7196",
21- "format": "tar.gz",
22- "path": "dotslash",
23- "providers": [
24- {
25- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.x86_64.v0.5.9.tar.gz"
26- }
27- ]
28- },
29- "linux-aarch64": {
30- "size": 754251,
31- "hash": "sha256",
32- "digest": "e58374446dacd4a228388cd275d974bbd8f946916b513cf0eb86bdff5d9d675e",
33- "format": "tar.gz",
34- "path": "dotslash",
35- "providers": [
36- {
37- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.arm64.v0.5.9.tar.gz"
38- }
39- ]
40- },
41- "macos-x86_64": {
42- "size": 716580,
43- "hash": "sha256",
44- "digest": "51446593596ffe4cd22bc43a0fe6d82dd367758eb53cb4ade36d6a684ed08469",
45- "format": "tar.gz",
46- "path": "dotslash",
47- "providers": [
48- {
49- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-amd64.v0.5.9.tar.gz"
50- }
51- ]
52- },
53- "macos-aarch64": {
54- "size": 600404,
55- "hash": "sha256",
56- "digest": "eef15be1b554de7b1409cb0c69c24f2cd04f19c0f101ad69fcdf9d66d4d51639",
57- "format": "tar.gz",
58- "path": "dotslash",
59- "providers": [
60- {
61- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-arm64.v0.5.9.tar.gz"
62- }
63- ]
64- }
65- }
66-}
modified scripts/frq/paths.clj +21 -4
@@ -1,9 +1,7 @@
11 ;; Where the other halves of this build are, and how to ask a program a
22 ;; question without writing the same three lines of shell each time.
33 ;;
4-;; Every script here loads this; nothing else does. The answers match the
5-;; justfile's, deliberately — a person who runs `just apk` and a person who
6-;; runs android/build-apk.bb should be building the same thing.
4+;; Every script here loads this; nothing else does.
75 (ns frq.paths
86 (:require [babashka.fs :as fs]
97 [babashka.process :as p]
@@ -26,8 +24,12 @@
2624 ;; every script here asks the same question of the same pin and a second
2725 ;; jolt-native checkout is never part of the answer.
2826 ;;
27+;; Only the desktop libraries are pinned this way now — `just lib`, and the
28+;; release half of a run. The Android side is nix/android.nix, which fetches
29+;; the same archives by the same digests as `fetchurl`.
30+;;
2931 ;; 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.
32+;; PATH.
3133 (defn dist [root name]
3234 (let [manifest (fs/path root "scripts" (str name ".dotslash"))]
3335 (when-not (fs/exists? manifest)
@@ -47,3 +49,18 @@
4749 (doseq [p paths]
4850 (when-not (fs/exists? (str p))
4951 (apply die (str "missing " label ": " p) hint))))
52+
53+;; A nix command, as an argv to run where nix is.
54+;;
55+;; nix is not on every host this runs on: on the machine these scripts were
56+;; written for it lives in an Arch distrobox, at the same path — which is why
57+;; the container is entered rather than the tree copied into it. See CLAUDE.md.
58+;; Trailing arguments are passed through `"$@"` rather than pasted into the
59+;; command line, so a value with a space in it survives the shell in between.
60+(defn nix [root args & [trailing]]
61+ (if (fs/which "nix")
62+ (concat args trailing)
63+ (concat ["distrobox" "enter" "arch" "--" "bash" "-lc"
64+ (str "cd " root " && exec " (str/join " " args) " \"$@\"")
65+ "--"]
66+ trailing)))
@@ -1,9 +1,7 @@
1 ;; Where the other halves of this build are, and how to ask a program a1 ;; Where the other halves of this build are, and how to ask a program a
2 ;; question without writing the same three lines of shell each time.2 ;; question without writing the same three lines of shell each time.
3 ;;3 ;;
4-;; Every script here loads this; nothing else does. The answers match the4+;; Every script here loads this; nothing else does.
5-;; justfile's, deliberately — a person who runs `just apk` and a person who
6-;; runs android/build-apk.bb should be building the same thing.
7 (ns frq.paths5 (ns frq.paths
8 (:require [babashka.fs :as fs]6 (:require [babashka.fs :as fs]
9 [babashka.process :as p]7 [babashka.process :as p]
@@ -26,8 +24,12 @@
26 ;; every script here asks the same question of the same pin and a second24 ;; every script here asks the same question of the same pin and a second
27 ;; jolt-native checkout is never part of the answer.25 ;; jolt-native checkout is never part of the answer.
28 ;;26 ;;
27+;; Only the desktop libraries are pinned this way now — `just lib`, and the
28+;; release half of a run. The Android side is nix/android.nix, which fetches
29+;; the same archives by the same digests as `fetchurl`.
30+;;
29 ;; DOTSLASH names the fetcher for a caller that has one but has not got it on31 ;; 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.32+;; PATH.
31 (defn dist [root name]33 (defn dist [root name]
32 (let [manifest (fs/path root "scripts" (str name ".dotslash"))]34 (let [manifest (fs/path root "scripts" (str name ".dotslash"))]
33 (when-not (fs/exists? manifest)35 (when-not (fs/exists? manifest)
@@ -47,3 +49,18 @@
47 (doseq [p paths]49 (doseq [p paths]
48 (when-not (fs/exists? (str p))50 (when-not (fs/exists? (str p))
49 (apply die (str "missing " label ": " p) hint))))51 (apply die (str "missing " label ": " p) hint))))
52+
53+;; A nix command, as an argv to run where nix is.
54+;;
55+;; nix is not on every host this runs on: on the machine these scripts were
56+;; written for it lives in an Arch distrobox, at the same path — which is why
57+;; the container is entered rather than the tree copied into it. See CLAUDE.md.
58+;; Trailing arguments are passed through `"$@"` rather than pasted into the
59+;; command line, so a value with a space in it survives the shell in between.
60+(defn nix [root args & [trailing]]
61+ (if (fs/which "nix")
62+ (concat args trailing)
63+ (concat ["distrobox" "enter" "arch" "--" "bash" "-lc"
64+ (str "cd " root " && exec " (str/join " " args) " \"$@\"")
65+ "--"]
66+ trailing)))
deleted scripts/glimmer-vidya.dotslash +0 -62
deleted file mode 100755
@@ -1,62 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The Jolt side that binds the tree ABI, from jolt-native's v0.1.3 release.
4-//
5-// 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,
7-// so every source root has to be named, and a path into somebody's ~/.jolt is
8-// not a thing a build can be handed. This is the same tree at the same commit,
9-// as an archive an action can depend on.
10-{
11- "name": "glimmer-vidya",
12- "platforms": {
13- "linux-x86_64": {
14- "size": 17988,
15- "hash": "sha256",
16- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
17- "format": "tar.gz",
18- "path": "glimmer-vidya/deps.edn",
19- "providers": [
20- {
21- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
22- }
23- ]
24- },
25- "linux-aarch64": {
26- "size": 17988,
27- "hash": "sha256",
28- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
29- "format": "tar.gz",
30- "path": "glimmer-vidya/deps.edn",
31- "providers": [
32- {
33- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
34- }
35- ]
36- },
37- "macos-x86_64": {
38- "size": 17988,
39- "hash": "sha256",
40- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
41- "format": "tar.gz",
42- "path": "glimmer-vidya/deps.edn",
43- "providers": [
44- {
45- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
46- }
47- ]
48- },
49- "macos-aarch64": {
50- "size": 17988,
51- "hash": "sha256",
52- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
53- "format": "tar.gz",
54- "path": "glimmer-vidya/deps.edn",
55- "providers": [
56- {
57- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
58- }
59- ]
60- }
61- }
62-}
deleted file mode 100755
@@ -1,62 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The Jolt side that binds the tree ABI, from jolt-native's v0.1.3 release.
4-//
5-// 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,
7-// so every source root has to be named, and a path into somebody's ~/.jolt is
8-// not a thing a build can be handed. This is the same tree at the same commit,
9-// as an archive an action can depend on.
10-{
11- "name": "glimmer-vidya",
12- "platforms": {
13- "linux-x86_64": {
14- "size": 17988,
15- "hash": "sha256",
16- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
17- "format": "tar.gz",
18- "path": "glimmer-vidya/deps.edn",
19- "providers": [
20- {
21- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
22- }
23- ]
24- },
25- "linux-aarch64": {
26- "size": 17988,
27- "hash": "sha256",
28- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
29- "format": "tar.gz",
30- "path": "glimmer-vidya/deps.edn",
31- "providers": [
32- {
33- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
34- }
35- ]
36- },
37- "macos-x86_64": {
38- "size": 17988,
39- "hash": "sha256",
40- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
41- "format": "tar.gz",
42- "path": "glimmer-vidya/deps.edn",
43- "providers": [
44- {
45- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
46- }
47- ]
48- },
49- "macos-aarch64": {
50- "size": 17988,
51- "hash": "sha256",
52- "digest": "5ea0f7d2c3d3ff56daa3983c7222bd724a6dd4d6977c6b3bb2311d7d708ea9fe",
53- "format": "tar.gz",
54- "path": "glimmer-vidya/deps.edn",
55- "providers": [
56- {
57- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-glimmer-vidya-v0.1.3.tar.gz"
58- }
59- ]
60- }
61- }
62-}
deleted scripts/jolt +0 -28
deleted file mode 100755
@@ -1,28 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// jolt with the Bionic `struct addrinfo` fix, from the fork at
4-// gitlab.com/nandithebull/jolt (commit 2b80d68d). Upstream's own release reads
5-// `ai_addr` at glibc's offset, which on Android is `ai_canonname` a null
6-// pointer so every TLS connect fails there and reports a refusal the network
7-// never made. Nothing else differs from v0.7.28.
8-//
9-// Linux x86_64 only: it is what the APK is built on. Other platforms fall back
10-// to whatever `jolt` is on PATH, which is upstream's, which is fine for
11-// everything but an Android build.
12-{
13- "name": "jolt",
14- "platforms": {
15- "linux-x86_64": {
16- "size": 15782379,
17- "hash": "sha256",
18- "digest": "aabb71f809aebd9d607b7a5036229f933c733ae90785cb29df899f116be9589f",
19- "format": "tar.gz",
20- "path": "jolt-v0.7.28-1-g2b80d68d-x86_64-linux/jolt",
21- "providers": [
22- {
23- "url": "https://gitlab.com/nandithebull/jolt/-/releases/v0.7.28-android/downloads/jolt-v0.7.28-1-g2b80d68d-x86_64-linux.tar.gz"
24- }
25- ]
26- }
27- }
28-}
deleted file mode 100755
@@ -1,28 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// jolt with the Bionic `struct addrinfo` fix, from the fork at
4-// gitlab.com/nandithebull/jolt (commit 2b80d68d). Upstream's own release reads
5-// `ai_addr` at glibc's offset, which on Android is `ai_canonname` a null
6-// pointer so every TLS connect fails there and reports a refusal the network
7-// never made. Nothing else differs from v0.7.28.
8-//
9-// Linux x86_64 only: it is what the APK is built on. Other platforms fall back
10-// to whatever `jolt` is on PATH, which is upstream's, which is fine for
11-// everything but an Android build.
12-{
13- "name": "jolt",
14- "platforms": {
15- "linux-x86_64": {
16- "size": 15782379,
17- "hash": "sha256",
18- "digest": "aabb71f809aebd9d607b7a5036229f933c733ae90785cb29df899f116be9589f",
19- "format": "tar.gz",
20- "path": "jolt-v0.7.28-1-g2b80d68d-x86_64-linux/jolt",
21- "providers": [
22- {
23- "url": "https://gitlab.com/nandithebull/jolt/-/releases/v0.7.28-android/downloads/jolt-v0.7.28-1-g2b80d68d-x86_64-linux.tar.gz"
24- }
25- ]
26- }
27- }
28-}
modified scripts/lib.bb +3 -2
@@ -9,8 +9,9 @@ exec "$(dirname "$0")/bb" "$0" "$@"
99 ;; plane. They come out of one archive because they are built together, and
1010 ;; they land in build/lib because a loader wants one directory. `just run` does
1111 ;; not come through here — running a change to jolt-native means building it,
12-;; which is what the dev shell is for — so this is the released half: what the
13-;; APK and the buck2 build take, and what a run of the last release takes.
12+;; which is what the dev shell is for — so this is the released half: the same
13+;; bytes the APK takes through nix/android.nix, and what a run of the last
14+;; release takes.
1415 ;;
1516 ;; Nothing is compiled here. The pinned bytes are the bytes: this repo used to
1617 ;; clone jolt-native and cargo-build it, which meant a Rust toolchain, a build
@@ -9,8 +9,9 @@ exec "$(dirname "$0")/bb" "$0" "$@"
9 ;; plane. They come out of one archive because they are built together, and9 ;; 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. `just run` does10 ;; they land in build/lib because a loader wants one directory. `just run` does
11 ;; not come through here — running a change to jolt-native means building it,11 ;; not come through here — running a change to jolt-native means building it,
12-;; which is what the dev shell is for — so this is the released half: what the12+;; which is what the dev shell is for — so this is the released half: the same
13-;; APK and the buck2 build take, and what a run of the last release takes.13+;; bytes the APK takes through nix/android.nix, and what a run of the last
14+;; release takes.
14 ;;15 ;;
15 ;; Nothing is compiled here. The pinned bytes are the bytes: this repo used to16 ;; Nothing is compiled here. The pinned bytes are the bytes: this repo used to
16 ;; clone jolt-native and cargo-build it, which meant a Rust toolchain, a build17 ;; clone jolt-native and cargo-build it, which meant a Rust toolchain, a build
deleted scripts/libjoltmoq-android.dotslash +0 -67
deleted file mode 100755
@@ -1,67 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The AV media plane for the phone, from jolt-native's v0.1.3 release.
4-//
5-// The same tarball libvidya-android names, and deliberately so: the two objects
6-// are built together and only make sense together libjoltapp links both, and
7-// a libjoltmoq from one release beside a libvidya from another is a pairing
8-// nothing has tested. Same digest, different file out of it.
9-//
10-// Before v0.1.3 there was no such object at all: the media plane was V4L2 and
11-// PipeWire, which a phone has neither of. The camera is Camera2 over JNI now
12-// and the microphone is cpal's AAudio host.
13-//
14-// The only answer for it, the same as libvidya.
15-{
16- "name": "libjoltmoq-android",
17- "platforms": {
18- "linux-x86_64": {
19- "size": 14150473,
20- "hash": "sha256",
21- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
22- "format": "tar.gz",
23- "path": "libjoltmoq.so",
24- "providers": [
25- {
26- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
27- }
28- ]
29- },
30- "linux-aarch64": {
31- "size": 14150473,
32- "hash": "sha256",
33- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
34- "format": "tar.gz",
35- "path": "libjoltmoq.so",
36- "providers": [
37- {
38- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
39- }
40- ]
41- },
42- "macos-x86_64": {
43- "size": 14150473,
44- "hash": "sha256",
45- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
46- "format": "tar.gz",
47- "path": "libjoltmoq.so",
48- "providers": [
49- {
50- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
51- }
52- ]
53- },
54- "macos-aarch64": {
55- "size": 14150473,
56- "hash": "sha256",
57- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
58- "format": "tar.gz",
59- "path": "libjoltmoq.so",
60- "providers": [
61- {
62- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
63- }
64- ]
65- }
66- }
67-}
deleted file mode 100755
@@ -1,67 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// The AV media plane for the phone, from jolt-native's v0.1.3 release.
4-//
5-// The same tarball libvidya-android names, and deliberately so: the two objects
6-// are built together and only make sense together libjoltapp links both, and
7-// a libjoltmoq from one release beside a libvidya from another is a pairing
8-// nothing has tested. Same digest, different file out of it.
9-//
10-// Before v0.1.3 there was no such object at all: the media plane was V4L2 and
11-// PipeWire, which a phone has neither of. The camera is Camera2 over JNI now
12-// and the microphone is cpal's AAudio host.
13-//
14-// The only answer for it, the same as libvidya.
15-{
16- "name": "libjoltmoq-android",
17- "platforms": {
18- "linux-x86_64": {
19- "size": 14150473,
20- "hash": "sha256",
21- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
22- "format": "tar.gz",
23- "path": "libjoltmoq.so",
24- "providers": [
25- {
26- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
27- }
28- ]
29- },
30- "linux-aarch64": {
31- "size": 14150473,
32- "hash": "sha256",
33- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
34- "format": "tar.gz",
35- "path": "libjoltmoq.so",
36- "providers": [
37- {
38- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
39- }
40- ]
41- },
42- "macos-x86_64": {
43- "size": 14150473,
44- "hash": "sha256",
45- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
46- "format": "tar.gz",
47- "path": "libjoltmoq.so",
48- "providers": [
49- {
50- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
51- }
52- ]
53- },
54- "macos-aarch64": {
55- "size": 14150473,
56- "hash": "sha256",
57- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
58- "format": "tar.gz",
59- "path": "libjoltmoq.so",
60- "providers": [
61- {
62- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
63- }
64- ]
65- }
66- }
67-}
deleted scripts/libvidya-android.dotslash +0 -65
deleted file mode 100755
@@ -1,65 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// libvidya for the phone, from jolt-native's v0.1.3 release.
4-//
5-// arm64, API 28, built by NDK r29 through jolt-native's buck2 toolchain. The
6-// same object `just ffi-android` produces there, pinned so that building the
7-// APK needs neither that checkout nor an NDK.
8-//
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>`.
13-{
14- "name": "libvidya-android",
15- "platforms": {
16- "linux-x86_64": {
17- "size": 14150473,
18- "hash": "sha256",
19- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
20- "format": "tar.gz",
21- "path": "libvidya.so",
22- "providers": [
23- {
24- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
25- }
26- ]
27- },
28- "linux-aarch64": {
29- "size": 14150473,
30- "hash": "sha256",
31- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
32- "format": "tar.gz",
33- "path": "libvidya.so",
34- "providers": [
35- {
36- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
37- }
38- ]
39- },
40- "macos-x86_64": {
41- "size": 14150473,
42- "hash": "sha256",
43- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
44- "format": "tar.gz",
45- "path": "libvidya.so",
46- "providers": [
47- {
48- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
49- }
50- ]
51- },
52- "macos-aarch64": {
53- "size": 14150473,
54- "hash": "sha256",
55- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
56- "format": "tar.gz",
57- "path": "libvidya.so",
58- "providers": [
59- {
60- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
61- }
62- ]
63- }
64- }
65-}
deleted file mode 100755
@@ -1,65 +0,0 @@
1-#!/usr/bin/env dotslash
2-
3-// libvidya for the phone, from jolt-native's v0.1.3 release.
4-//
5-// arm64, API 28, built by NDK r29 through jolt-native's buck2 toolchain. The
6-// same object `just ffi-android` produces there, pinned so that building the
7-// APK needs neither that checkout nor an NDK.
8-//
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>`.
13-{
14- "name": "libvidya-android",
15- "platforms": {
16- "linux-x86_64": {
17- "size": 14150473,
18- "hash": "sha256",
19- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
20- "format": "tar.gz",
21- "path": "libvidya.so",
22- "providers": [
23- {
24- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
25- }
26- ]
27- },
28- "linux-aarch64": {
29- "size": 14150473,
30- "hash": "sha256",
31- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
32- "format": "tar.gz",
33- "path": "libvidya.so",
34- "providers": [
35- {
36- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
37- }
38- ]
39- },
40- "macos-x86_64": {
41- "size": 14150473,
42- "hash": "sha256",
43- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
44- "format": "tar.gz",
45- "path": "libvidya.so",
46- "providers": [
47- {
48- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
49- }
50- ]
51- },
52- "macos-aarch64": {
53- "size": 14150473,
54- "hash": "sha256",
55- "digest": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
56- "format": "tar.gz",
57- "path": "libvidya.so",
58- "providers": [
59- {
60- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz"
61- }
62- ]
63- }
64- }
65-}
modified scripts/run.bb +9 -14
@@ -22,8 +22,8 @@ exec "$(dirname "$0")/bb" "$0" "$@"
2222 ;;
2323 ;; And deliberately not the scripts/*.dotslash pins either, which is what this
2424 ;; used to do. Those name a release; a change to jolt-native is by definition
25-;; not in one yet. `just lib` still fetches them — the APK and the buck2 build
26-;; take the released bytes — but a run does not.
25+;; not in one yet. `just lib` still fetches them, and the APK takes the same
26+;; released bytes through nix/android.nix — but a run does not.
2727 (require '[babashka.classpath :as cp])
2828 (cp/add-classpath (str (babashka.fs/parent *file*)))
2929 (require '[frq.paths :as paths]
@@ -45,18 +45,13 @@ exec "$(dirname "$0")/bb" "$0" "$@"
4545 ;; a remote builder has likely built already. FRQ_MAX_JOBS is the way out on a
4646 ;; machine with no builder configured: FRQ_MAX_JOBS=auto.
4747 (when-not (System/getenv "JOLT_NATIVE_LIB")
48- (let [args ["nix" "develop" root "--max-jobs" (paths/env "FRQ_MAX_JOBS" "0")
49- "--command" self]
50- ;; nix is not on every host this runs on: on the machine this was
51- ;; written for it lives in an Arch distrobox, at the same path — which
52- ;; is why the container is entered rather than the tree copied into it.
53- ;; See CLAUDE.md.
54- cmd (if (fs/which "nix")
55- (concat args *command-line-args*)
56- (concat ["distrobox" "enter" "arch" "--" "bash" "-lc"
57- (str "cd " root " && exec " (str/join " " args) " \"$@\"")
58- "--"]
59- *command-line-args*))]
48+ ;; Getting to a nix on a host that may not have one is paths/nix's problem,
49+ ;; and scripts/apk.bb has the same one.
50+ (let [cmd (paths/nix root
51+ ["nix" "develop" root
52+ "--max-jobs" (paths/env "FRQ_MAX_JOBS" "0")
53+ "--command" self]
54+ *command-line-args*)]
6055 (System/exit (:exit @(apply p/process {:inherit true :dir root} cmd)))))
6156
6257 ;; The Jolt halves that have to match those objects. glimmer-vidya lives inside
@@ -22,8 +22,8 @@ exec "$(dirname "$0")/bb" "$0" "$@"
22 ;;22 ;;
23 ;; And deliberately not the scripts/*.dotslash pins either, which is what this23 ;; And deliberately not the scripts/*.dotslash pins either, which is what this
24 ;; used to do. Those name a release; a change to jolt-native is by definition24 ;; used to do. Those name a release; a change to jolt-native is by definition
25-;; not in one yet. `just lib` still fetches them — the APK and the buck2 build25+;; not in one yet. `just lib` still fetches them, and the APK takes the same
26-;; take the released bytes — but a run does not.26+;; released bytes through nix/android.nix — but a run does not.
27 (require '[babashka.classpath :as cp])27 (require '[babashka.classpath :as cp])
28 (cp/add-classpath (str (babashka.fs/parent *file*)))28 (cp/add-classpath (str (babashka.fs/parent *file*)))
29 (require '[frq.paths :as paths]29 (require '[frq.paths :as paths]
@@ -45,18 +45,13 @@ exec "$(dirname "$0")/bb" "$0" "$@"
45 ;; a remote builder has likely built already. FRQ_MAX_JOBS is the way out on a45 ;; a remote builder has likely built already. FRQ_MAX_JOBS is the way out on a
46 ;; machine with no builder configured: FRQ_MAX_JOBS=auto.46 ;; machine with no builder configured: FRQ_MAX_JOBS=auto.
47 (when-not (System/getenv "JOLT_NATIVE_LIB")47 (when-not (System/getenv "JOLT_NATIVE_LIB")
48- (let [args ["nix" "develop" root "--max-jobs" (paths/env "FRQ_MAX_JOBS" "0")48+ ;; Getting to a nix on a host that may not have one is paths/nix's problem,
49- "--command" self]49+ ;; and scripts/apk.bb has the same one.
50- ;; nix is not on every host this runs on: on the machine this was50+ (let [cmd (paths/nix root
51- ;; written for it lives in an Arch distrobox, at the same path — which51+ ["nix" "develop" root
52- ;; is why the container is entered rather than the tree copied into it.52+ "--max-jobs" (paths/env "FRQ_MAX_JOBS" "0")
53- ;; See CLAUDE.md.53+ "--command" self]
54- cmd (if (fs/which "nix")54+ *command-line-args*)]
55- (concat args *command-line-args*)
56- (concat ["distrobox" "enter" "arch" "--" "bash" "-lc"
57- (str "cd " root " && exec " (str/join " " args) " \"$@\"")
58- "--"]
59- *command-line-args*))]
60 (System/exit (:exit @(apply p/process {:inherit true :dir root} cmd)))))55 (System/exit (:exit @(apply p/process {:inherit true :dir root} cmd)))))
61 56
62 ;; The Jolt halves that have to match those objects. glimmer-vidya lives inside57 ;; The Jolt halves that have to match those objects. glimmer-vidya lives inside
deleted toolchains/BUCK +0 -19
deleted file mode 100644
@@ -1,19 +0,0 @@
1-# There is no compiler toolchain here, and that is the whole design.
2-#
3-# The APK's two native pieces are built by jolt-native: libvidya by its buck2
4-# graph, and the glue by the NDK its scripts/ pins. Everything this repo adds
5-# on top — the boot image, the dex, the packaging — is a tool invocation, so
6-# genrule is the only toolchain the graph needs. Nothing here is resolved
7-# against the machine except the Android SDK, which .buckconfig.local names.
8-load("@prelude//toolchains:genrule.bzl", "system_genrule_toolchain")
9-load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain")
10-
11-system_genrule_toolchain(
12- name = "genrule",
13- visibility = ["PUBLIC"],
14-)
15-
16-system_python_bootstrap_toolchain(
17- name = "python_bootstrap",
18- visibility = ["PUBLIC"],
19-)
deleted file mode 100644
@@ -1,19 +0,0 @@
1-# There is no compiler toolchain here, and that is the whole design.
2-#
3-# The APK's two native pieces are built by jolt-native: libvidya by its buck2
4-# graph, and the glue by the NDK its scripts/ pins. Everything this repo adds
5-# on top — the boot image, the dex, the packaging — is a tool invocation, so
6-# genrule is the only toolchain the graph needs. Nothing here is resolved
7-# against the machine except the Android SDK, which .buckconfig.local names.
8-load("@prelude//toolchains:genrule.bzl", "system_genrule_toolchain")
9-load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain")
10-
11-system_genrule_toolchain(
12- name = "genrule",
13- visibility = ["PUBLIC"],
14-)
15-
16-system_python_bootstrap_toolchain(
17- name = "python_bootstrap",
18- visibility = ["PUBLIC"],
19-)
deleted toolchains/dist.bzl +0 -32
deleted file mode 100644
@@ -1,32 +0,0 @@
1-# DotSlash, as a build artifact rather than something found on the machine.
2-#
3-# scripts/dotslash.dotslash is where the version and digest are written down,
4-# and it stays that way: dist/generated.bzl is derived from it by
5-# scripts/dotslash-to-buck, so there is one place to bump a version and no
6-# second copy of a digest to drift.
7-#
8-# Only DotSlash is fetched this way. jolt is not, and that is the point: what
9-# travels to a worker is the fetcher and the manifest, both small, and the
10-# worker resolves the manifest itself. See android/BUCK.
11-load("//dist:generated.bzl", "DIST")
12-
13-def dist_archive(name, tool, platform):
14- """One pinned archive, fetched by buck rather than by a shim.
15-
16- Unlike DotSlash, which resolves on the machine that runs a tool, this
17- makes the archive's contents an input: their bytes are in the digest of
18- every action that reads them, so a new release rebuilds what depends on
19- it and an unchanged one rebuilds nothing.
20- """
21- entry = DIST[tool][platform]
22- native.http_archive(
23- name = name,
24- urls = [entry["url"]],
25- sha256 = entry["sha256"],
26- strip_prefix = entry["strip_prefix"] or None,
27- type = entry["type"],
28- visibility = ["PUBLIC"],
29- )
30-
31-def dotslash_dist(name, platform):
32- dist_archive(name, "dotslash", platform)
deleted file mode 100644
@@ -1,32 +0,0 @@
1-# DotSlash, as a build artifact rather than something found on the machine.
2-#
3-# scripts/dotslash.dotslash is where the version and digest are written down,
4-# and it stays that way: dist/generated.bzl is derived from it by
5-# scripts/dotslash-to-buck, so there is one place to bump a version and no
6-# second copy of a digest to drift.
7-#
8-# Only DotSlash is fetched this way. jolt is not, and that is the point: what
9-# travels to a worker is the fetcher and the manifest, both small, and the
10-# worker resolves the manifest itself. See android/BUCK.
11-load("//dist:generated.bzl", "DIST")
12-
13-def dist_archive(name, tool, platform):
14- """One pinned archive, fetched by buck rather than by a shim.
15-
16- Unlike DotSlash, which resolves on the machine that runs a tool, this
17- makes the archive's contents an input: their bytes are in the digest of
18- every action that reads them, so a new release rebuilds what depends on
19- it and an unchanged one rebuilds nothing.
20- """
21- entry = DIST[tool][platform]
22- native.http_archive(
23- name = name,
24- urls = [entry["url"]],
25- sha256 = entry["sha256"],
26- strip_prefix = entry["strip_prefix"] or None,
27- type = entry["type"],
28- visibility = ["PUBLIC"],
29- )
30-
31-def dotslash_dist(name, platform):
32- dist_archive(name, "dotslash", platform)
deleted toolchains/dist/BUCK +0 -15
deleted file mode 100644
@@ -1,15 +0,0 @@
1-# The pinned fetcher. See ../dist.bzl; the version and digest come from
2-# scripts/dotslash.dotslash.
3-load("//:dist.bzl", "dist_archive", "dotslash_dist")
4-
5-dotslash_dist(name = "dotslash", platform = "linux-x86_64")
6-
7-# jolt-native's release: what a build gets when there is no sibling checkout to
8-# prefer — see the `buck` recipe in the justfile.
9-dist_archive(name = "libvidya-android", tool = "libvidya-android", platform = "linux-x86_64")
10-
11-dist_archive(name = "libjoltmoq-android", tool = "libjoltmoq-android", platform = "linux-x86_64")
12-
13-dist_archive(name = "glimmer-vidya", tool = "glimmer-vidya", platform = "linux-x86_64")
14-
15-dist_archive(name = "android-glue", tool = "android-glue", platform = "linux-x86_64")
deleted file mode 100644
@@ -1,15 +0,0 @@
1-# The pinned fetcher. See ../dist.bzl; the version and digest come from
2-# scripts/dotslash.dotslash.
3-load("//:dist.bzl", "dist_archive", "dotslash_dist")
4-
5-dotslash_dist(name = "dotslash", platform = "linux-x86_64")
6-
7-# jolt-native's release: what a build gets when there is no sibling checkout to
8-# prefer — see the `buck` recipe in the justfile.
9-dist_archive(name = "libvidya-android", tool = "libvidya-android", platform = "linux-x86_64")
10-
11-dist_archive(name = "libjoltmoq-android", tool = "libjoltmoq-android", platform = "linux-x86_64")
12-
13-dist_archive(name = "glimmer-vidya", tool = "glimmer-vidya", platform = "linux-x86_64")
14-
15-dist_archive(name = "android-glue", tool = "android-glue", platform = "linux-x86_64")
deleted toolchains/dist/generated.bzl +0 -137
deleted file mode 100644
@@ -1,137 +0,0 @@
1-# @generated by scripts/dotslash-to-buck — do not edit.
2-#
3-# The same archives scripts/*.dotslash pins, as facts buck can act on.
4-# Bump the DotSlash file and run `just sync-dist`.
5-
6-DIST = {
7- "android-glue": {
8- "linux-aarch64": {
9- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
10- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
11- "strip_prefix": "jolt-native-android-glue",
12- "type": "tar.gz"
13- },
14- "linux-x86_64": {
15- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
16- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
17- "strip_prefix": "jolt-native-android-glue",
18- "type": "tar.gz"
19- },
20- "macos-aarch64": {
21- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
22- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
23- "strip_prefix": "jolt-native-android-glue",
24- "type": "tar.gz"
25- },
26- "macos-x86_64": {
27- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
28- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
29- "strip_prefix": "jolt-native-android-glue",
30- "type": "tar.gz"
31- }
32- },
33- "dotslash": {
34- "linux-aarch64": {
35- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.arm64.v0.5.9.tar.gz",
36- "sha256": "e58374446dacd4a228388cd275d974bbd8f946916b513cf0eb86bdff5d9d675e",
37- "strip_prefix": "",
38- "type": "tar.gz"
39- },
40- "linux-x86_64": {
41- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.x86_64.v0.5.9.tar.gz",
42- "sha256": "4c75c6eb7890ae35993b962073f6d9bbe78b42b81a5691303ad70f63bfbf7196",
43- "strip_prefix": "",
44- "type": "tar.gz"
45- },
46- "macos-aarch64": {
47- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-arm64.v0.5.9.tar.gz",
48- "sha256": "eef15be1b554de7b1409cb0c69c24f2cd04f19c0f101ad69fcdf9d66d4d51639",
49- "strip_prefix": "",
50- "type": "tar.gz"
51- },
52- "macos-x86_64": {
53- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-amd64.v0.5.9.tar.gz",
54- "sha256": "51446593596ffe4cd22bc43a0fe6d82dd367758eb53cb4ade36d6a684ed08469",
55- "strip_prefix": "",
56- "type": "tar.gz"
57- }
58- },
59- "glimmer-vidya": {
60- "linux-aarch64": {
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",
63- "strip_prefix": "glimmer-vidya",
64- "type": "tar.gz"
65- },
66- "linux-x86_64": {
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",
69- "strip_prefix": "glimmer-vidya",
70- "type": "tar.gz"
71- },
72- "macos-aarch64": {
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",
75- "strip_prefix": "glimmer-vidya",
76- "type": "tar.gz"
77- },
78- "macos-x86_64": {
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",
81- "strip_prefix": "glimmer-vidya",
82- "type": "tar.gz"
83- }
84- },
85- "libjoltmoq-android": {
86- "linux-aarch64": {
87- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
88- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
89- "strip_prefix": "",
90- "type": "tar.gz"
91- },
92- "linux-x86_64": {
93- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
94- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
95- "strip_prefix": "",
96- "type": "tar.gz"
97- },
98- "macos-aarch64": {
99- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
100- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
101- "strip_prefix": "",
102- "type": "tar.gz"
103- },
104- "macos-x86_64": {
105- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
106- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
107- "strip_prefix": "",
108- "type": "tar.gz"
109- }
110- },
111- "libvidya-android": {
112- "linux-aarch64": {
113- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
114- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
115- "strip_prefix": "",
116- "type": "tar.gz"
117- },
118- "linux-x86_64": {
119- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
120- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
121- "strip_prefix": "",
122- "type": "tar.gz"
123- },
124- "macos-aarch64": {
125- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
126- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
127- "strip_prefix": "",
128- "type": "tar.gz"
129- },
130- "macos-x86_64": {
131- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
132- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
133- "strip_prefix": "",
134- "type": "tar.gz"
135- }
136- }
137-}
deleted file mode 100644
@@ -1,137 +0,0 @@
1-# @generated by scripts/dotslash-to-buck — do not edit.
2-#
3-# The same archives scripts/*.dotslash pins, as facts buck can act on.
4-# Bump the DotSlash file and run `just sync-dist`.
5-
6-DIST = {
7- "android-glue": {
8- "linux-aarch64": {
9- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
10- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
11- "strip_prefix": "jolt-native-android-glue",
12- "type": "tar.gz"
13- },
14- "linux-x86_64": {
15- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
16- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
17- "strip_prefix": "jolt-native-android-glue",
18- "type": "tar.gz"
19- },
20- "macos-aarch64": {
21- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
22- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
23- "strip_prefix": "jolt-native-android-glue",
24- "type": "tar.gz"
25- },
26- "macos-x86_64": {
27- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-glue-v0.1.3.tar.gz",
28- "sha256": "83313eda124f2a0cfff6827cf4473600c1f71db2f208d654b97068a85af38da5",
29- "strip_prefix": "jolt-native-android-glue",
30- "type": "tar.gz"
31- }
32- },
33- "dotslash": {
34- "linux-aarch64": {
35- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.arm64.v0.5.9.tar.gz",
36- "sha256": "e58374446dacd4a228388cd275d974bbd8f946916b513cf0eb86bdff5d9d675e",
37- "strip_prefix": "",
38- "type": "tar.gz"
39- },
40- "linux-x86_64": {
41- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-linux-musl.x86_64.v0.5.9.tar.gz",
42- "sha256": "4c75c6eb7890ae35993b962073f6d9bbe78b42b81a5691303ad70f63bfbf7196",
43- "strip_prefix": "",
44- "type": "tar.gz"
45- },
46- "macos-aarch64": {
47- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-arm64.v0.5.9.tar.gz",
48- "sha256": "eef15be1b554de7b1409cb0c69c24f2cd04f19c0f101ad69fcdf9d66d4d51639",
49- "strip_prefix": "",
50- "type": "tar.gz"
51- },
52- "macos-x86_64": {
53- "url": "https://github.com/facebook/dotslash/releases/download/v0.5.9/dotslash-macos-amd64.v0.5.9.tar.gz",
54- "sha256": "51446593596ffe4cd22bc43a0fe6d82dd367758eb53cb4ade36d6a684ed08469",
55- "strip_prefix": "",
56- "type": "tar.gz"
57- }
58- },
59- "glimmer-vidya": {
60- "linux-aarch64": {
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",
63- "strip_prefix": "glimmer-vidya",
64- "type": "tar.gz"
65- },
66- "linux-x86_64": {
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",
69- "strip_prefix": "glimmer-vidya",
70- "type": "tar.gz"
71- },
72- "macos-aarch64": {
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",
75- "strip_prefix": "glimmer-vidya",
76- "type": "tar.gz"
77- },
78- "macos-x86_64": {
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",
81- "strip_prefix": "glimmer-vidya",
82- "type": "tar.gz"
83- }
84- },
85- "libjoltmoq-android": {
86- "linux-aarch64": {
87- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
88- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
89- "strip_prefix": "",
90- "type": "tar.gz"
91- },
92- "linux-x86_64": {
93- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
94- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
95- "strip_prefix": "",
96- "type": "tar.gz"
97- },
98- "macos-aarch64": {
99- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
100- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
101- "strip_prefix": "",
102- "type": "tar.gz"
103- },
104- "macos-x86_64": {
105- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
106- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
107- "strip_prefix": "",
108- "type": "tar.gz"
109- }
110- },
111- "libvidya-android": {
112- "linux-aarch64": {
113- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
114- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
115- "strip_prefix": "",
116- "type": "tar.gz"
117- },
118- "linux-x86_64": {
119- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
120- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
121- "strip_prefix": "",
122- "type": "tar.gz"
123- },
124- "macos-aarch64": {
125- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
126- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
127- "strip_prefix": "",
128- "type": "tar.gz"
129- },
130- "macos-x86_64": {
131- "url": "https://gitlab.com/nandithebull/jolt-native/-/releases/v0.1.3/downloads/jolt-native-android-arm64-v0.1.3.tar.gz",
132- "sha256": "4519745bae6db9a791a71b38a26478879e246166802b0a48dbf7d45e4d45a108",
133- "strip_prefix": "",
134- "type": "tar.gz"
135- }
136- }
137-}