📒 MNN Chat Android App 构建笔记

一、背景知识

  1. MNN 简介

    • MNN 是阿里开源的轻量级深度学习框架,支持 Android / iOS / Linux / Windows。
    • 提供推理、LLM、Vision、Audio 等模块。
    • Android App 里用到的是 Java + JNI 调用 MNN 库
  2. CMake + NDK 的作用

    • CMake:跨平台构建工具,用于生成工程文件(Makefile / Ninja)。
    • NDK:Android 原生开发工具包,提供交叉编译环境,把 C++ 源码编译成 .so 库。
    • Gradle:Android Studio 的构建系统,最终把 .so 打包到 APK。
  3. 构建的两部分

    • MNN 主库 (libMNN.so):用 CMake + NDK 编译。
    • MnnLlmChat App:用 Android Studio (Gradle) 构建,依赖上面生成的 libMNN.so

二、官方推荐步骤

MNN 官方文档的流程(apps/Android/MnnLlmChat/README.md 里给出):

  1. 编译 MNN 主库

    cd project/android
    mkdir build_64
    ../build_64.sh "-DMNN_BUILD_LLM=true -DMNN_OPENCL=true ..."
    make install
    
    • 输出:libMNN.so
  2. 打开 Android App 工程

    • 路径:apps/Android/MnnLlmChat/
    • 用 Android Studio 打开,Gradle 会自动拉依赖。
    • 连接 Android 手机,运行 Run app

三、我的操作过程

1. 初次尝试:跟随官方步骤

cd project/android
mkdir build_64
../build_64.sh "-DMNN_BUILD_LLM=true ..."
make install

❌ 报错:

Could not find toolchain file: D:/Git/build/cmake/android.toolchain.cmake
CMake Error: CMAKE_C_COMPILER not set

原因

  • 系统环境找不到 Android NDK 的路径(脚本默认路径不对)。
  • Windows 下 make 也不可用。

2. 修改后尝试:手动 CMake

export ANDROID_NDK=/d/sdk/ndk/27.2.12479018
cmake .. -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake ...

❌ 报错:

The source directory "project/android" does not appear to contain CMakeLists.txt

原因

  • project/android 目录下运行,但 CMakeLists.txt项目根目录

3. 正确构建方式

cd /g/down/MNN-master/MNN-master
mkdir -p build_64
cd build_64

cmake .. -G Ninja \
  -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
  -DANDROID_ABI=arm64-v8a \
  -DANDROID_PLATFORM=android-33 \
  -DMNN_BUILD_LLM=true \
  -DMNN_OPENCL=true \
  -DMNN_ARM82=true \
  -DMNN_USE_LOGCAT=true \
  -DMNN_BUILD_OPENCV=true \
  -DLLM_SUPPORT_VISION=true \
  -DLLM_SUPPORT_AUDIO=true

ninja install

✅ 成功输出:build_64/lib/libMNN.so


4. Android Studio 部分

  • 打开 apps/Android/MnnLlmChat/
  • 等待 Gradle 下载依赖(可能比较慢,需要网络)
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

⚠️ 遇到的错误:

Unknown host 'repo.maven.apache.org'

原因:网络问题,无法下载依赖。
解决

  • 关掉 Gradle 的 offline mode
  • 确保网络能访问 repo.maven.apache.org(必要时开代理)

后续 Gradle 下载 kotlin-compiler-embeddable 包时:

Downloading kotlin-compiler-embeddable-2.1.21.jar (56MB)

这是 正常的依赖下载过程


四、报错与解决总结

步骤 报错 原因 解决
build_64.sh 找不到 toolchain.cmake 默认路径不对 设置 ANDROID_NDK 环境变量
cmake … 没有 CMakeLists.txt 路径选错 必须在 项目根目录 执行
make 找不到 make Windows 下没有 GNU Make Ninja
Gradle sync Unknown host 网络问题 配置代理,关闭 offline mode
Gradle build kotlin-compiler 下载很慢 包很大 (56MB) 等待即可

五、最终全流程总结

  1. 准备环境

    • Android NDK: D:\sdk\ndk\27.2.12479018
    • CMake: D:\sdk\cmake\3.22.1\bin
    • Ninja: 已安装 (ninja --version 正常)
  2. 编译 MNN 主库

    cd /g/down/MNN-master/MNN-master
    mkdir -p build_64 && cd build_64
    
    cmake .. -G Ninja \
      -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
      -DANDROID_ABI=arm64-v8a \
      -DANDROID_PLATFORM=android-33 \
      -DMNN_BUILD_LLM=true \
      -DMNN_OPENCL=true \
      -DMNN_ARM82=true \
      -DMNN_USE_LOGCAT=true \
      -DMNN_BUILD_OPENCV=true \
      -DLLM_SUPPORT_VISION=true \
      -DLLM_SUPPORT_AUDIO=true
    
    ninja install
    

