#!/bin/bash # MNN 统一构建脚本 # 支持构建 Android、iOS、鸿蒙和 Python 版本的 MNN set -e # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 默认配置 BUILD_ANDROID=false BUILD_IOS=false BUILD_PYTHON=false BUILD_IOS_SIMULATOR=false BUILD_HARMONY=false ANDROID_NDK="" HARMONY_HOME="" OUTPUT_DIR="mnn_builds" CLEAN_BUILD=true VERSION="" PYTHON_CMD="python3" DEPS_OPTIONS="" # 获取项目根目录 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$SCRIPT_DIR" print_usage() { echo "MNN 统一构建脚本" echo "" echo "用法: $0 [选项]" echo "" echo "构建目标:" echo " --android 构建 Android 版本 (需要 --ndk)" echo " --ios 构建 iOS 真机版本 (arm64)" echo " --ios-simulator 构建 iOS 模拟器版本 (x86_64 + arm64)" echo " --harmony 构建鸿蒙版本 (需要 --harmony-home 或设置 HARMONY_HOME)" echo " --python 构建 Python 版本" echo "" echo "Android 选项:" echo " --ndk PATH Android NDK 路径 (例如: ~/Library/Android/sdk/ndk/29.0.13599879)" echo "" echo "鸿蒙选项:" echo " --harmony-home PATH 鸿蒙工具链路径 (例如: ~/Library/OpenHarmony/Sdk/native)" echo " 如果未指定,将优先查找 ~/Library/OpenHarmony/Sdk/native" echo "" echo "Python 选项:" echo " --python-deps OPTIONS Python 依赖选项,多个用逗号分隔" echo " 可用选项: llm,opencl,cuda,torch,render,vulkan,internal,no_sse,openmp" echo " --python-cmd CMD Python 命令 (默认: python3)" echo "" echo "通用选项:" echo " -o, --output DIR 输出目录 (默认: mnn_builds)" echo " -v, --version VERSION 版本号 (默认: 自动从源码读取)" echo " --no-clean 不清理之前的构建目录" echo " -h, --help 显示帮助信息" echo "" echo "示例:" echo " # 构建所有平台" echo " $0 --android --ios --harmony --python --ndk ~/Library/Android/sdk/ndk/29.0.13599879" echo "" echo " # 仅构建 Android" echo " $0 --android --ndk ~/Library/Android/sdk/ndk/29.0.13599879" echo "" echo " # 构建鸿蒙版本" echo " $0 --harmony --harmony-home ~/Library/OpenHarmony/Sdk/native" echo "" echo " # 构建 iOS 真机和模拟器" echo " $0 --ios --ios-simulator" echo "" echo " # 构建 Python (带 LLM 支持)" echo " $0 --python --python-deps llm,opencl" } # 解析命令行参数 while [[ $# -gt 0 ]]; do case $1 in --android) BUILD_ANDROID=true shift ;; --ios) BUILD_IOS=true shift ;; --ios-simulator) BUILD_IOS_SIMULATOR=true shift ;; --python) BUILD_PYTHON=true shift ;; --harmony) BUILD_HARMONY=true shift ;; --ndk) ANDROID_NDK="$2" shift 2 ;; --harmony-home) HARMONY_HOME="$2" shift 2 ;; --python-deps) DEPS_OPTIONS="$2" shift 2 ;; --python-cmd) PYTHON_CMD="$2" shift 2 ;; -o|--output) OUTPUT_DIR="$2" shift 2 ;; -v|--version) VERSION="$2" shift 2 ;; --no-clean) CLEAN_BUILD=false shift ;; -h|--help) print_usage exit 0 ;; *) echo -e "${RED}错误: 未知选项 $1${NC}" print_usage exit 1 ;; esac done # 检查是否至少选择了一个构建目标 if [ "$BUILD_ANDROID" = false ] && [ "$BUILD_IOS" = false ] && [ "$BUILD_IOS_SIMULATOR" = false ] && [ "$BUILD_HARMONY" = false ] && [ "$BUILD_PYTHON" = false ]; then echo -e "${RED}错误: 请至少选择一个构建目标 (--android, --ios, --ios-simulator, --harmony, 或 --python)${NC}" print_usage exit 1 fi # 检查 Android NDK if [ "$BUILD_ANDROID" = true ]; then if [ -z "$ANDROID_NDK" ]; then echo -e "${RED}错误: 构建 Android 必须指定 NDK 路径 (使用 --ndk)${NC}" echo -e "${RED}示例: $0 --android --ndk ~/Library/Android/sdk/ndk/29.0.13599879${NC}" exit 1 fi # 展开路径中的 ~ ANDROID_NDK="${ANDROID_NDK/#\~/$HOME}" if [ ! -d "$ANDROID_NDK" ]; then echo -e "${RED}错误: NDK 路径不存在: $ANDROID_NDK${NC}" exit 1 fi fi # 查找鸿蒙工具链的函数 find_harmony_toolchain() { # 如果环境变量已设置,优先使用 if [ -n "$HARMONY_HOME" ]; then # 支持两种路径格式:直接指定或带 native 子目录 if [ -f "$HARMONY_HOME/build/cmake/ohos.toolchain.cmake" ]; then echo "$HARMONY_HOME" return 0 elif [ -f "$HARMONY_HOME/native/build/cmake/ohos.toolchain.cmake" ]; then echo "$HARMONY_HOME" return 0 fi fi # 优先查找 ~/Library/OpenHarmony/Sdk,支持版本号目录 local sdk_base="$HOME/Library/OpenHarmony/Sdk" if [ -d "$sdk_base" ]; then # 查找所有版本号目录下的 native 或 toolchains # 按版本号倒序排列,优先使用最新版本 for version_dir in $(ls -d "$sdk_base"/* 2>/dev/null | sort -Vr); do if [ -d "$version_dir" ]; then # 尝试 native/build/cmake/ohos.toolchain.cmake if [ -f "$version_dir/native/build/cmake/ohos.toolchain.cmake" ]; then echo "$version_dir/native" return 0 fi # 尝试 build/cmake/ohos.toolchain.cmake if [ -f "$version_dir/build/cmake/ohos.toolchain.cmake" ]; then echo "$version_dir" return 0 fi fi done fi # 其他可能的路径 local possible_paths=( "$HOME/Library/OpenHarmony/Sdk/native" "$HOME/HarmonyOS/Sdk/native" "$HOME/.ohos/native" "/opt/HarmonyOS/Sdk/native" "/usr/local/HarmonyOS/Sdk/native" "$HOME/Library/HarmonyOS/Sdk/native" ) # 尝试查找 for path in "${possible_paths[@]}"; do if [ -n "$path" ] && [ -f "$path/build/cmake/ohos.toolchain.cmake" ]; then echo "$path" return 0 fi done # 限制搜索范围,只在 OpenHarmony/Sdk 目录下快速查找 # 避免在整个 OpenHarmony 目录下递归查找,这可能会很慢 local found=$(find "$HOME/Library/OpenHarmony/Sdk" -maxdepth 4 -type f -name "ohos.toolchain.cmake" 2>/dev/null | head -1) if [ -n "$found" ]; then # 从 ohos.toolchain.cmake 向上查找 native 目录或 SDK 根目录 found=$(dirname "$found") if [ "$(basename "$found")" = "cmake" ]; then found=$(dirname "$found") if [ "$(basename "$found")" = "build" ]; then found=$(dirname "$found") fi fi echo "$found" return 0 fi return 1 } # 检查鸿蒙工具链 if [ "$BUILD_HARMONY" = true ]; then # 展开路径中的 ~ if [ -n "$HARMONY_HOME" ]; then HARMONY_HOME="${HARMONY_HOME/#\~/$HOME}" fi # 尝试查找工具链 if [ -z "$HARMONY_HOME" ] || [ ! -f "$HARMONY_HOME/build/cmake/ohos.toolchain.cmake" ]; then # 检查是否在 native 子目录下 if [ -n "$HARMONY_HOME" ] && [ -f "$HARMONY_HOME/native/build/cmake/ohos.toolchain.cmake" ]; then HARMONY_HOME="$HARMONY_HOME/native" else echo -e "${YELLOW}正在查找鸿蒙工具链...${NC}" HARMONY_HOME=$(find_harmony_toolchain) if [ -z "$HARMONY_HOME" ]; then echo -e "${RED}错误: 找不到鸿蒙工具链${NC}" echo -e "${RED}默认查找路径: ~/Library/OpenHarmony/Sdk/*/native${NC}" echo -e "${RED}请使用 --harmony-home 指定路径,或设置 HARMONY_HOME 环境变量${NC}" echo -e "${RED}工具链文件应位于: /build/cmake/ohos.toolchain.cmake 或 /native/build/cmake/ohos.toolchain.cmake${NC}" exit 1 fi # 如果找到的是带 native 的路径,需要调整 if [ -f "$HARMONY_HOME/native/build/cmake/ohos.toolchain.cmake" ]; then HARMONY_HOME="$HARMONY_HOME/native" fi fi echo -e "${GREEN}找到鸿蒙工具链: $HARMONY_HOME${NC}" fi # 验证工具链文件存在 if [ ! -f "$HARMONY_HOME/build/cmake/ohos.toolchain.cmake" ]; then echo -e "${RED}错误: 鸿蒙工具链文件不存在: $HARMONY_HOME/build/cmake/ohos.toolchain.cmake${NC}" exit 1 fi fi echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}MNN 统一构建脚本${NC}" echo -e "${GREEN}========================================${NC}" echo "项目根目录: $PROJECT_ROOT" echo "输出目录: $OUTPUT_DIR" echo "" echo -e "${BLUE}构建目标:${NC}" [ "$BUILD_ANDROID" = true ] && echo " ✓ Android" [ "$BUILD_IOS" = true ] && echo " ✓ iOS (真机 arm64)" [ "$BUILD_IOS_SIMULATOR" = true ] && echo " ✓ iOS (模拟器 x86_64 + arm64)" [ "$BUILD_HARMONY" = true ] && echo " ✓ 鸿蒙 (arm64-v8a)" [ "$BUILD_PYTHON" = true ] && echo " ✓ Python" echo "" cd "$PROJECT_ROOT" mkdir -p "$OUTPUT_DIR" # ============================================================================ # 构建 Android 版本 # ============================================================================ if [ "$BUILD_ANDROID" = true ]; then echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}开始构建 Android 版本${NC}" echo -e "${GREEN}========================================${NC}" export ANDROID_NDK ANDROID_BUILD_DIR="project/android" ANDROID_OUTPUT_DIR="$OUTPUT_DIR/android" cd "$ANDROID_BUILD_DIR" # 清理 if [ "$CLEAN_BUILD" = true ]; then echo -e "${YELLOW}清理之前的 Android 构建...${NC}" rm -rf build_32 build_64 export fi # 在项目根目录创建输出目录 mkdir -p "$PROJECT_ROOT/$ANDROID_OUTPUT_DIR" # 构建 armeabi-v7a echo -e "${BLUE}构建 armeabi-v7a...${NC}" mkdir -p build_32 cd build_32 cmake ../../../ \ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ -DCMAKE_BUILD_TYPE=Release \ -DANDROID_ABI="armeabi-v7a" \ -DANDROID_STL=c++_static \ -DANDROID_NATIVE_API_LEVEL=android-14 \ -DANDROID_TOOLCHAIN=clang \ -DMNN_USE_LOGCAT=false \ -DMNN_USE_SSE=OFF \ -DMNN_BUILD_TEST=ON \ -DMNN_ARM82=OFF \ -DMNN_LOW_MEMORY=ON \ -DMNN_SUPPORT_TRANSFORMER_FUSE=ON \ -DMNN_BUILD_LLM=ON \ -DMNN_BUILD_DIFFUSION=ON \ -DMNN_OPENCL=OFF \ -DMNN_SEP_BUILD=OFF \ -DLLM_SUPPORT_AUDIO=ON \ -DMNN_BUILD_AUDIO=ON \ -DLLM_SUPPORT_VISION=ON \ -DMNN_BUILD_OPENCV=ON \ -DMNN_IMGCODECS=ON \ -DMNN_BUILD_FOR_ANDROID_COMMAND=true \ -DNATIVE_LIBRARY_OUTPUT=. \ -DNATIVE_INCLUDE_OUTPUT=. \ > /dev/null make -j4 MNN > /dev/null cd .. # 构建 arm64-v8a echo -e "${BLUE}构建 arm64-v8a...${NC}" mkdir -p build_64 cd build_64 cmake ../../../ \ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ -DCMAKE_BUILD_TYPE=Release \ -DANDROID_ABI="arm64-v8a" \ -DANDROID_STL=c++_static \ -DANDROID_NATIVE_API_LEVEL=android-21 \ -DANDROID_TOOLCHAIN=clang \ -DMNN_USE_LOGCAT=false \ -DMNN_BUILD_BENCHMARK=ON \ -DMNN_USE_SSE=OFF \ -DMNN_BUILD_TEST=ON \ -DMNN_ARM82=ON \ -DMNN_LOW_MEMORY=ON \ -DMNN_SUPPORT_TRANSFORMER_FUSE=ON \ -DMNN_BUILD_LLM=ON \ -DMNN_BUILD_DIFFUSION=ON \ -DMNN_OPENCL=OFF \ -DMNN_SEP_BUILD=OFF \ -DLLM_SUPPORT_AUDIO=ON \ -DMNN_BUILD_AUDIO=ON \ -DLLM_SUPPORT_VISION=ON \ -DMNN_BUILD_OPENCV=ON \ -DMNN_IMGCODECS=ON \ -DMNN_BUILD_FOR_ANDROID_COMMAND=true \ -DNATIVE_LIBRARY_OUTPUT=. \ -DNATIVE_INCLUDE_OUTPUT=. \ > /dev/null make -j4 MNN > /dev/null cd .. # 导出文件 echo -e "${BLUE}导出 Android 库文件...${NC}" mkdir -p export/android/{armeabi-v7a,arm64-v8a}/libs export/android/include/MNN cp build_32/*.so export/android/armeabi-v7a/libs/ 2>/dev/null || true cp build_64/*.so export/android/arm64-v8a/libs/ 2>/dev/null || true cp -r ../../include/MNN/* export/android/include/MNN/ # 复制到统一输出目录 # 如果目标路径存在但不是目录,先删除 if [ -e "$PROJECT_ROOT/$ANDROID_OUTPUT_DIR" ] && [ ! -d "$PROJECT_ROOT/$ANDROID_OUTPUT_DIR" ]; then rm -f "$PROJECT_ROOT/$ANDROID_OUTPUT_DIR" fi mkdir -p "$PROJECT_ROOT/$ANDROID_OUTPUT_DIR" cp -r export/android/* "$PROJECT_ROOT/$ANDROID_OUTPUT_DIR/" echo -e "${GREEN}Android 构建完成!${NC}" echo "输出位置: $ANDROID_OUTPUT_DIR" cd "$PROJECT_ROOT" fi # ============================================================================ # 构建 iOS 真机版本 # ============================================================================ if [ "$BUILD_IOS" = true ]; then echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}开始构建 iOS 真机版本${NC}" echo -e "${GREEN}========================================${NC}" # 检查是否在 macOS 上 if [[ "$OSTYPE" != "darwin"* ]]; then echo -e "${RED}错误: iOS 构建只能在 macOS 上执行${NC}" exit 1 fi # 检查 Xcode if ! command -v xcodebuild &> /dev/null; then echo -e "${RED}错误: 找不到 Xcode,请先安装 Xcode${NC}" exit 1 fi IOS_BUILD_DIR="project/ios" IOS_OUTPUT_DIR="$OUTPUT_DIR/ios/device" cd "$IOS_BUILD_DIR" # 清理 if [ "$CLEAN_BUILD" = true ]; then echo -e "${YELLOW}清理之前的 iOS 真机构建...${NC}" rm -rf MNN-iOS-CPU-GPU/Static/ios_64 find "$PROJECT_ROOT" -name "CMakeCache.txt" -path "*/ios_64/*" 2>/dev/null | xargs rm -f 2>/dev/null || true fi mkdir -p MNN-iOS-CPU-GPU/Static cd MNN-iOS-CPU-GPU/Static # 构建真机版本 (arm64) echo -e "${BLUE}构建 iOS 真机版本 (arm64)...${NC}" rm -rf ios_64 mkdir ios_64 cd ios_64 cmake "$PROJECT_ROOT" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE=$PROJECT_ROOT/cmake/ios.toolchain.cmake \ -DENABLE_BITCODE=0 \ -DMNN_AAPL_FMWK=1 \ -DMNN_SEP_BUILD=OFF \ -DMNN_BUILD_SHARED_LIBS=false \ -DMNN_USE_THREAD_POOL=OFF \ -DPLATFORM=OS64 \ -DARCHS="arm64" \ -DMNN_ARM82=ON \ -DMNN_LOW_MEMORY=ON \ -DMNN_SUPPORT_TRANSFORMER_FUSE=ON \ -DMNN_BUILD_LLM=ON \ -DMNN_METAL=ON \ -DMNN_BUILD_DIFFUSION=ON \ -DMNN_OPENCL=OFF \ -DLLM_SUPPORT_AUDIO=ON \ -DMNN_BUILD_AUDIO=ON \ -DLLM_SUPPORT_VISION=ON \ -DMNN_BUILD_OPENCV=ON \ -DMNN_IMGCODECS=ON \ > /dev/null make MNN -j8 > /dev/null cd .. # 输出真机版本 mkdir -p "$PROJECT_ROOT/$IOS_OUTPUT_DIR" rm -rf "$PROJECT_ROOT/$IOS_OUTPUT_DIR/MNN.framework" cp -R ios_64/MNN.framework "$PROJECT_ROOT/$IOS_OUTPUT_DIR/" # 清理 rm -rf ios_64 echo -e "${GREEN}iOS 真机构建完成!${NC}" echo "输出位置: $IOS_OUTPUT_DIR/MNN.framework" cd "$PROJECT_ROOT" fi # ============================================================================ # 构建 iOS 模拟器版本 # ============================================================================ if [ "$BUILD_IOS_SIMULATOR" = true ]; then echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}开始构建 iOS 模拟器版本${NC}" echo -e "${GREEN}========================================${NC}" # 检查是否在 macOS 上 if [[ "$OSTYPE" != "darwin"* ]]; then echo -e "${RED}错误: iOS 构建只能在 macOS 上执行${NC}" exit 1 fi # 检查 Xcode if ! command -v xcodebuild &> /dev/null; then echo -e "${RED}错误: 找不到 Xcode,请先安装 Xcode${NC}" exit 1 fi IOS_BUILD_DIR="project/ios" IOS_OUTPUT_DIR="$OUTPUT_DIR/ios/simulator" cd "$IOS_BUILD_DIR" # 清理 if [ "$CLEAN_BUILD" = true ]; then echo -e "${YELLOW}清理之前的 iOS 模拟器构建...${NC}" rm -rf MNN-iOS-CPU-GPU/Static/ios_simulator* find "$PROJECT_ROOT" -name "CMakeCache.txt" -path "*/ios_simulator*/*" 2>/dev/null | xargs rm -f 2>/dev/null || true fi mkdir -p MNN-iOS-CPU-GPU/Static cd MNN-iOS-CPU-GPU/Static # 构建 x86_64 模拟器版本(尝试构建,失败则跳过) BUILD_X86_64=false echo -e "${BLUE}构建 iOS 模拟器版本 (x86_64)...${NC}" rm -rf ios_simulator_x86 mkdir ios_simulator_x86 cd ios_simulator_x86 if cmake "$PROJECT_ROOT" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE=$PROJECT_ROOT/cmake/ios.toolchain.cmake \ -DENABLE_BITCODE=0 \ -DMNN_AAPL_FMWK=1 \ -DMNN_SEP_BUILD=OFF \ -DMNN_BUILD_SHARED_LIBS=false \ -DMNN_USE_THREAD_POOL=OFF \ -DPLATFORM=SIMULATOR64 \ -DARCHS="x86_64" \ -DMNN_ARM82=OFF \ -DMNN_LOW_MEMORY=ON \ -DMNN_SUPPORT_TRANSFORMER_FUSE=ON \ -DMNN_BUILD_LLM=ON \ -DMNN_METAL=OFF \ -DMNN_BUILD_DIFFUSION=ON \ -DMNN_OPENCL=OFF \ -DLLM_SUPPORT_AUDIO=ON \ -DMNN_BUILD_AUDIO=ON \ -DLLM_SUPPORT_VISION=ON \ -DMNN_BUILD_OPENCV=ON \ -DMNN_IMGCODECS=ON \ && make MNN -j8; then if [ -f "MNN.framework/MNN" ]; then BUILD_X86_64=true echo -e "${GREEN}x86_64 模拟器构建成功${NC}" cd .. else echo -e "${YELLOW}警告: x86_64 模拟器构建产物不存在,跳过此架构${NC}" cd .. rm -rf ios_simulator_x86 fi else echo -e "${YELLOW}警告: x86_64 模拟器构建失败,跳过此架构(这在 Apple Silicon Mac 上是正常的)${NC}" cd .. rm -rf ios_simulator_x86 fi # 构建 arm64 模拟器版本 echo -e "${BLUE}构建 iOS 模拟器版本 (arm64)...${NC}" rm -rf ios_simulator_arm64 mkdir ios_simulator_arm64 cd ios_simulator_arm64 if ! cmake "$PROJECT_ROOT" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE=$PROJECT_ROOT/cmake/ios.toolchain.cmake \ -DENABLE_BITCODE=0 \ -DMNN_AAPL_FMWK=1 \ -DMNN_SEP_BUILD=OFF \ -DMNN_BUILD_SHARED_LIBS=false \ -DMNN_USE_THREAD_POOL=OFF \ -DPLATFORM=SIMULATOR64 \ -DARCHS="arm64" \ -DMNN_ARM82=ON \ -DMNN_LOW_MEMORY=ON \ -DMNN_SUPPORT_TRANSFORMER_FUSE=ON \ -DMNN_BUILD_LLM=ON \ -DMNN_METAL=OFF \ -DMNN_BUILD_DIFFUSION=ON \ -DMNN_OPENCL=OFF \ -DLLM_SUPPORT_AUDIO=ON \ -DMNN_BUILD_AUDIO=ON \ -DLLM_SUPPORT_VISION=ON \ -DMNN_BUILD_OPENCV=ON \ -DMNN_IMGCODECS=ON; then echo -e "${RED}错误: arm64 模拟器 cmake 配置失败${NC}" cd "$PROJECT_ROOT" exit 1 fi if ! make MNN -j8; then echo -e "${RED}错误: arm64 模拟器编译失败${NC}" cd "$PROJECT_ROOT" exit 1 fi cd .. # 验证构建产物 if [ ! -f "ios_simulator_arm64/MNN.framework/MNN" ]; then echo -e "${RED}错误: 未找到 arm64 模拟器框架文件${NC}" cd "$PROJECT_ROOT" exit 1 fi # 合并模拟器架构 echo -e "${BLUE}合并模拟器架构...${NC}" rm -rf ios_simulator mkdir ios_simulator if [ "$BUILD_X86_64" = true ] && [ -f "ios_simulator_x86/MNN.framework/MNN" ]; then # 合并 x86_64 + arm64 echo -e "${BLUE}合并 x86_64 + arm64 架构...${NC}" cp -R ios_simulator_x86/MNN.framework ios_simulator/MNN.framework mv ios_simulator/MNN.framework/MNN ios_simulator/MNN.framework/MNN_x86 if ! lipo -create ios_simulator/MNN.framework/MNN_x86 ios_simulator_arm64/MNN.framework/MNN -output ios_simulator/MNN.framework/MNN; then echo -e "${RED}错误: 合并架构失败${NC}" cd "$PROJECT_ROOT" exit 1 fi rm ios_simulator/MNN.framework/MNN_x86 else # 仅使用 arm64 echo -e "${BLUE}仅使用 arm64 架构(x86_64 不可用)...${NC}" cp -R ios_simulator_arm64/MNN.framework ios_simulator/MNN.framework fi # 输出模拟器版本 mkdir -p "$PROJECT_ROOT/$IOS_OUTPUT_DIR" rm -rf "$PROJECT_ROOT/$IOS_OUTPUT_DIR/MNN.framework" cp -R ios_simulator/MNN.framework "$PROJECT_ROOT/$IOS_OUTPUT_DIR/" # 清理临时目录 rm -rf ios_simulator ios_simulator_x86 ios_simulator_arm64 echo -e "${GREEN}iOS 模拟器构建完成!${NC}" echo "输出位置: $IOS_OUTPUT_DIR/MNN.framework" cd "$PROJECT_ROOT" fi # ============================================================================ # 构建鸿蒙版本 # ============================================================================ if [ "$BUILD_HARMONY" = true ]; then echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}开始构建鸿蒙版本${NC}" echo -e "${GREEN}========================================${NC}" export HARMONY_HOME HARMONY_BUILD_DIR="project/harmony" HARMONY_OUTPUT_DIR="$OUTPUT_DIR/harmony" cd "$HARMONY_BUILD_DIR" # 清理 if [ "$CLEAN_BUILD" = true ]; then echo -e "${YELLOW}清理之前的鸿蒙构建...${NC}" rm -rf build_64 export fi # 在项目根目录创建输出目录 mkdir -p "$PROJECT_ROOT/$HARMONY_OUTPUT_DIR" # 构建 arm64-v8a echo -e "${BLUE}构建 arm64-v8a...${NC}" mkdir -p build_64 cd build_64 cmake "$PROJECT_ROOT" \ -DCMAKE_TOOLCHAIN_FILE=$HARMONY_HOME/build/cmake/ohos.toolchain.cmake \ -DCMAKE_BUILD_TYPE=Release \ -DOHOS_ARCH="arm64-v8a" \ -DOHOS_STL=c++_static \ -DMNN_USE_LOGCAT=true \ -DMNN_BUILD_BENCHMARK=ON \ -DMNN_USE_SSE=OFF \ -DMNN_SUPPORT_BF16=OFF \ -DMNN_BUILD_TEST=ON \ -DMNN_ARM82=ON \ -DMNN_LOW_MEMORY=ON \ -DMNN_SUPPORT_TRANSFORMER_FUSE=ON \ -DMNN_BUILD_LLM=ON \ -DMNN_BUILD_DIFFUSION=ON \ -DMNN_OPENCL=OFF \ -DMNN_SEP_BUILD=OFF \ -DLLM_SUPPORT_AUDIO=ON \ -DMNN_BUILD_AUDIO=ON \ -DLLM_SUPPORT_VISION=ON \ -DMNN_BUILD_OPENCV=ON \ -DMNN_IMGCODECS=ON \ -DOHOS_PLATFORM_LEVEL=9 \ -DNATIVE_LIBRARY_OUTPUT=. \ -DNATIVE_INCLUDE_OUTPUT=. \ > /dev/null make -j4 MNN > /dev/null cd .. # 导出文件 echo -e "${BLUE}导出鸿蒙库文件...${NC}" mkdir -p export/harmony/arm64-v8a/libs export/harmony/include/MNN cp build_64/*.so export/harmony/arm64-v8a/libs/ 2>/dev/null || true cp -r ../../include/MNN/* export/harmony/include/MNN/ # 复制到统一输出目录 # 如果目标路径存在但不是目录,先删除 if [ -e "$PROJECT_ROOT/$HARMONY_OUTPUT_DIR" ] && [ ! -d "$PROJECT_ROOT/$HARMONY_OUTPUT_DIR" ]; then rm -f "$PROJECT_ROOT/$HARMONY_OUTPUT_DIR" fi mkdir -p "$PROJECT_ROOT/$HARMONY_OUTPUT_DIR" cp -r export/harmony/* "$PROJECT_ROOT/$HARMONY_OUTPUT_DIR/" echo -e "${GREEN}鸿蒙构建完成!${NC}" echo "输出位置: $HARMONY_OUTPUT_DIR" cd "$PROJECT_ROOT" fi # ============================================================================ # 构建 Python 版本 # ============================================================================ if [ "$BUILD_PYTHON" = true ]; then echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}开始构建 Python 版本${NC}" echo -e "${GREEN}========================================${NC}" # 检查 Python if ! command -v $PYTHON_CMD &> /dev/null; then echo -e "${RED}错误: 找不到 Python 命令 '$PYTHON_CMD'${NC}" exit 1 fi PYTHON_OUTPUT_DIR="$OUTPUT_DIR/python" # 使用之前创建的 build_pymnn.sh 脚本 if [ -f "$PROJECT_ROOT/build_pymnn.sh" ]; then PYTHON_BUILD_ARGS="-o $PYTHON_OUTPUT_DIR" [ -n "$VERSION" ] && PYTHON_BUILD_ARGS="$PYTHON_BUILD_ARGS -v $VERSION" [ -n "$DEPS_OPTIONS" ] && PYTHON_BUILD_ARGS="$PYTHON_BUILD_ARGS -d $DEPS_OPTIONS" [ "$CLEAN_BUILD" = false ] && PYTHON_BUILD_ARGS="$PYTHON_BUILD_ARGS --no-clean" PYTHON_BUILD_ARGS="$PYTHON_BUILD_ARGS --python $PYTHON_CMD" bash "$PROJECT_ROOT/build_pymnn.sh" $PYTHON_BUILD_ARGS else echo -e "${YELLOW}警告: 未找到 build_pymnn.sh,使用基本构建方式...${NC}" cd pymnn/pip_package # 构建依赖 if [ -n "$DEPS_OPTIONS" ]; then $PYTHON_CMD build_deps.py $DEPS_OPTIONS else $PYTHON_CMD build_deps.py fi # 构建 wheel $PYTHON_CMD -m pip install -U numpy wheel setuptools --quiet rm -rf build dist BUILD_ARGS="" [ -n "$VERSION" ] && BUILD_ARGS="--version $VERSION" [ -n "$DEPS_OPTIONS" ] && BUILD_ARGS="$BUILD_ARGS --deps $DEPS_OPTIONS" $PYTHON_CMD setup.py bdist_wheel $BUILD_ARGS mkdir -p "$PROJECT_ROOT/$PYTHON_OUTPUT_DIR" cp dist/*.whl "$PROJECT_ROOT/$PYTHON_OUTPUT_DIR/" cd "$PROJECT_ROOT" fi echo -e "${GREEN}Python 构建完成!${NC}" echo "输出位置: $PYTHON_OUTPUT_DIR" fi # ============================================================================ # 总结 # ============================================================================ echo "" echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}所有构建完成!${NC}" echo -e "${GREEN}========================================${NC}" echo "" echo "输出目录: $PROJECT_ROOT/$OUTPUT_DIR" echo "" [ "$BUILD_ANDROID" = true ] && echo -e "${GREEN}Android:${NC} $OUTPUT_DIR/android" [ "$BUILD_IOS" = true ] && echo -e "${GREEN}iOS (真机):${NC} $OUTPUT_DIR/ios/device" [ "$BUILD_IOS_SIMULATOR" = true ] && echo -e "${GREEN}iOS (模拟器):${NC} $OUTPUT_DIR/ios/simulator" [ "$BUILD_HARMONY" = true ] && echo -e "${GREEN}鸿蒙:${NC} $OUTPUT_DIR/harmony" [ "$BUILD_PYTHON" = true ] && echo -e "${GREEN}Python:${NC} $OUTPUT_DIR/python" echo ""