windows客户端的ARM64国产化适配
0 概要
本文以《XXX项目》为基础,在国产化麒麟操作系统广泛应用的背景下,聚焦于windows客户端产品,提供客户端产品适配ARM国产化电脑的基本思路。
1 主要工具的编译安装
1.1 QT源码编译
QT源码的编译与否,取决于客户端产品开发时使用的QT版本。不同的QT版本,无法完全相互兼容。因此,在适配工作开始前,需要找到合适的QT版本(一般与原工程项目开发版本相同)。本项目中客户端原工程使用QT 5.9.6进行开发,故需要在用于做适配工作的国产化电脑(系统版本如图1.1所示)上编译安装QT 5.9.6版本。
图1.1 系统版本
QT源码编译涉及多模块,具体模块的是否编译依据项目工程的使用情况决定。如,本工程中使用了QT Audio模块,故进行源码编译时,需添加相关Audio参数。如下,为经过多次尝试、修改部分QT冲突代码后,最终的编译参数命令:
./configure -prefix /usr/local/qt-5.9.6-20230918 -no-openssl -skip qtlocation -alsa -no-pulseaudio -skip qtwebengine
QT5.9.6源码地址:https://download.csdn.net/download/qq_39612333/88545197
1.2 QtCreator
QtCreator可使用系统自带的工具,无需编译。(同样可通过sudo apt-get install qtcreator直接安装系统支持的版本),安装完成后,打开QtCreator,将构建套件切换为编译的QT 5.9.6工具套件即可,此处不赘述。
1.3 打包工具编译安装
客户端编译完成后,通过打包工具,可以自动的将可执行程序依赖的库文件、qt插件共同打包至一个文件夹内,使得应用程序在纯净的系统里能够独立运行。本项目的打包工具使用了linuxdeployqt(使用编译好的qt 5.9.6进行编译即可)。
资源地址:https://download.csdn.net/download/qq_39612333/88545189
1.3编译工具链编译
不同的GCC版本支持的C基础库版本不同,比如高版本的GCC编译的程序,难以在低版本的linux系统中兼容运行。主要原因的GCC编译程序时,使用的libc.so的GLIBC库版本较高,而低版本系统中,libc.so并不支持高版本的GLIBC。报错现象如图1.2所示。因此,建议使用低版本的GCC编译QT 5.9.6和项目工程。本项目中,使用GCC5.4版本,编译了QT 5.9.6和项目工程。
图1.2 兼容报错
2 适配工作内容
2.1 PRO工程文件的生成
1、pro文件可以理解为CMakeList文件,qt使用pro文件生成工程make文件,来达到编译工程代码的目的。
2、本项目中,由于原工程是使用vs+qt工具进行开发的,故进行工程arm版适配前,需要基于vs工程生成纯qt版本的pro文件。
3、vs+qt tools生成的pro文件并不能直接使用,需要安装项目工程结构进行修改。主要增加三方库路径、三方头文件路径、编译的目标程序类型、目标程序路径等描述。如下:
TEMPLATE:项目类型,app或lib
TARGET:生成的可执行文件名或库名称
DESTDIR:生成的可执行文件目录
QT:涉及的qt模块
CONFIG:编译选项,如debug,调试
INCLUDEPATH:链接库的头文件路径
LIBS:链接的三方库
HEADERS:源码的头文件
SOURCES:源码的源文件
QMAKE_RPATHDIR(指定程序执行时,共享库的搜索路径)
4、初步完成pro文件后,进行编译测试,基于qt编译报错结果,逐步补充pro,直至编译成果。(注三方库提示不存在的常见错误见“本项目适配中遇到的主要问题”)
2.2 ARM版本三方库编译
本项目中,三方库的获取渠道包括:1、开源库中查找 2、对于开源的库,使用GCC进行编译。
需要注意的是,项目工程编译过程中,可能会报“库文件不存在的错误”,但是实际上库文件存在,此时考虑库版本与目标系统架构不同。(本项目中系统架构为aarch64)。
2.3代码跨平台兼容
本项目中,项目工程源码部分需要进行跨平台适配,主要为以下情况:
1、本项目中源代码已进行了部分跨平台适配,但是对arm平台的适配做了功能删减、需求删减。如某些功能按键在非win平台上进行了隐藏,使用了默认配置。这部分缺陷通常在对比测试中发现。
本项目中,如选择麦克风、音响的comboBox的 下拉键,源代码中对不属于windows版本的进行了隐藏。
2、库加载方式不同。Win平台中大量使用#pragma comment(lib,”./*lib”)的形式加载库。因此实际适配中,需要将这种形式的库链接在pro文件中进行配置。
3、默认编码格式不同。如果程序需要读取的配置文件中包含中文,需要指定以GBK编码的形式读取文件,否则会出现乱码。
4、三方库部分接口变化,与win版本不同。这种情况可能会导致程序奔溃。本项目中,使用的播放库,由于返回的播放句柄与win版本返回的数据类型不同,导致进行3D放大功能时奔溃。Win版本返回int类型,arm64版本返回long类型。
2.4 字体适配
由于qt不会提供字体文件,为了和win平台客户端的字体保持一致,需要将win平台的字体拷贝至ARM64系统。字体文件是跨平台通用的,因此直接拷贝即可。(拷贝至qt安装目录下的/lib文件夹下,程序打包是需要手动拷贝至可执行目录文件夹)。
2.5 皮肤资源、其他配置文件
需要将原工程相关文件资源均复制至可执行文件下相同目录,并且与可执行程序的相对路径不能改变。
如本项目中,相关资源、配置文件如下。
图2.1 相关文件
3、程序打包
3.1使用Linuxdeployqt打包
一、将编译生成的可执行程序单独拷贝至新文件夹下
二、进入该目录下的终端,设置环境变量,包括QT 5.9.6安装目录下的lib文件路径、plugins路径、以及可执行程序依赖的其他三方库所在路径。(可使用LD_LIBRARY_PATH={动态库路径}:$LD_LIBRARY_PATH指定环境变量)
三、执行linuxdeployqt {程序名称} -verbose=2
四、执行完成后,目录结构如图3.1
图3.1 目录结构
五、至此,linuxdeployqt已经把可执行程序***依赖的库文件、qt插件加载至目录中。
六、但是,程序并不能正常运行。主要原因包括以下:
a) 缺少了配置文件、字体文件、皮肤文件、翻译文件。
需要注意的是,linuxdeploy并不会把配置文件、字体文件、皮肤文件、翻译文件等相关文件拷贝至打包文件夹中,因此执行完打包命令后,还需要手动(或者脚本)将所有相关文件拷贝至打包文件夹中。
b) 缺少了库文件。
缺少库文件存在两种情况。
一是库文件已经存在3.1的lib文件夹中,但是未加载到。造成这种情况的原因是:由于lib文件夹是linuxdeployqt生成的,而pro配置文件并未将lib文件夹路径指定为动态库搜索路径,因此可执行程序无法找到库文件。
二是库文件的确未被linuxdeployqt拷贝。造成这种情况的原因是,源工程代码中使用三方库时未使用传统的链接方式,如“-lhpr”,而是使用qt的api加载动态库,如QLibrary a=new QLibtary(/home/liba.so)。这导致了linuxdeployqt无法正确的获取可执行程序的依赖库。因此,为了避免这种问题,需要将打包后的文件目录与win版本的打包目录对此,将缺少的库补齐。
七、最后完整的打包文件目录如下图3.2。
3.2 完整的打包目录
3.2 程序的快捷方式
Linux中可执行程序的快捷方式使用.desktop文件格式进行描述。文件内容如下图3.3所示。
其中,Exec表示该desktop文件所映射的可执行文件,Icon表示该快捷方式所显示的图标,Comment为描述,Terminal为是否打开终端。其中“/opt/apps/***”为预设的客户端安装路径。
图3.3 desktop文件
3.3 deb安装包生成
deb是一种安装包格式。生成deb安装包的文件目录结构如图3.3所示。
其中DEBIAN文件夹中的postinst、postrm文件是脚本文件,分别在deb包安装成功后执行、卸载后执行,非必要文件,可按需配置。Control文件是描述文件,具体文件内容此处不赘述。/usr/share/applications/文件夹是linux系统用于存放desktop快捷方式文件的路径。通过配置该路径,可在开始菜单查看到安装后的客户端。
在当前目录下的前一级目录执行生成deb包的命令:dpkg –b ./(当前文件目录) com..***.deb 即可生成deb安装包。
图3.3 deb文件结构
4、本项目适配中遇到的主要问题
1、读取配置文件中的中文,出现乱码。
虽然在windows显示正常,但由于银河麒麟系统编码格式不同,导致读取配置文件时的字符编码乱码,使用QTextStream in(&file); in.setCodec(“GBK”),以GBK编码格式读取文件,显示正常。
2、读取配置文件失败,如本项目中的读取登录信息本地数据库失败。
检查数据库路径和程序查询路径是否一致。本项目中,出现程序中加载数据路径不对而导致的登录初始化失败,原因是源工程项目使用的程序目录路径不对,后使用QApplication::currentPath获取当前路径,正常加载。
3、日志不生产问题。
主要有两个原因,一是日志配置文件加载路径错误,二是当前用户无权限创建日志文件夹和日志文件,所以安装时需要配置好可执行程序和安装目录的创建文件权限
4、对讲库异常,无法对讲,但是demo测试正常。
对讲库内部加载openal动态库的方式使用相对路径,导致客户端内无法正常加载openal动态库,目前已更新对讲库。
5、视频预览播放无声音问题。
播放库组件缺陷,替换后正常播放。原因是不支持G711音频格式。
6、windows版本的语音对讲界面有下拉框,适配版本没有下拉框。
原因为源工程代码中对非win平台的版本默认隐藏。
7、视频预览3D放大功能无法使用。
3D放大功能流程会向驱动透传接口发送放大请求,根据报错,定位问题为请求未返回导致的报错,将请求在postman中复现,发现请求协议错误(修改前为https),强制修改成http,测试后正常3D电子放大。
8、在视频界面画框进行3D放大时,程序奔溃。
在调用播放的画框函数褚奔溃,使用gdb查看堆栈,查看发现获取播放句柄时,返回参数被强制由long转成int。
9、点击视频预览,程序崩溃问题。
问题定位为tinyxml开源库崩溃,具体为创建TiXMLText对象崩溃,更换新版本开源库tinyxml2,适配代码解决。
10、客户端启动,无法切换输入法、中英文,导致无法输入中文。
缺失库:libfcitxplatforminputcontextplugin.so。