在这里插入图片描述
最后失败了
在这里插入图片描述
遇到的是 链接阶段报错,编译 .o 文件都成功了,但是在 生成可执行文件 时失败了:

clang++: error: linker command failed with exit code 1
ninja: build stopped: subcommand failed.

结合日志可以看到,它失败的位置大概在这里:

[748/766] Linking CXX executable OpenCLProgramBuildTest.out
...
[756/766] Linking CXX executable timeProfile.out

为什么会失败?

MNN 的 CMakeLists.txt 默认会编译很多 测试用的可执行文件(比如 timeProfile.out, testModel.out,这些都是 PC/Linux 下测试 MNN 用的,不是 Android 必须的)。

但是我现在的目标是 交叉编译到 Android,这些可执行文件在 Android NDK 下是没法正常链接的(因为它们需要 main(),还依赖 host 库),所以链接失败。


✅ 解决方法

只需要 构建 so 库,而不是这些测试程序。

在 CMake 配置时加上:

-DBUILD_TEST=OFF -DMNN_BUILD_TEST=OFF

完整命令变成:

cmake .. -G Ninja \
  -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
  -DANDROID_ABI=arm64-v8a \
  -DANDROID_PLATFORM=android-33 \
  -DMNN_LOW_MEMORY=true \
  -DMNN_CPU_WEIGHT_DEQUANT_GEMM=true \
  -DMNN_BUILD_LLM=true \
  -DMNN_SUPPORT_TRANSFORMER_FUSE=true \
  -DMNN_ARM82=true \
  -DMNN_USE_LOGCAT=true \
  -DMNN_OPENCL=true \
  -DLLM_SUPPORT_VISION=true \
  -DMNN_BUILD_OPENCV=true \
  -DBUILD_TEST=OFF \
  -DMNN_BUILD_TEST=OFF

然后重新执行:

ninja install

在这里插入图片描述

编译结果

这样就不会去编译那些 xxxTest.outxxxProfile.out,只会输出核心库:

  • build_64/lib/libMNN.so
  • build_64/lib/libMNN_Express.so

这些 .so 文件才是在 Android App 里要用的。
在这里插入图片描述


  1. 构建 Android App

    • 打开 apps/Android/MnnLlmChat/
    • Gradle 自动拉依赖(需要联网)
    • 连接手机,点击 Run
      在这里插入图片描述遇到的错误是典型的 Android Studio + CMake/Ninja 找不到预编译的 libMNN.so 错误:
ninja: error: '../../../../../../../../project/android/build_64/lib/libMNN.so', 
needed by '.../libmnn_tts.so', missing and no known rule to make it

意思是:

  1. libmnn_tts.so 依赖 libMNN.so
  2. Ninja/Gradle 想在路径 project/android/build_64/lib/libMNN.so 找到它,但实际没有
  3. 因为 CMake 没有生成 .so 或者生成路径不对,所以报错。

🔑 原因分析

  1. 可能没有把 MNN 编译成 Android 库(或者编译失败了,参考你之前的链接报错)。
  2. 或者 CMake 输出路径不对,默认可能在 build_64/lib/build_64/install/lib/
  3. 或者测试程序编译失败导致 Ninja 中断,所以 .so 没生成。

✅ 解决方案

1️⃣ 重新配置 CMake,只生成 Android 库

project/android/build_64 里:

cmake .. -G Ninja \
  -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
  -DANDROID_ABI=arm64-v8a \
  -DANDROID_PLATFORM=android-33 \
  -DMNN_LOW_MEMORY=true \
  -DMNN_CPU_WEIGHT_DEQUANT_GEMM=true \
  -DMNN_BUILD_LLM=true \
  -DMNN_SUPPORT_TRANSFORMER_FUSE=true \
  -DMNN_ARM82=true \
  -DMNN_USE_LOGCAT=true \
  -DMNN_OPENCL=true \
  -DLLM_SUPPORT_VISION=true \
  -DMNN_BUILD_OPENCV=true \
  -DBUILD_TEST=OFF \
  -DMNN_BUILD_TEST=OFF

重点:BUILD_TEST=OFF + MNN_BUILD_TEST=OFF 确保不会去编译 PC 测试程序导致中断。
在这里插入图片描述

2️⃣ 编译安装
ninja install

在这里插入图片描述
遇到的错误是 LLM 模块在编译 Android 共享库 libllm.so 时链接失败,报错信息:

undefined symbol: MNN::CV::imread(std::__ndk1::basic_string<char, ...> const&, int)
referenced by omni.cpp:557
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