#!/bin/bash set -e PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)" BUILD_DIR="$PROJECT_DIR/build" APK_DIR="$BUILD_DIR/apk" MANIFEST="$PROJECT_DIR/android/AndroidManifest.xml" ASSETS_DIR="$PROJECT_DIR/assets" SO_FILE="$BUILD_DIR/libuidef-tool.so" ANDROID_JAR="$HOME/android.jar" JAVA_SRC_DIR="$PROJECT_DIR/android/java" RES_DIR="$PROJECT_DIR/android/res" # Check prerequisites if [ ! -f "$SO_FILE" ]; then echo "ERROR: libuidef-tool.so not found. Run cmake --build build first." exit 1 fi echo "=== Building APK ===" # Clean staging area rm -rf "$APK_DIR" mkdir -p "$APK_DIR/lib/arm64-v8a" mkdir -p "$APK_DIR/assets" # 1. Copy shared libraries (strip Termux RUNPATH first) cp "$SO_FILE" "$APK_DIR/lib/arm64-v8a/" if command -v patchelf &>/dev/null; then patchelf --remove-rpath "$APK_DIR/lib/arm64-v8a/libuidef-tool.so" fi # Bundle libc++_shared.so (NDK builds link against it dynamically) LIBCXX="$PREFIX/lib/libc++_shared.so" if [ -f "$LIBCXX" ]; then cp "$LIBCXX" "$APK_DIR/lib/arm64-v8a/" fi # libxml2 is loaded via dlopen at runtime (not bundled) # XSD validation will gracefully degrade if unavailable echo "[1/7] Copied shared libraries" # 2. Copy assets cp -r "$ASSETS_DIR"/* "$APK_DIR/assets/" echo "[2/7] Copied assets" # 3. Compile Java sources to classes.dex JAVA_BUILD="$BUILD_DIR/java_build" rm -rf "$JAVA_BUILD" mkdir -p "$JAVA_BUILD/classes" javac -source 8 -target 8 \ -bootclasspath "$ANDROID_JAR" \ -d "$JAVA_BUILD/classes" \ "$JAVA_SRC_DIR"/com/uidef/edit/*.java d8 --output "$JAVA_BUILD" "$JAVA_BUILD"/classes/com/uidef/edit/*.class echo "[3/7] Compiled Java to DEX" # 4. Compile and link resources with aapt2 RES_COMPILED="$BUILD_DIR/res_compiled" rm -rf "$RES_COMPILED" mkdir -p "$RES_COMPILED" # Compile each resource directory if [ -d "$RES_DIR" ]; then for res_subdir in "$RES_DIR"/*/; do if [ -d "$res_subdir" ]; then aapt2 compile -o "$RES_COMPILED" "$res_subdir"* fi done fi # Collect all compiled .flat files FLAT_FILES="" if [ -d "$RES_COMPILED" ]; then FLAT_FILES=$(find "$RES_COMPILED" -name "*.flat" -type f 2>/dev/null | tr '\n' ' ') fi aapt2 link \ --manifest "$MANIFEST" \ -I "$ANDROID_JAR" \ --min-sdk-version 26 \ --target-sdk-version 26 \ -o "$BUILD_DIR/base.apk" \ --auto-add-overlay \ $FLAT_FILES echo "[4/7] Linked resources" # 5. Add .so, assets, and classes.dex into the APK (it's a zip) cd "$APK_DIR" zip -r "$BUILD_DIR/base.apk" lib/ assets/ cd "$JAVA_BUILD" zip -j "$BUILD_DIR/base.apk" classes.dex cd "$PROJECT_DIR" echo "[5/7] Added libs, assets, and DEX" # 6. Zipalign zipalign -f 4 "$BUILD_DIR/base.apk" "$BUILD_DIR/aligned.apk" echo "[6/7] Zipaligned" # 7. Sign with debug key KEYSTORE="$BUILD_DIR/debug.keystore" if [ ! -f "$KEYSTORE" ]; then echo " Generating debug keystore..." keytool -genkeypair \ -keystore "$KEYSTORE" \ -alias debug \ -keyalg RSA \ -keysize 2048 \ -validity 10000 \ -storepass android \ -keypass android \ -dname "CN=Debug,O=Debug,C=US" fi apksigner sign \ --ks "$KEYSTORE" \ --ks-key-alias debug \ --ks-pass pass:android \ --key-pass pass:android \ --out "$BUILD_DIR/uidef-edit.apk" \ "$BUILD_DIR/aligned.apk" echo "[7/7] Signed APK" # Cleanup intermediates rm -f "$BUILD_DIR/base.apk" "$BUILD_DIR/aligned.apk" echo "" echo "=== APK built: $BUILD_DIR/uidef-edit.apk ===" ls -lh "$BUILD_DIR/uidef-edit.apk"