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

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

Take the Android objects from jolt-native's CI, always the latest 472e179 · on 472e179b3bf7b6b6b58384036615ee6693c0f9d7 · nandi · 11d ago
apk.bb · 98 lines · 4.3 KBBlitzBasic Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/bin/sh
#_(
exec "$(dirname "$0")/bb" "$0" "$@"
)

;; The APK, out of the flake.
;;
;;   apk.bb [build|install|run|log]
;;
;; The build itself is nix/android.nix, reached as `.#apk`; this only asks nix
;; for the file and then does what was asked with it. Nothing here names an
;; Android SDK, an NDK, a Chez cross target or an OpenSSL: the derivation
;; builds or fetches every one of them, which is the difference between this
;; and the buck2 graph it replaces — that one was handed four hand-built paths
;; from the machine and stopped if any was missing.
;;
;; The APK is signed with a debug key generated inside the derivation, so the
;; output is installable and not reproducible; anything meant for a store gets
;; signed from `.#apk-unsigned` instead. See nix/android.nix.
;;
;; FRQ_NIX_STORE builds the whole graph somewhere else rather than here —
;;
;;     FRQ_NIX_STORE=ssh-ng://eu.nixbuild.net scripts/apk.bb
;;
;; which is the shape android.nix asks for: with a `builders` entry instead,
;; nix copies every remotely-built output back, and androidenv's NDK is both
;; `preferLocalBuild` and absent from cache.nixos.org, so 3.1 GB of toolchain
;; is built here and uploaded. With the remote as the *store* only .drv files
;; go up. An install then needs the file here, so it is fetched back at the
;; end — one APK rather than the closure that made it.
(require '[babashka.classpath :as cp])
(cp/add-classpath (str (babashka.fs/parent *file*)))
(require '[frq.paths :as paths]
         '[babashka.fs :as fs]
         '[babashka.process :as p]
         '[clojure.string :as str])

(def root (str (fs/canonicalize (fs/path (fs/parent *file*) ".."))))
(def action (or (first *command-line-args*) "build"))
(def adb (paths/env "ADB" (str (fs/path (fs/home) ".local" "share" "android-sdk"
                                        "platform-tools" "adb"))))
(def package "uk.nandi.frq")

;; --eval-store auto goes with a remote store and only with one: evaluation
;; wants this tree, which is here.
(def store
  (when-let [s (paths/env "FRQ_NIX_STORE" nil)]
    ["--store" s "--eval-store" "auto"]))

;; The Android objects come from jolt-native's CI under a "latest" alias, and a
;; flake input is locked once and then stays put — so without this an APK is
;; built against whatever `flake.lock` recorded the first time, however old.
;; Re-resolving that one input before every build is what makes "latest" mean
;; latest; the lock still records which bytes this APK was built from, so a
;; build remains reproducible after the fact.
;;
;; Only this input: `nix flake update` with no argument would move jolt,
;; nixpkgs and glimmer too, and the whole point of their pins is that they move
;; when someone decides they should.
(defn refresh-native []
  (apply paths/out (paths/nix root ["nix" "flake" "update" "jolt-native-android"
                                    "--flake" (str root)])))

;; Built without a `result` symlink: the path is what the caller wants, and a
;; symlink into a store that may not be this one is not a useful thing to leave
;; in the tree.
(defn build []
  (refresh-native)
  (let [out (->> (paths/nix root (concat ["nix" "build" (str root "#apk")
                                          "--no-link" "--print-out-paths"]
                                         store))
                 (apply paths/out)
                 str/split-lines
                 (filter #(str/starts-with? % "/nix/store/"))
                 last)]
    (when-not out
      (paths/die "nix build printed no store path"))
    out))

;; Off a remote store the path names a file on the builder, so adb has nothing
;; to open. `nix copy --no-check-sigs --from` brings just that one path here.
(defn local-file []
  (let [out (build)]
    (when store
      (apply p/shell (paths/nix root (concat ["nix" "copy" "--no-check-sigs"
                                              "--from" (paths/env "FRQ_NIX_STORE" nil)
                                              out]))))
    out))

(case action
  "build" (println (build))
  "install" (p/shell adb "install" "-r" (local-file))
  "run" (let [file (local-file)]
          (p/shell adb "install" "-r" file)
          (p/shell adb "shell" "am" "force-stop" package)
          (p/shell adb "shell" "am" "start" "-n" (str package "/.FrqActivity")))
  "log" (p/shell adb "logcat" "-s" "VidyaJolt" "Vidya")
  (paths/die "usage: apk.bb [build|install|run|log]"))