#!/usr/bin/env bash # Build the gallery Android APK (and optionally install it). # # ./scripts/build.sh # release x86_64 (emulator) + install # ./scripts/build.sh aarch64 # release aarch64 (real device) + install # ./scripts/build.sh debug # debug x86_64 + install (faster builds) # ./scripts/build.sh no-install # # framelog (FR frame-gap lines for tools/fr_capture.py): # ./scripts/build.sh aarch64 framelog # or append `framelog` set -euo pipefail cd "$(dirname "$0")/.." export ANDROID_HOME=$HOME/android-sdk export ANDROID_NDK_ROOT=$HOME/android-sdk/ndk/27.0.12077973 # ~/.local/bin: nasm (host build of libjpeg-turbo SIMD; aarch64 needs no nasm). export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$ANDROID_HOME/platform-tools:$PATH" # turbojpeg (M2): build the vendored libjpeg-turbo with CMake, statically # linked into the app (no extra .so in the APK). The NDK CMake toolchain + # ANDROID_* vars are picked up by the `cmake` crate. if [ -n "$ANDROID_NDK_ROOT" ]; then export CMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake export ANDROID_PLATFORM=android-26 export ANDROID_STL=c++_static export TURBOJPEG_STATIC=1 fi # C/C++ cross-compilers for bundled native deps (libsqlite3-sys via # rusqlite, libjpeg-turbo via turbojpeg). The `cc`/`cmake` crates pick # these up per target triple (min sdk 26). NDK_BIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin # CMake target ABI (x86_64 default; overridden below for aarch64). export ANDROID_ABI=x86_64 # The cc crate picks these up per target triple (min sdk 26). export CC_x86_64_linux_android=$NDK_BIN/x86_64-linux-android26-clang export CXX_x86_64_linux_android=$NDK_BIN/x86_64-linux-android26-clang++ export AR_x86_64_linux_android=$NDK_BIN/llvm-ar export CC_aarch64_linux_android=$NDK_BIN/aarch64-linux-android26-clang export CXX_aarch64_linux_android=$NDK_BIN/aarch64-linux-android26-clang++ export AR_aarch64_linux_android=$NDK_BIN/llvm-ar # The cmake crate (turbojpeg-sys → libjpeg-turbo) only honors the plain # CC/CXX: NDK 27's CMake toolchain defaults to `x86_64-linux-android-clang` # (no API suffix), which does not exist, so the compiler must be given. # Set AFTER the target is known (below). # Debug-keystore signing is fine for personal use / Play internal testing. export CARGO_APK_RELEASE_KEYSTORE=$HOME/.android/debug.keystore export CARGO_APK_RELEASE_KEYSTORE_PASSWORD=android arg1=${1:-x86_64} arg2=${2:-install} profile=--release features="" case $arg1 in debug) target=x86_64-linux-android; profile="" ;; debug-aarch64) target=aarch64-linux-android; profile=""; export ANDROID_ABI=arm64-v8a ;; x86_64) target=x86_64-linux-android ;; aarch64) target=aarch64-linux-android; export ANDROID_ABI=arm64-v8a ;; *) echo "unknown arch: $arg1" >&2; exit 1 ;; esac # `framelog` as the second arg: FR lines for tools/fr_capture.py. if [ "$arg2" = framelog ]; then features="framelog" arg2=install fi # Plain CC/CXX for the cmake crate (full NDK compiler for this target). export CC=$NDK_BIN/${target}-android26-clang export CXX=$NDK_BIN/${target}-android26-clang++ profile_dir=release; [ -z "$profile" ] && profile_dir=debug # Optional: ADB_SERIAL picks the device when several are attached (see AGENTS.md). adb=(); [ -n "${ADB_SERIAL:-}" ] && adb=(adb -s "$ADB_SERIAL") # 16 KB page kernel (Pixel 9 Pro): keep the .so's program-header page # size at 4096 or it refuses to load. (The linker itself is set by # cargo-apk2: CARGO_TARGET_*_LINKER = the NDK clang.) export RUSTFLAGS="-C link-arg=-Wl,-z,max-page-size=4096" cargo apk2 build $profile --target "$target" --lib ${features:+--features $features} apk=target/$profile_dir/apk/gallery.apk echo "APK: $apk ($(du -h "$apk" | cut -f1))" if [ "$arg2" = install ] && command -v adb >/dev/null; then "${adb[@]}" install -r "$apk" "${adb[@]}" shell am start -n wow.gmp.gallery/android.app.NativeActivity || true fi