| A freeq client in jolt, as glimmer components on Vidya 4719d6f nandi 20d ago | 1 | #!/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) |
| 7 | # libjoltapp.so vidya's android/jolt_main.c plus frq's Jolt boot image, |
| 8 | # dlopened by the above |
| 9 | # |
| 10 | # Neither half is built here beyond that last link: the UI library comes from |
| 11 | # vidya's `just ffi-android` and the boot image from build-jolt-boot.sh. Both |
| 12 | # native pieces are vidya's — only the boot image is frq's. |
| 13 | set -euo pipefail |
| 14 | |
| 15 | ROOT="$(cd "$(dirname "$0")/.." && pwd)" |
| 16 | VIDYA="${VIDYA:-$(cd "$ROOT/../vidya" && pwd)}" |
| 17 | ANDROID_HOME="${ANDROID_HOME:-$HOME/.local/share/android-sdk}" |
| 18 | ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$HOME/.local/share/android-ndk-r29}" |
| 19 | CHEZ_ANDROID="${CHEZ_ANDROID:-$HOME/.cache/vidya-chez-android}" |
| 20 | BUILD="$ROOT/android/build" |
| 21 | JOLT_BUILD="$BUILD/jolt" |
| 22 | STAGE="$BUILD/stage" |
| 23 | TOOLS="$ANDROID_HOME/build-tools/36.0.0" |
| 24 | ADB="${ADB:-$ANDROID_HOME/platform-tools/adb}" |
| 25 | NDK_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" |
| 26 | PACKAGE="uk.nandi.frq" |
| 27 | ACTIVITY="$PACKAGE/android.app.NativeActivity" |
| 28 | API=28 |
| 29 | |
| 30 | for path in \ |
| 31 | "$NDK_BIN/aarch64-linux-android$API-clang" \ |
| 32 | "$ANDROID_HOME/platforms/android-36/android.jar" \ |
| 33 | "$TOOLS/aapt2" "$TOOLS/zipalign" "$TOOLS/apksigner"; do |
| 34 | [[ -e "$path" ]] || { echo "missing Android tool: $path" >&2; exit 1; } |
| 35 | done |
| 36 | |
| 37 | # --- the UI half ------------------------------------------------------------ |
| 38 | ( cd "$VIDYA" && just ffi-android >&2 ) |
| 39 | VIDYA_SO="$VIDYA/build/android/arm64-v8a/libvidya.so" |
| 40 | [[ -f "$VIDYA_SO" ]] || { echo "missing $VIDYA_SO" >&2; exit 1; } |
| 41 | |
| 42 | # --- the Jolt half ---------------------------------------------------------- |
| 43 | "$ROOT/android/build-jolt-boot.sh" "$JOLT_BUILD" |
| 44 | ( |
| 45 | cd "$JOLT_BUILD" |
| 46 | # The boot image travels as a blob in the object file's data section; the |
| 47 | # _binary_jolt_boot_{start,end} symbols jolt_main.c reads come from this. |
| 48 | "$NDK_BIN/llvm-objcopy" \ |
| 49 | --input-target=binary \ |
| 50 | --output-target=elf64-littleaarch64 \ |
| 51 | --binary-architecture=aarch64 \ |
| 52 | jolt.boot jolt_boot.o |
| 53 | ) |
| 54 | |
| 55 | rm -rf "$STAGE" |
| 56 | mkdir -p "$STAGE/lib/arm64-v8a" |
| 57 | cp "$VIDYA_SO" "$STAGE/lib/arm64-v8a/libvidya.so" |
| 58 | |
| 59 | "$NDK_BIN/aarch64-linux-android$API-clang" \ |
| 60 | -shared -fPIC -O2 \ |
| 61 | -o "$STAGE/lib/arm64-v8a/libjoltapp.so" \ |
| 62 | "$VIDYA/android/jolt_main.c" \ |
| 63 | "$JOLT_BUILD/jolt_boot.o" \ |
| 64 | -I"$JOLT_BUILD" \ |
| 65 | -I"$VIDYA/raylib/include" \ |
| 66 | -I"$VIDYA/ffi/include" \ |
| 67 | -L"$STAGE/lib/arm64-v8a" \ |
| 68 | "$CHEZ_ANDROID/tarm64le/boot/tarm64le/libkernel.a" \ |
| 69 | "$CHEZ_ANDROID/lz4/lib/liblz4.a" \ |
| 70 | -lvidya -landroid -llog -lz -ldl -lm \ |
| 71 | -Wl,--no-undefined |
| 72 | |
| 73 | # --- the APK ---------------------------------------------------------------- |
| 74 | UNALIGNED="$BUILD/frq-unaligned.apk" |
| 75 | ALIGNED="$BUILD/frq-aligned.apk" |
| 76 | APK="$BUILD/frq.apk" |
| 77 | rm -f "$UNALIGNED" "$ALIGNED" "$APK" |
| 78 | "$TOOLS/aapt2" link \ |
| 79 | -o "$UNALIGNED" \ |
| 80 | -I "$ANDROID_HOME/platforms/android-36/android.jar" \ |
| 81 | --manifest "$ROOT/android/AndroidManifest.xml" \ |
| 82 | --min-sdk-version $API \ |
| 83 | --target-sdk-version 36 \ |
| 84 | --version-code 1 \ |
| 85 | --version-name 0.1.0 |
| 86 | # Stored, not deflated: the loader maps these straight out of the APK. |
| 87 | (cd "$STAGE" && zip -q -0 "$UNALIGNED" \ |
| 88 | lib/arm64-v8a/libvidya.so lib/arm64-v8a/libjoltapp.so) |
| 89 | "$TOOLS/zipalign" -f -p 4 "$UNALIGNED" "$ALIGNED" |
| 90 | |
| 91 | KEYSTORE="$HOME/.android/debug.keystore" |
| 92 | if [[ ! -f "$KEYSTORE" ]]; then |
| 93 | mkdir -p "$(dirname "$KEYSTORE")" |
| 94 | keytool -genkeypair -v \ |
| 95 | -keystore "$KEYSTORE" -storepass android -keypass android \ |
| 96 | -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 \ |
| 97 | -dname "CN=Android Debug,O=Android,C=US" |
| 98 | fi |
| 99 | "$TOOLS/apksigner" sign \ |
| 100 | --ks "$KEYSTORE" --ks-key-alias androiddebugkey \ |
| 101 | --ks-pass pass:android --key-pass pass:android \ |
| 102 | --out "$APK" "$ALIGNED" |
| 103 | "$TOOLS/apksigner" verify "$APK" >/dev/null |
| 104 | |
| 105 | case "${1:-build}" in |
| 106 | build) printf '%s\n' "$APK" ;; |
| 107 | install) "$ADB" install -r "$APK" ;; |
| 108 | run) |
| 109 | "$ADB" install -r "$APK" |
| 110 | "$ADB" shell am force-stop "$PACKAGE" |
| 111 | "$ADB" shell am start -n "$ACTIVITY" |
| 112 | ;; |
| 113 | log) "$ADB" logcat -s VidyaJolt Vidya ;; |
| 114 | *) |
| 115 | echo "usage: $0 [build|install|run|log]" >&2 |
| 116 | exit 2 |
| 117 | ;; |
| 118 | esac |