| Write the build in babashka, and pin the babashka 34832a8 nandi 18d ago | 1 | #!/bin/sh |
| 2 | #_( |
| 3 | exec "$(dirname "$0")/bb" "$0" "$@" |
| 4 | ) |
| 5 | |
| Build the APK as derivations only, and retire the buck2 graph 3bc3aaa nandi 16d ago | 6 | ;; The APK, out of the flake. |
| Write the build in babashka, and pin the babashka 34832a8 nandi 18d ago | 7 | ;; |
| 8 | ;; apk.bb [build|install|run|log] |
| 9 | ;; |
| Build the APK as derivations only, and retire the buck2 graph 3bc3aaa nandi 16d ago | 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. |
| Write the build in babashka, and pin the babashka 34832a8 nandi 18d ago | 31 | (require '[babashka.classpath :as cp]) |
| 32 | (cp/add-classpath (str (babashka.fs/parent *file*))) |
| 33 | (require '[frq.paths :as paths] |
| 34 | '[babashka.fs :as fs] |
| 35 | '[babashka.process :as p] |
| 36 | '[clojure.string :as str]) |
| 37 | |
| 38 | (def root (str (fs/canonicalize (fs/path (fs/parent *file*) "..")))) |
| 39 | (def action (or (first *command-line-args*) "build")) |
| 40 | (def adb (paths/env "ADB" (str (fs/path (fs/home) ".local" "share" "android-sdk" |
| 41 | "platform-tools" "adb")))) |
| 42 | (def package "uk.nandi.frq") |
| 43 | |
| Build the APK as derivations only, and retire the buck2 graph 3bc3aaa nandi 16d ago | 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 | |
| Take the Android objects from jolt-native's CI, always the latest 472e179 nandi 11d ago | 50 | ;; The Android objects come from jolt-native's CI under a "latest" alias, and a |
| 51 | ;; flake input is locked once and then stays put — so without this an APK is |
| 52 | ;; built against whatever `flake.lock` recorded the first time, however old. |
| 53 | ;; Re-resolving that one input before every build is what makes "latest" mean |
| 54 | ;; latest; the lock still records which bytes this APK was built from, so a |
| 55 | ;; build remains reproducible after the fact. |
| 56 | ;; |
| 57 | ;; Only this input: `nix flake update` with no argument would move jolt, |
| 58 | ;; nixpkgs and glimmer too, and the whole point of their pins is that they move |
| 59 | ;; when someone decides they should. |
| 60 | (defn refresh-native [] |
| 61 | (apply paths/out (paths/nix root ["nix" "flake" "update" "jolt-native-android" |
| 62 | "--flake" (str root)]))) |
| 63 | |
| Build the APK as derivations only, and retire the buck2 graph 3bc3aaa nandi 16d ago | 64 | ;; Built without a `result` symlink: the path is what the caller wants, and a |
| 65 | ;; symlink into a store that may not be this one is not a useful thing to leave |
| 66 | ;; in the tree. |
| 67 | (defn build [] |
| Take the Android objects from jolt-native's CI, always the latest 472e179 nandi 11d ago | 68 | (refresh-native) |
| Build the APK as derivations only, and retire the buck2 graph 3bc3aaa nandi 16d ago | 69 | (let [out (->> (paths/nix root (concat ["nix" "build" (str root "#apk") |
| 70 | "--no-link" "--print-out-paths"] |
| 71 | store)) |
| 72 | (apply paths/out) |
| 73 | str/split-lines |
| 74 | (filter #(str/starts-with? % "/nix/store/")) |
| 75 | last)] |
| 76 | (when-not out |
| 77 | (paths/die "nix build printed no store path")) |
| 78 | out)) |
| 79 | |
| 80 | ;; Off a remote store the path names a file on the builder, so adb has nothing |
| 81 | ;; to open. `nix copy --no-check-sigs --from` brings just that one path here. |
| 82 | (defn local-file [] |
| 83 | (let [out (build)] |
| 84 | (when store |
| 85 | (apply p/shell (paths/nix root (concat ["nix" "copy" "--no-check-sigs" |
| 86 | "--from" (paths/env "FRQ_NIX_STORE" nil) |
| 87 | out])))) |
| 88 | out)) |
| Write the build in babashka, and pin the babashka 34832a8 nandi 18d ago | 89 | |
| 90 | (case action |
| Build the APK as derivations only, and retire the buck2 graph 3bc3aaa nandi 16d ago | 91 | "build" (println (build)) |
| 92 | "install" (p/shell adb "install" "-r" (local-file)) |
| 93 | "run" (let [file (local-file)] |
| Write the build in babashka, and pin the babashka 34832a8 nandi 18d ago | 94 | (p/shell adb "install" "-r" file) |
| 95 | (p/shell adb "shell" "am" "force-stop" package) |
| 96 | (p/shell adb "shell" "am" "start" "-n" (str package "/.FrqActivity"))) |
| 97 | "log" (p/shell adb "logcat" "-s" "VidyaJolt" "Vidya") |
| 98 | (paths/die "usage: apk.bb [build|install|run|log]")) |