基于Flutter实现Windows平台离线大模型对话应用实战

您所在的位置:网站首页 cmakelist指定编译器 基于Flutter实现Windows平台离线大模型对话应用实战

基于Flutter实现Windows平台离线大模型对话应用实战

2023-06-01 08:37| 来源: 网络整理| 查看: 265

1、背景

前面文章《基于Flutter实现跨平台离线大模型对话应用》中介绍了基于Flutter实现跨平台的离线模型对话应用,跑通了Android、iOS、Mac平台,在编译Windows平台时由于不熟悉Windows平台编译器,踩了一些坑,最终搞了一个晚上加一个上午成功搞定。

2、Windows编译器介绍

传统的编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd)。在编译过程中:

前端主要负责词法和语法分析,将源代码转化为抽象语法树; 优化器则是在前端的基础上,对得到的中间代码进行优化,使代码更加高效; 后端则是将已经优化的中间代码转化为针对各自平台的机器代码。

作为一个移动端开发,日常用到最多的C++编译器是GCC、Clang。

GCC(GNU Compiler Collection,GNU 编译器套装),是一套由 GNU 开发的编程语言编译器。GCC 原名为 GNU C 语言编译器,因为它原本只能处理 C语言。GCC 快速演进,变得可处理 C++、Fortran、Pascal、Objective-C、Java 以及 Ada 等他语言。 Clang是以 LLVM(Low Level Virtual Machine,底层虚拟机)为后端的一款高效易用,并且与IDE 结合很好的编译前端。Clang 只支持C,C++ 和 Objective-C 三种语言。

虽然Windows上也有Cygwin、MinGW、TDM-GCC等GCC移植版本,但我们还是选微软官方的MSVC系列编译器。它与Visual Studio集成发布,微软自己的编译器,VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等。所写的目标代码适用于微软支持的所有平台,包括Microsoft Windows、Windows Mobile、Windows CE、.NET Framework、.NET Compact Framework和Microsoft Silverlight 及Windows Phone。

3、Windows平台开发Flutter桌面应用 3.1 环境安装

Flutter 2.10 开始,对Windows 的支持已进入 stable 渠道。要开发Windows应用除了安装Flutter SDK,还需要安装微软提供的Visual Studio22或者是Visual Studio 2022生成工具。在安装时要选择”使用C++的桌面开发“,它包含了所有默认组件(必要的C++工具链和Windows SDK的头文件)。

3.2 配置C++编译脚本

直接在windows目录下创建CMakeLists.txt文件,在CMakeLists.txt中直接添加编译信息:

cmake_minimum_required(VERSION 3.10) # 项目名称 set(PROJECT_NAME "libNativeAdd") project(${PROJECT_NAME} LANGUAGES CXX) # 源文件 add_library(${PROJECT_NAME} SHARED "./native_add.cpp" ) # 动态库的输出目录 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$$") # 安装动态库的目标目录 set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") # 安装动态库,到执行目录 install(FILES "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${PROJECT_NAME}.dll" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime)

也可以添加子目录方式添加对应模块:

add_subdirectory("../libs/native_add" native_add) 3.3 遇到问题 项目里面有几个.cpp文件还有一个.c文件,这样配置后运行flutter run,一直报错,提示连接C文件里的函数失败,查看了编译时中间文件,发现C文件没有被执行编译,最后发现是CMakelist.txt中指定了project(${PROJECT_NAME} LANGUAGES CXX)编译语言导致C文件没有执行编译,其他平台都没问题,Windows上报错。 运行时FFI查找C函数时提示找不到,将编译出的DLL文件放到指定路径,通过指定路径加载也同样失败,而且debug查看,动态库已经成功加载,就是找不到函数。向外暴露的函数通过#define EXPORT_API __attribute__ ((visibility ("default")))定义的EXPORT修饰:EXPORT_API void* init(const char* path);,windows编译时EXPORT_API修饰报错,以为这个修饰没有用,直接删除掉了,导致找不到函数。最后通过: #ifdef WIN32 #define EXPORT_API extern "C" __declspec(dllexport) #else #define EXPORT_API extern "C" __attribute__((visibility("default"))) __attribute__((used)) #endif

来支持不同平台接口。

3.4 应用打包

我们一般安装windows程序都提供了一个安装包,我们执行安装,然后释放资源和可执行文件,同时应用程序发布到微软商店前必须要打包。有效的格式是 .msix、 .msixbundle、 .msixupload、 .appx、 .appxbundle、 .appxupload 和 .xap。Flutter提供了打包msix程序的工具。MSIX是微软提供的新的Windows应用程序包格式,它提供了一种现代的打包格式和安装程序。这种格式既可以用于将应用程序发布到Windows上的Microsoft Store,也可以直接分发应用程序安装程序。

Flutter提供了MSIX pub打包方式。打包时需要配置.pfx证书:

请下载OpenSSL工具包来生成证书。 进入OpenSSL的安装路径,例如C:\Program Files\ OpenSSL- win64 \bin。为方便使用我们设置一个环境变量,这样可以从任何地方访问OpenSSL。 生成私钥:Openssl genrsa -out mykeyname.key 2048 。 使用私钥生成证书签名请求(CSR)文件:Openssl req -new -key mykeyname.key -out mycsrname.csr 使用私钥和CSR文件生成已签名的CRT文件:openssl x509 -in mycsrname.csr -out mycrtname.crt -req -signkey mykeyname.key -days 10000 使用私钥和CRT文件生成。pfx文件:openssl pkcs12 -export -out CERTIFICATE.pfx -inkey mykeyname.key -in mycrtname.crt 在安装应用程序的机器上安装.pfx证书,配置作为受信任的根证书颁发机构。

Flutter可执行文件.exe可以在我们的项目build\windows\runner下找到。除了.exe可执行文件,您还需要以下文件:

统一目录上所有的.dll文件 data目录 拷贝依赖文件:msvcp140.dll ,vcruntime140.dll,vcruntime140_1.dll

最终目录结构:

Release │ flutter_windows.dll │ msvcp140.dll │ my_app.exe │ vcruntime140.dll │ vcruntime140_1.dll │ └───data │ │ app.so │ │ icudtl.dat ... 3.5 Flutter插件

我们代码里面写死了加载.dll文件路径,打包后解压安装后加载路径不好找,Flutter提供了插件支持,我们只需要创建Native插件即可,不用再考虑加载路径的问题。

flutter create --template=plugin_ffi hello创建插件; pubspec.yaml 配置 FFI plugins: plugin: platforms: some_platform: ffiPlugin: true

这样在插件里面实现本地代码,应用工程中调用插件代码即可。

参考:

GitHub - gaoshang212/flutter_native_demo zhuanlan.zhihu.com/p/458488070 Flutter Packages 的开发和提交 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 4、性能优化

运行时效果不是很理想,使用的thinkpad,2.8G主频8核,24G内存,SSD,推理速度不是很快,开启编译优化:

target_compile_options(model_lib PRIVATE "$" "$" )

并没有很快的速度提升,具体优化还得持续研究。

5、总结

本文介绍了Windows上的MSVC C++编译器以及Flutter创建桌面应用的步骤及应用程序打包方式,并分享了FFI集成本地代码遇到的问题和解决办法。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3