build-aar.sh 6.36 KB
#!/bin/bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$ROOT_DIR/../../.." && pwd)"
OUT_DIR="$(cd "$ROOT_DIR/.." && pwd)/android"
SRC_DIR="$ROOT_DIR/src"
BUILD_DIR="$ROOT_DIR/build"
DEPS_DIR="$ROOT_DIR/deps"
UPOS_DEMO_ROOT="$PROJECT_ROOT/UnifiedPOSDevicesDemo_V1.026_EN"
UPOS_AAR="$UPOS_DEMO_ROOT/app/libs/possdk-release.aar"
UPOS_CORE_JAR="$UPOS_DEMO_ROOT/app/libs/core-2.3.0.jar"
STUB_DIR="$BUILD_DIR/stubs"
CLASS_DIR="$BUILD_DIR/classes"
STUB_CLASS_DIR="$BUILD_DIR/stub-classes"
ANDROID_JAR="${ANDROID_JAR:-$HOME/Library/Android/sdk/platforms/android-34/android.jar}"
SDK_LIB_JAR="${SDK_LIB_JAR:-$PROJECT_ROOT/打印机SDK/Android/标签打印机安卓SDK-V3.3.1-20230327/TscDemo/app/libs/SDKLib.jar}"
OUT_AAR="$OUT_DIR/native_fast_printer-release.aar"

# Git Bash / MSYS:Windows 路径 C:\... 需转成 /c/...,否则 javac 拿不到 android.jar(会报 android.* 不存在)
normalize_path_for_bash() {
  local p="$1"
  if [[ -z "$p" ]]; then
    echo ""
    return
  fi
  if command -v cygpath >/dev/null 2>&1; then
    cygpath -u "$p" 2>/dev/null || echo "$p"
    return
  fi
  if [[ "$p" =~ ^[A-Za-z]: ]]; then
    local d
    d=$(echo "${p:0:1}" | tr '[:upper:]' '[:lower:]')
    local r="${p:2}"
    r="${r//\\//}"
    echo "/$d$r"
    return
  fi
  echo "$p"
}

ANDROID_JAR="$(normalize_path_for_bash "$ANDROID_JAR")"
SDK_LIB_JAR="$(normalize_path_for_bash "$SDK_LIB_JAR")"
UPOS_AAR="$(normalize_path_for_bash "$UPOS_AAR")"
UPOS_CORE_JAR="$(normalize_path_for_bash "$UPOS_CORE_JAR")"

mkdir -p "$DEPS_DIR"
JSON_JAR="$DEPS_DIR/json-20240303.jar"
if [[ ! -f "$JSON_JAR" ]]; then
  echo "Downloading org.json jar for host compile..."
  curl -fsSL -o "$JSON_JAR" "https://repo1.maven.org/maven2/org/json/json/20240303/json-20240303.jar"
fi

UPOS_CLASSES_JAR="$DEPS_DIR/possdk-classes.jar"
UPOS_JNI_DIR="$DEPS_DIR/possdk-jni"
if [[ -f "$UPOS_AAR" ]]; then
  if [[ ! -f "$UPOS_CLASSES_JAR" ]] || [[ "$UPOS_AAR" -nt "$UPOS_CLASSES_JAR" ]] || [[ ! -d "$UPOS_JNI_DIR" ]]; then
    echo "Extracting possdk classes.jar/jni from AAR..."
    TMP_UPOS_DIR="$DEPS_DIR/.upos_aar_extract"
    rm -rf "$TMP_UPOS_DIR"
    mkdir -p "$TMP_UPOS_DIR"
    (
      cd "$TMP_UPOS_DIR"
      # AAR is ZIP; jar can extract it.
      jar xf "$UPOS_AAR"
    )
    if [[ ! -f "$TMP_UPOS_DIR/classes.jar" ]]; then
      echo "ERROR: classes.jar not found inside possdk-release.aar" >&2
      exit 1
    fi
    cp "$TMP_UPOS_DIR/classes.jar" "$UPOS_CLASSES_JAR"
    rm -rf "$UPOS_JNI_DIR"
    if [[ -d "$TMP_UPOS_DIR/jni" ]]; then
      mkdir -p "$UPOS_JNI_DIR"
      cp -R "$TMP_UPOS_DIR/jni/." "$UPOS_JNI_DIR/"
    fi
    rm -rf "$TMP_UPOS_DIR"
  fi
else
  echo "WARN: UnifiedPOS possdk-release.aar not found: $UPOS_AAR"
fi

rm -rf "$BUILD_DIR"
mkdir -p "$STUB_DIR/com/taobao/weex/annotation" \
         "$STUB_DIR/com/taobao/weex/bridge" \
         "$STUB_DIR/io/dcloud/feature/uniapp/common" \
         "$STUB_DIR/com/alibaba/fastjson" \
         "$CLASS_DIR" "$STUB_CLASS_DIR" "$OUT_DIR" "$BUILD_DIR/libs"

