📒 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_64cmake .. -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=trueninja 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找不到 makeWindows 下没有 GNU MakeNinja
Gradle syncUnknown host网络问题配置代理,关闭 offline mode
Gradle buildkotlin-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_64cmake .. -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=trueninja 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919749.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919749.shtml
英文地址,请注明出处:http://en.pswp.cn/news/919749.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Axios 中处理多个 baseURL 而不造成混乱

网罗开发&#xff08;小红书、快手、视频号同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

AP服务发现PRS_SOMEIPSD_00255 的解析

[PRS_SOMEIPSD_00255 ] 「SOME/IP-SD头部的重启标志&#xff0c;对于重启后发出的所有报文&#xff0c;都应设置为 1&#xff0c;直至 SOME/IP头部中的会话 ID (Session-ID) 回绕并因此再次从 1 开始。在此回绕之后&#xff0c;重启标志应设置为 0。」(RS_SOMEIPSD_00006)核心含…

纯手撸一个RAG

纯手撸一个RAGRAG基本流程第一阶段&#xff1a;数据预处理&#xff08;索引&#xff09; - 构建知识库第二阶段&#xff1a;查询与生成&#xff08;推理&#xff09; - 回答问题总结Chunk介绍Chunk框架的介绍Chunk核心概念选择分块策略和框架如何选择分块框架Python代码实现第一…

视觉语言对比学习的发展史:从CLIP、BLIP、BLIP2、InstructBLIP(含MiniGPT4的详解)

前言 本文一开始是属于此文《图像生成(AI绘画)的发展史&#xff1a;从CLIP、BLIP、InstructBLIP到DALLE、DALLE 2、DALLE 3、Stable Diffusion(含ControlNet详解)》的&#xff0c;后独立成本文 第一部分 从CLIP、BLIP1、BLIP2到InstructBLIP 1.1 CLIP&#xff1a;基于对比文本…

HTTP代理与SOCKS代理的区别、应用场景与选择指南

在互联网日常使用与跨境业务中&#xff0c;HTTP代理 和 SOCKS代理 是两种常见的网络代理方式。无论是跨境电商、社交媒体账号运营、数据采集&#xff0c;还是科学访问海外资源&#xff0c;都需要选择合适的代理协议。什么是HTTP代理&#xff1f;定义HTTP代理 是基于 HTTP协议 的…

AI重塑职业教育:个性化学习计划提效率、VR实操模拟强技能,对接就业新路径

职业教育长期面临着一系列问题&#xff0c;包括“统一课程难以适配不同基础学员”、“实操反馈滞后”和“就业技能与企业需求脱节”等。随着人工智能技术的应用&#xff0c;这些传统教学模式正在发生变化。个性化技能培养得以实现&#xff0c;甚至可以提前识别学员的就业短板。…

主题配色下的背景透明度

用 CSS color-mix() 解决背景透明度的痛点 在设计卡片组件时&#xff0c;经常遇到这样的需求&#xff1a;卡片背景需要80%透明度&#xff0c;鼠标悬浮在内部某项时&#xff0c;修改背景色但保持同样的透明度。 问题场景 .card {background: rgba(59, 130, 246, 0.8); /* 蓝色80…

【Python代码】谷歌专利CSV处理函数

以下是一个重构后的高可用、可配置、低耦合的专利CSV处理函数&#xff0c;包含清晰的注释和结构&#xff1a; import csv import pandas as pd from datetime import datetime import os from typing import List, Dict, Any, Optional, Tuple import logging# 配置日志 loggin…

3-2〔OSCP ◈ 研记〕❘ WEB应用攻击▸WEB安全防护体系

郑重声明&#xff1a; 本文所有安全知识与技术&#xff0c;仅用于探讨、研究及学习&#xff0c;严禁用于违反国家法律法规的非法活动。对于因不当使用相关内容造成的任何损失或法律责任&#xff0c;本人不承担任何责任。 如需转载&#xff0c;请注明出处且不得用于商业盈利。 …

PCIe 5.0相比顶级PCIe 4.0有何提升?

