nandi/frqpublic Fork 0
719742dcbe6d54f9a46d2dd1d059f7a72286e5ba
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-apk.sh · 170 lines · 6.9 KBBash Blame HistoryRaw
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago1#!/usr/bin/env bash
2# Glue the two halves of the frq Android app into an APK.
3#
4# libvidya.so the C ABI on Rust/egui, cross-compiled by buck2, and the
5# NativeActivity's own library (it holds android-activity's
6# glue, so it owns the event loop)
Build the APK with buck2, from pins rather than from a second checkout a71ef8f nandi 19d ago7# libjoltapp.so jolt-native's android/jolt_main.c plus frq's Jolt boot
8# image, dlopened by the above
Sign in and choose a picture on the phone 7b6e915 nandi 19d ago9# classes.dex one Java class, and only because a picture chooser answers
10# through onActivityResult and a NativeActivity has nowhere to
11# deliver that
Carry OpenSSL into the APK 7ef496a nandi 19d ago12# libssl.so OpenSSL, because the platform's own is not ours to load: an
13# libcrypto.so app's linker namespace refuses /system/lib64/libssl.so, and
14# without one there is no TLS at all on the phone
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago15#
16# Neither half is built here beyond that last link: the UI library comes from
Build the APK with buck2, from pins rather than from a second checkout a71ef8f nandi 19d ago17# jolt-native's `just ffi-android` and the boot image from build-jolt-boot.sh.
18# Both native pieces are jolt-native's — only the boot image is frq's.
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago19set -euo pipefail
20
21ROOT="$(cd "$(dirname "$0")/.." && pwd)"
Build the APK with buck2, from pins rather than from a second checkout a71ef8f nandi 19d ago22
23# Where jolt-native is, answered the same way the justfile answers it: a
24# sibling checkout wins, and otherwise it is the clone `just lib` leaves under
25# .jolt-native. --git-common-dir rather than the working tree because this
26# script runs from a worktree as readily as from the checkout, and in one of
27# those "../jolt-native" is not a sibling of anything.
28CHECKOUT="$(dirname "$(git -C "$ROOT" rev-parse --path-format=absolute --git-common-dir)")"
29if [[ -z "${JOLT_NATIVE:-}" ]]; then
30 if [[ -d "$CHECKOUT/../jolt-native" ]]; then
31 JOLT_NATIVE="$(cd "$CHECKOUT/../jolt-native" && pwd)"
32 else
33 JOLT_NATIVE="$CHECKOUT/.jolt-native"
34 fi
35fi
36[[ -d "$JOLT_NATIVE" ]] || {
37 echo "no jolt-native at $JOLT_NATIVE — run \`just lib\` to clone it" >&2
38 exit 1
39}
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago40ANDROID_HOME="${ANDROID_HOME:-$HOME/.local/share/android-sdk}"
41ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$HOME/.local/share/android-ndk-r29}"
42CHEZ_ANDROID="${CHEZ_ANDROID:-$HOME/.cache/vidya-chez-android}"
Carry OpenSSL into the APK 7ef496a nandi 19d ago43OPENSSL_ANDROID="${OPENSSL_ANDROID:-$HOME/.cache/frq-openssl-android/lib}"
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago44BUILD="$ROOT/android/build"
45JOLT_BUILD="$BUILD/jolt"
46STAGE="$BUILD/stage"
47TOOLS="$ANDROID_HOME/build-tools/36.0.0"
48ADB="${ADB:-$ANDROID_HOME/platform-tools/adb}"
49NDK_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
50PACKAGE="uk.nandi.frq"
Sign in and choose a picture on the phone 7b6e915 nandi 19d ago51ACTIVITY="$PACKAGE/.FrqActivity"
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago52API=28
53
54for path in \
55 "$NDK_BIN/aarch64-linux-android$API-clang" \
56 "$ANDROID_HOME/platforms/android-36/android.jar" \
Carry OpenSSL into the APK 7ef496a nandi 19d ago57 "$TOOLS/aapt2" "$TOOLS/zipalign" "$TOOLS/apksigner" "$TOOLS/d8" \
58 "$OPENSSL_ANDROID/libssl.so" "$OPENSSL_ANDROID/libcrypto.so"; do
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago59 [[ -e "$path" ]] || { echo "missing Android tool: $path" >&2; exit 1; }
60done
61
62# --- the UI half ------------------------------------------------------------
Build the APK with buck2, from pins rather than from a second checkout a71ef8f nandi 19d ago63# buck2 fetches its own NDK for this, from the pin in jolt-native's
64# scripts/android-ndk.dotslash, so the toolchain below is the only one that has
65# to be installed by hand.
66( cd "$JOLT_NATIVE" && just ffi-android >&2 )
67VIDYA_SO="$JOLT_NATIVE/build/android/arm64-v8a/libvidya.so"
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago68[[ -f "$VIDYA_SO" ]] || { echo "missing $VIDYA_SO" >&2; exit 1; }
69
70# --- the Jolt half ----------------------------------------------------------
71"$ROOT/android/build-jolt-boot.sh" "$JOLT_BUILD"
72(
73 cd "$JOLT_BUILD"
74 # The boot image travels as a blob in the object file's data section; the
75 # _binary_jolt_boot_{start,end} symbols jolt_main.c reads come from this.
76 "$NDK_BIN/llvm-objcopy" \
77 --input-target=binary \
78 --output-target=elf64-littleaarch64 \
79 --binary-architecture=aarch64 \
80 jolt.boot jolt_boot.o
81)
82
Sign in and choose a picture on the phone 7b6e915 nandi 19d ago83# --- the Java half ----------------------------------------------------------
84# One class: the photo chooser's result has to land somewhere, and native code
85# is not somewhere. d8 turns it into the classes.dex the runtime loads.
86JAVA_BUILD="$BUILD/java"
87rm -rf "$JAVA_BUILD"
88mkdir -p "$JAVA_BUILD/classes"
89# android.jar on the class path is where every android.* type comes from; the
90# JDK's own java.* is what is left, and this class uses nothing of it that
91# Android does not have. (`-bootclasspath` would be the stricter way to say
92# that, and javac refuses it for a release this recent.)
93javac --release 17 \
94 --class-path "$ANDROID_HOME/platforms/android-36/android.jar" \
95 -d "$JAVA_BUILD/classes" \
96 "$ROOT/android/java/uk/nandi/frq/FrqActivity.java"
97"$TOOLS/d8" --min-api $API --output "$JAVA_BUILD" \
98 $(find "$JAVA_BUILD/classes" -name '*.class')
99
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago100rm -rf "$STAGE"
101mkdir -p "$STAGE/lib/arm64-v8a"
Sign in and choose a picture on the phone 7b6e915 nandi 19d ago102cp "$JAVA_BUILD/classes.dex" "$STAGE/classes.dex"
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago103cp "$VIDYA_SO" "$STAGE/lib/arm64-v8a/libvidya.so"
Carry OpenSSL into the APK 7ef496a nandi 19d ago104# jolt.mvn-http dlopens these by name at first use; beside the app's own
105# libraries is where an app's namespace will answer for that name.
106cp "$OPENSSL_ANDROID/libssl.so" "$OPENSSL_ANDROID/libcrypto.so" \
107 "$STAGE/lib/arm64-v8a/"
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago108
109"$NDK_BIN/aarch64-linux-android$API-clang" \
110 -shared -fPIC -O2 \
111 -o "$STAGE/lib/arm64-v8a/libjoltapp.so" \
Build the APK with buck2, from pins rather than from a second checkout a71ef8f nandi 19d ago112 "$JOLT_NATIVE/android/jolt_main.c" \
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago113 "$JOLT_BUILD/jolt_boot.o" \
114 -I"$JOLT_BUILD" \
Build the APK with buck2, from pins rather than from a second checkout a71ef8f nandi 19d ago115 -I"$JOLT_NATIVE/crates/jolt-vidya/include" \
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago116 -L"$STAGE/lib/arm64-v8a" \
117 "$CHEZ_ANDROID/tarm64le/boot/tarm64le/libkernel.a" \
118 "$CHEZ_ANDROID/lz4/lib/liblz4.a" \
119 -lvidya -landroid -llog -lz -ldl -lm \
120 -Wl,--no-undefined
121
122# --- the APK ----------------------------------------------------------------
123UNALIGNED="$BUILD/frq-unaligned.apk"
124ALIGNED="$BUILD/frq-aligned.apk"
125APK="$BUILD/frq.apk"
126rm -f "$UNALIGNED" "$ALIGNED" "$APK"
127"$TOOLS/aapt2" link \
128 -o "$UNALIGNED" \
129 -I "$ANDROID_HOME/platforms/android-36/android.jar" \
130 --manifest "$ROOT/android/AndroidManifest.xml" \
131 --min-sdk-version $API \
132 --target-sdk-version 36 \
133 --version-code 1 \
134 --version-name 0.1.0
135# Stored, not deflated: the loader maps these straight out of the APK.
136(cd "$STAGE" && zip -q -0 "$UNALIGNED" \
Carry OpenSSL into the APK 7ef496a nandi 19d ago137 lib/arm64-v8a/libvidya.so lib/arm64-v8a/libjoltapp.so \
138 lib/arm64-v8a/libssl.so lib/arm64-v8a/libcrypto.so)
Sign in and choose a picture on the phone 7b6e915 nandi 19d ago139# The dex is read by the runtime rather than mapped, so it may as well deflate.
140(cd "$STAGE" && zip -q "$UNALIGNED" classes.dex)
A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago141"$TOOLS/zipalign" -f -p 4 "$UNALIGNED" "$ALIGNED"
142
143KEYSTORE="$HOME/.android/debug.keystore"
144if [[ ! -f "$KEYSTORE" ]]; then
145 mkdir -p "$(dirname "$KEYSTORE")"
146 keytool -genkeypair -v \
147 -keystore "$KEYSTORE" -storepass android -keypass android \
148 -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 \
149 -dname "CN=Android Debug,O=Android,C=US"
150fi
151"$TOOLS/apksigner" sign \
152 --ks "$KEYSTORE" --ks-key-alias androiddebugkey \
153 --ks-pass pass:android --key-pass pass:android \
154 --out "$APK" "$ALIGNED"
155"$TOOLS/apksigner" verify "$APK" >/dev/null
156
157case "${1:-build}" in
158 build) printf '%s\n' "$APK" ;;
159 install) "$ADB" install -r "$APK" ;;
160 run)
161 "$ADB" install -r "$APK"
162 "$ADB" shell am force-stop "$PACKAGE"
163 "$ADB" shell am start -n "$ACTIVITY"
164 ;;
165 log) "$ADB" logcat -s VidyaJolt Vidya ;;
166 *)
167 echo "usage: $0 [build|install|run|log]" >&2
168 exit 2
169 ;;
170esac