cat > "$STUB_DIR/com/taobao/weex/annotation/JSMethod.java" <<'STUB'
package com.taobao.weex.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface JSMethod { boolean uiThread() default true; }
STUB

cat > "$STUB_DIR/com/taobao/weex/bridge/JSCallback.java" <<'STUB'
package com.taobao.weex.bridge;
public interface JSCallback {
  void invoke(Object value);
  void invokeAndKeepAlive(Object value);
}
STUB

cat > "$STUB_DIR/io/dcloud/feature/uniapp/common/UniModule.java" <<'STUB'
package io.dcloud.feature.uniapp.common;
public class UniModule {}
STUB

cat > "$STUB_DIR/com/alibaba/fastjson/JSONObject.java" <<'STUB'
package com.alibaba.fastjson;
import java.util.HashMap;
public class JSONObject extends HashMap<String, Object> {
  public String getString(String key){ Object v = get(key); return v == null ? null : String.valueOf(v); }
  public Integer getInteger(String key){ Object v = get(key); if (v == null) return null; if (v instanceof Number) return ((Number)v).intValue(); return Integer.parseInt(String.valueOf(v)); }
}
STUB

if [[ ! -f "$ANDROID_JAR" ]]; then
  echo "ERROR: ANDROID_JAR not found: $ANDROID_JAR" >&2
  echo "Set ANDROID_JAR to your SDK platforms/android-XX/android.jar" >&2
  exit 1
fi
if [[ ! -f "$SDK_LIB_JAR" ]]; then
  echo "ERROR: SDK_LIB_JAR not found: $SDK_LIB_JAR" >&2
  exit 1
fi

CP_MAIN="$ANDROID_JAR:$BUILD_DIR/stubs.jar:$SDK_LIB_JAR:$JSON_JAR"
if [[ -f "$UPOS_CLASSES_JAR" ]]; then
  CP_MAIN="$CP_MAIN:$UPOS_CLASSES_JAR"
fi
if [[ -f "$UPOS_CORE_JAR" ]]; then
  CP_MAIN="$CP_MAIN:$UPOS_CORE_JAR"
fi

find "$STUB_DIR" -name '*.java' -print0 | xargs -0 javac -source 1.8 -target 1.8 -encoding UTF-8 -cp "$ANDROID_JAR" -d "$STUB_CLASS_DIR"
jar cf "$BUILD_DIR/stubs.jar" -C "$STUB_CLASS_DIR" .

find "$SRC_DIR" -name '*.java' -print0 | xargs -0 javac -source 1.8 -target 1.8 -encoding UTF-8 -cp "$CP_MAIN" -d "$CLASS_DIR"
jar cf "$BUILD_DIR/classes.jar" -C "$CLASS_DIR" .
cp "$SDK_LIB_JAR" "$BUILD_DIR/libs/SDKLib.jar"
if [[ -f "$UPOS_CLASSES_JAR" ]]; then
  cp "$UPOS_CLASSES_JAR" "$BUILD_DIR/libs/possdk-classes.jar"
fi
if [[ -f "$UPOS_CORE_JAR" ]]; then
  cp "$UPOS_CORE_JAR" "$BUILD_DIR/libs/core-2.3.0.jar"
fi
if [[ -d "$UPOS_JNI_DIR" ]]; then
  mkdir -p "$BUILD_DIR/jni"
  cp -R "$UPOS_JNI_DIR/." "$BUILD_DIR/jni/"
fi

cat > "$BUILD_DIR/AndroidManifest.xml" <<'MANIFEST'
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.foodlabel.nativeprinter" />
MANIFEST
: > "$BUILD_DIR/R.txt"
mkdir -p "$BUILD_DIR/META-INF/com/android/build/gradle"
cat > "$BUILD_DIR/META-INF/com/android/build/gradle/aar-metadata.properties" <<'META'
aarFormatVersion=1.0
aarMetadataVersion=1.0
META

cd "$BUILD_DIR"
rm -f "$OUT_AAR"
# Windows Git Bash 通常没有 zip;AAR 本质是 ZIP,用 JDK 自带的 jar 打包(与 javac 同目录)
if command -v zip >/dev/null 2>&1; then
  zip -q -r "$OUT_AAR" AndroidManifest.xml classes.jar R.txt META-INF libs jni
else
  if ! command -v jar >/dev/null 2>&1; then
    echo "ERROR: neither zip nor jar found in PATH. Install JDK and add JAVA_HOME/bin to PATH." >&2
    exit 127
  fi
  # c0 = 仅存储;M = 不生成 jar 默认 MANIFEST(避免污染 AAR 的 META-INF)
  jar c0Mf "$OUT_AAR" AndroidManifest.xml classes.jar R.txt META-INF libs jni
fi

echo "Built AAR: $OUT_AAR"