windows 上编译 cpu 版本的 ncnn
从 发布页面 下载最新的完整的 ncnn 代码包,即 -full-source
后缀的文件。以及 protobuf 的代码包(用于生成 caffe2ncnn 和 onnx2ncnn 工具)。
- 我下载的 20221128 版本的 ncnn 和 3.11.2 版本的 protobuf。(这里参考的是https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-windows-x64-using-visual-studio-community-2017)
- 解压后进入源代码文件夹中。
- 启动 cmake-gui 程序。
编译安装 protobuf
使用 cmake-gui:
- source-dir:<你的 protobuf 目录>/cmake
- build-dir: <你的 protobuf 目录>/build-mingw
- 选项设置:
- CMAKE_BUILD_TYPE=Release
- CMAKE_INSTALL_PREFIX=<你的 protobuf 目录>/build-mingw/install
- protobuf_WIZH_ZLIB=OFF
- protobuf_BUILD_TESTS=OFF
- protobuf_MSVC_STATIC_RUNTIME=OFF
mingw32-make.exe -j2
mingw32-make.exe install
编译安装 cpu 版本的 ncnn
使用 cmake-gui:
- source-dir:<你的 ncnn 目录>
- build-dir:<你的 ncnn 目录>/build-mingw
- 选项设置:
- OpenCV_DIR=你的 opencv 的编译目录里的 install 路径
- CMAKE_BUILD_TYPE=Release
- CMAKE_INSTALL_PREFIX=<你的 ncnn 目录>/build-mingw/install
- Protobuf_INCLUDE_DIR=<你的 protobuf 目录>/build-mingw/install/include
- Protobuf_LIBRARY_RELEASE=<你的 protobuf 目录>/build-mingw/install/lib/libprotobuf.a
- Protobuf_LITE_LIBRARY_RELEASE=<你的 protobuf 目录>/build-mingw/install/lib/libprotobuf-lite.a
- Protobuf_PROTOC_EXECUTABLE=<你的 protobuf 目录>/build-mingw/install/bin/protoc.exe
- Protobuf_PROTOC_LIBEAEY_RELEASE=<你的 protobuf 目录>/build-mingw/install/lib/libprotoc.a
- NCNN_VULKAN=OFF
- NCNN_AVX2=OFF
- NCNN_SSE2=OFF
mingw32-make.exe -j2
mingw32-make.exe install
onnx -> ncnn
编译安装好 ncnn 后,install 的 bin 里会出现一个 onnx2ncnn.exe 的可执行程序,可以用于将 onnx 转为 ncnn 可使用的模型文件。
dll/lib/so/a/map/pdb 文件
(摘自参考资料2)
- dll,与 lib 是 Windows 下描述封装代码库的一种格式;a,so 是 linux 下的。- dll 与.so 是动态库,lib 与.a 是静态库。
- map 文件记录了程序中的数据,变量,函数的地址,数据存放区域。如果程序发生奔溃,则可以通过奔溃的地址在 map 文件中判断崩溃的程序位置。需要在链接中开启生成 map 文件的设置。
- pdb 文件是 bebug 模式下的调试信息。有次文件才能调试程序。记录了变量位置,函数 1 地址等。
静态库(lib,.a)是以静态的方式(隐式方式)将 lib 文件加载到可执行文件中。通常需要在使用时包含其头文件和在链接设置中设置加载此静态库。动态库(dll,.so)可以用 (1) 静态方式(隐式方式)或者 (2) 动态链接的方式加载到可执行文件中。以静态方式加载相同,需要在链接设置中配置 dll 的 lib 或者.so 的.a 文件。如果是以动态加载方式则需要 dlopen 等接口去加载 dll 或者.so。两者的区别是动态加载是在程序启动后根据程序实际情况进行加载 dll。静态加载在链接阶段便已经将接口地址等信息加载到可执行文件中。静态库将代码,符号等信息都编译到了 lib 文件中。所以如果程序使用,就必须要链接 lib 库。同时,多个程序之间不能分享 lib 库。动态库可以在多个程序见使用一份 dll,减少资源浪费。
参考资料
- 27、Window10+Clion+MinGW32编译NCNN使用
- dll,lib,.a,.so的联系与区别。什么是共享库?与dll的区别是什么?
- ncnn 与 opencv 的互操作:https://github.com/Tencent/ncnn/wiki/use-ncnn-with-opencv