还在为PCIe 4.0固态硬盘那7000MB/s的速度沾沾自喜&#xff1f;醒醒&#xff0c;朋友。当很多人还在讨论PCIe 4.0是否“性能过剩”时&#xff0c;真正面向未来的PCIe 5.0已经带着碾压级的实力&#xff0c;来到了我们面前。这不是一次常规的“升级”&#xff0c;更不是英特尔式的…

23种设计模式——适配器模式(Adapter)​详解

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a; 设计模式 ✨特色专栏&#xff1a; 知识分享 &…

Vue3源码reactivity响应式篇之Reactive

概览 vue3中reactive用于将普通对象转换为响应式对象&#xff0c;它的实现原理是通过Proxy和Reflect来实现的。具体的实现文件参见packages\reactivity\src\reactive.ts。本文会介绍reactive的相关api如下&#xff1a; reactive&#xff1a;将普通对象转换为响应式对象readonly…

初识数据结构——Map和Set:哈希表与二叉搜索树的魔法对决

数据结构专栏 ⬅(click) 大家好&#xff01;我是你们的老朋友——想不明白的过度思考者&#xff01;今天我们要一起探索Java中两个神奇的数据结构&#xff1a;Map和Set&#xff01;准备好了吗&#xff1f;让我们开始这场魔法之旅吧&#xff01;&#x1f3a9; &#x1f3af; 先…

Unreal Engine UStaticMeshComponent

UnrealUnreal Engine - UStaticMeshComponent&#x1f3db; 定义&#x1f3db; 类继承⚡ 关键特性⚙️ 常见配置&#x1f6e0;️ 使用方法&#x1f4da; 在 C 中使用&#x1f4da; 在蓝图中使用&#x1f3ae; 典型应用场景&#x1f4da; 常见子类与用途&#x1f4dd; 小结Unrea…

demo 汽车之家(渲染-筛选-排序-模块抽离数据)

效果图展示&#xff1a;代码截图注释详情实现笔记总体目标&#xff08;按需求点对照代码&#xff09;数据模块化、整体渲染框架、筛选/排序的高亮与行为&#xff0c;全部已在 Index.ets CarData.ets 落地。下面按图片需求 2~4 点逐条总结&#xff0c;并给出关键代码定位与“为…

双重机器学习DML介绍

本文参考&#xff1a; [1]文心一言回答&#xff1b; 一、核心原理与数学框架 双重机器学习&#xff08;Double Machine Learning, DML&#xff09;由Chernozhukov等学者于2018年提出&#xff0c;是一种结合机器学习与传统计量经济学的因果推断框架。其核心目标是在高维数据和非…

【图像算法 - 21】慧眼识虫:基于深度学习与OpenCV的农田害虫智能识别系统

摘要&#xff1a; 在现代农业生产中&#xff0c;病虫害是影响作物产量和品质的关键因素之一。传统的害虫识别依赖人工巡查&#xff0c;效率低、成本高且易出错。本文将介绍如何利用深度学习与OpenCV构建一套高效的农田害虫智能识别系统。该系统能够自动识别10类常见农业害虫&a…

循环神经网络实战:GRU 对比 LSTM 的中文情感分析(三)

循环神经网络实战&#xff1a;GRU 对比 LSTM 的中文情感分析&#xff08;三&#xff09; 文章目录循环神经网络实战&#xff1a;GRU 对比 LSTM 的中文情感分析&#xff08;三&#xff09;前言数据准备&#xff08;与 LSTM 相同&#xff09;模型搭建&#xff08;GRU&#xff09;…

学习游戏制作记录(制作提示框以及使用键盘切换UI)8.21

1.制作装备提示框创建提示框&#xff0c;添加文本子对象&#xff0c;用来描述名称&#xff0c;类型以及属性加成挂载垂直分配组件和文本大小适配组件&#xff0c;这样图像会根据文本大小来调整自己创建UI_ItemTip脚本并挂载在文本框上&#xff1a;[SerializeField] private Tex…

chapter07_初始化和销毁方法

一、简介 一个Bean&#xff0c;在进行实例化之后&#xff0c;需要进行两种初始化 初始化属性&#xff0c;由PropertyValues进行赋值初始化方法&#xff0c;由ApplicationContext统一调用&#xff0c;例如加载配置文件 Bean的初始化与销毁&#xff0c;共有三种方式&#xff08;注…