NCNN 安装与部署:桌面编译、交叉编译与 Android 构建
NCNN 安装与部署:桌面编译、交叉编译与 Android 构建
桌面编译:验证与转换工具
- 装好 CMake 与 C++ 编译器(Linux 上是 g++ / clang++,Windows 上是 MSVC 或 MinGW);
- 拉取源码并初始化子模块;
- 建 build 目录,用 CMake 生成工程;
- 打开工具开关,编译出
onnx2ncnn、ncnnoptimize、ncnn2table、ncnn2int8; - 用官方示例模型跑一遍 benchmark,确认编译产物可用。
git clone https://github.com/Tencent/ncnn.git
cd ncnn
git submodule update --init
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release \
-DNCNN_VULKAN=OFF \
-DNCNN_BUILD_TOOLS=ON \
-DNCNN_BUILD_EXAMPLES=ON \
-DNCNN_BUILD_BENCHMARK=ON ..
cmake --build . -j$(nproc)
编译完成后,工具在 build/tools/,示例在 build/examples/。转模型只需要工具,端侧只需要 libncnn.a 与 include/ 下的头文件——把这两点分清楚,交叉编译时就不必把整个仓库搬过去。
Android 交叉编译
官方提供了 build-android.sh,前提是装好 Android NDK 并设置好环境变量。要点是 ABI 与 STL 的选择:arm64-v8a 覆盖绝大多数现代设备,armeabi-v7a 留给老设备;STL 选 c++_static 可以避免额外携带 .so 文件。
export ANDROID_NDK=/path/to/android-ndk
./build-android.sh $ANDROID_NDK \
-DANDROID_ABI=arm64-v8a \
-DANDROID_PLATFORM=android-24 \
-DANDROID_STL=c++_static \
-DNCNN_VULKAN=ON
有三点要注意:一是启用 Vulkan 时通常要把 ANDROID_PLATFORM 提到 android-24 及以上,默认值以官方脚本为准;二是开启 Vulkan 会连带编译 glslang 子模块,必须先执行 git submodule update --init,否则 CMake 阶段就会报找不到 glslang;三是体积敏感的项目可以关掉 benchmark 等非必要目标,但不要随意关闭 NCNN_INT8,否则量化模型会加载失败。
iOS 与 ARM Linux
iOS 用官方的 build-ios.sh,产物是 XCFramework 或静态库。ARM Linux 板卡(树莓派、瑞芯微、全志等)可以直接在板上用 g++ 编译,也可以用交叉工具链编译,注意对齐 CPU 指令集与浮点 ABI。Vulkan 只在确实有 Vulkan 驱动的板卡上才开启编译。
CMake 常用开关
| 开关 | 作用 | 建议 |
|---|---|---|
| NCNN_VULKAN | 启用 Vulkan GPU 加速 | 移动端与带驱动的 ARM 板卡开启 |
| NCNN_OPENMP | 多线程并行 | Android 上一般关闭,改用内部线程池 |
| NCNN_BUILD_TOOLS | 编译转换与量化工具 | 桌面侧开启,端侧关闭 |
| NCNN_BUILD_BENCHMARK | 编译基准测试程序 | 性能调优时开启 |
| NCNN_INT8 | 支持 int8 量化推理 | 保持开启,除非明确不用量化 |
| NCNN_AVX2 等 | x86 指令集优化 | 桌面构建可选,端侧无关 |
常见构建与加载报错
| 报错 | 原因 | 处理 |
|---|---|---|
| Could not find glslang | 没有初始化子模块 | 执行 git submodule update --init |
| undefined reference to vkCreateInstance | 开了 Vulkan 但没链上 Vulkan 库 | 安装 Vulkan loader 与头文件,或先关闭 NCNN_VULKAN |
| NDK 与 CMake 组合过旧导致的 STL 报错 | 工具链版本不匹配 | 换用官方推荐的组合,以官方文档为准 |
| 运行时 layer X not exists or registered | param 里有运行时不认识的层类型 | 升级 NCNN 版本,或注册自定义层,或换一条转换路径 |

