From e9b4dbce6ead97b63ae6a7a104842e77e109ea22 Mon Sep 17 00:00:00 2001 From: "Sijie.Sun" Date: Sun, 28 Sep 2025 23:18:51 +0800 Subject: [PATCH] use cargo ndk in jni build script (#1424) --- .../easytier-android-jni/build.sh | 125 +++++++++--------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/easytier-contrib/easytier-android-jni/build.sh b/easytier-contrib/easytier-android-jni/build.sh index 42a81de..4bb1ea0 100755 --- a/easytier-contrib/easytier-android-jni/build.sh +++ b/easytier-contrib/easytier-android-jni/build.sh @@ -2,6 +2,7 @@ # EasyTier Android JNI 构建脚本 # 用于编译适用于 Android 平台的 JNI 库 +# 使用 cargo-ndk 工具简化 Android 编译过程 set -e @@ -13,8 +14,8 @@ NC='\033[0m' # No Color REPO_ROOT=$(git rev-parse --show-toplevel) -echo -e "${GREEN}EasyTier Android JNI 构建脚本${NC}" -echo "==============================" +echo -e "${GREEN}EasyTier Android JNI 构建脚本 (使用 cargo-ndk)${NC}" +echo "==============================================" # 检查 Rust 是否安装 if ! command -v rustc &> /dev/null; then @@ -28,18 +29,38 @@ if ! command -v cargo &> /dev/null; then exit 1 fi -# Android 目标架构 -# TARGETS=("aarch64-linux-android" "armv7-linux-androideabi" "i686-linux-android" "x86_64-linux-android") -TARGETS=("aarch64-linux-android") +# 检查 cargo-ndk 是否安装 +if ! cargo ndk --version &> /dev/null; then + echo -e "${YELLOW}cargo-ndk 未安装,正在安装...${NC}" + cargo install cargo-ndk + if ! cargo ndk --version &> /dev/null; then + echo -e "${RED}错误: cargo-ndk 安装失败${NC}" + exit 1 + fi +fi -# 检查是否安装了 Android 目标 -echo -e "${YELLOW}检查 Android 目标架构...${NC}" -for target in "${TARGETS[@]}"; do - if ! rustup target list --installed | grep -q "$target"; then - echo -e "${YELLOW}安装目标架构: $target${NC}" - rustup target add "$target" +echo -e "${GREEN}cargo-ndk 版本: $(cargo ndk --version)${NC}" + +# Android 目标架构映射 (cargo-ndk 使用的架构名称) +# ANDROID_TARGETS=("arm64-v8a" "armeabi-v7a" "x86" "x86_64") +ANDROID_TARGETS=("arm64-v8a") + +# Android 架构到 Rust target 的映射 +declare -A TARGET_MAP +TARGET_MAP["arm64-v8a"]="aarch64-linux-android" +TARGET_MAP["armeabi-v7a"]="armv7-linux-androideabi" +TARGET_MAP["x86"]="i686-linux-android" +TARGET_MAP["x86_64"]="x86_64-linux-android" + +# 检查并安装所需的 Rust target +echo -e "${YELLOW}检查并安装 Android 目标架构...${NC}" +for android_target in "${ANDROID_TARGETS[@]}"; do + rust_target="${TARGET_MAP[$android_target]}" + if ! rustup target list --installed | grep -q "$rust_target"; then + echo -e "${YELLOW}安装目标架构: $rust_target (for $android_target)${NC}" + rustup target add "$rust_target" else - echo -e "${GREEN}目标架构已安装: $target${NC}" + echo -e "${GREEN}目标架构已安装: $rust_target (for $android_target)${NC}" fi done @@ -49,66 +70,45 @@ mkdir -p "$OUTPUT_DIR" # 构建函数 build_for_target() { - local target=$1 - echo -e "${YELLOW}构建目标: $target${NC}" - - # 设置环境变量 - export CC_aarch64_linux_android="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang" - export CC_armv7_linux_androideabi="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang" - export CC_i686_linux_android="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang" - export CC_x86_64_linux_android="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang" + local android_target=$1 + echo -e "${YELLOW}构建目标: $android_target${NC}" # 首先构建 easytier-ffi - echo -e "${YELLOW}构建 easytier-ffi for $target${NC}" - (cd $REPO_ROOT/easytier-contrib/easytier-ffi && cargo build --target="$target" --release) - - # 设置链接器环境变量 - export RUSTFLAGS="-L $(readlink -f $REPO_ROOT/target/$target/release) -l easytier_ffi" - echo $RUSTFLAGS + echo -e "${YELLOW}构建 easytier-ffi for $android_target${NC}" + (cd $REPO_ROOT/easytier-contrib/easytier-ffi && cargo ndk -t $android_target build --release) # 构建 JNI 库 - cargo build --target="$target" --release + cargo ndk -t $android_target build --release # 复制库文件到输出目录 - local arch_dir - case $target in - "aarch64-linux-android") - arch_dir="arm64-v8a" - ;; - "armv7-linux-androideabi") - arch_dir="armeabi-v7a" - ;; - "i686-linux-android") - arch_dir="x86" - ;; - "x86_64-linux-android") - arch_dir="x86_64" - ;; - esac - - mkdir -p "$OUTPUT_DIR/$arch_dir" - cp "$REPO_ROOT/target/$target/release/libeasytier_android_jni.so" "$OUTPUT_DIR/$arch_dir/" - echo -e "${GREEN}库文件已复制到: $OUTPUT_DIR/$arch_dir/${NC}" + # cargo-ndk 使用 Rust target 名称作为目录名,而不是 Android 架构名称 + rust_target="${TARGET_MAP[$android_target]}" + mkdir -p "$OUTPUT_DIR/$android_target" + cp "$REPO_ROOT/target/$rust_target/release/libeasytier_android_jni.so" "$OUTPUT_DIR/$android_target/" + echo -e "${GREEN}库文件已复制到: $OUTPUT_DIR/$android_target/${NC}" } -# 检查 Android NDK -if [ -z "$ANDROID_NDK_ROOT" ]; then - echo -e "${RED}错误: 未设置 ANDROID_NDK_ROOT 环境变量${NC}" - echo "请设置 ANDROID_NDK_ROOT 指向您的 Android NDK 安装目录" - echo "例如: export ANDROID_NDK_ROOT=/path/to/android-ndk" - exit 1 +# 检查 Android NDK (cargo-ndk 会自动处理 NDK 路径) +if [ -z "$ANDROID_NDK_ROOT" ] && [ -z "$ANDROID_NDK_HOME" ] && [ -z "$NDK_HOME" ]; then + echo -e "${YELLOW}警告: 未设置 Android NDK 环境变量${NC}" + echo "cargo-ndk 将尝试自动检测 NDK 路径" + echo "如果构建失败,请设置以下环境变量之一:" + echo " - ANDROID_NDK_ROOT" + echo " - ANDROID_NDK_HOME" + echo " - NDK_HOME" +else + if [ -n "$ANDROID_NDK_ROOT" ]; then + echo -e "${GREEN}使用 Android NDK: $ANDROID_NDK_ROOT${NC}" + elif [ -n "$ANDROID_NDK_HOME" ]; then + echo -e "${GREEN}使用 Android NDK: $ANDROID_NDK_HOME${NC}" + elif [ -n "$NDK_HOME" ]; then + echo -e "${GREEN}使用 Android NDK: $NDK_HOME${NC}" + fi fi -if [ ! -d "$ANDROID_NDK_ROOT" ]; then - echo -e "${RED}错误: Android NDK 目录不存在: $ANDROID_NDK_ROOT${NC}" - exit 1 -fi - -echo -e "${GREEN}使用 Android NDK: $ANDROID_NDK_ROOT${NC}" - # 构建所有目标 echo -e "${YELLOW}开始构建所有目标架构...${NC}" -for target in "${TARGETS[@]}"; do +for target in "${ANDROID_TARGETS[@]}"; do build_for_target "$target" done @@ -122,4 +122,7 @@ echo "" echo -e "${YELLOW}使用说明:${NC}" echo "1. 将生成的 .so 文件复制到您的 Android 项目的 src/main/jniLibs/ 目录下" echo "2. 将 java/com/easytier/jni/EasyTierJNI.java 复制到您的 Android 项目中" -echo "3. 在您的 Android 代码中调用 EasyTierJNI 类的方法" \ No newline at end of file +echo "3. 在您的 Android 代码中调用 EasyTierJNI 类的方法" +echo "" +echo -e "${GREEN}注意: 此脚本使用 cargo-ndk 工具,无需手动设置复杂的环境变量${NC}" +echo -e "${GREEN}cargo-ndk 会自动处理交叉编译所需的工具链配置${NC}"