搞了一周,把所有的坑都跳了一遍,最后放弃了。

        由于一开始不清楚目标机的情况,就直接在 ubuntu20.04 里装了 Qt5.14.2 开发程序,程序开发完目标机才到,一看是银河麒麟aarch64架构,就开始交叉编译吧。

        照着博友提示,下载了 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz

        又下载了Qt5.14.2 源码,一套操作编译成功,这里不详述,只想说版本问题。

        移植到目标机,运行程序,提示GLIBC_的版本不对, /lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /opt/Qt-5.14.2-aarch64/lib/libQt5Widgets.so.5)

        敲命令 strings /lib/aarch64-linux-gnu/libc.so.6 | grep GLIBC_ 和 gcc --version 一看版本才5.4,又上网查不能随便给目标机升级gcc版本,有可能会导致系统崩溃,一想也是,可能麒麟的桌面就是5.4编译的,看来只能降低交叉编译的版本了。不然10.3编译的库,5.4提供的链接器去连接动态库新特性怎么能支持呢。

        看了看各个版本的时间,下载了gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu.tar.xz

        交叉编译QT,再搞一遍!! 很不幸make时报错,有些语法编译器不支持,查了下qt5.14需要gcc7.3才能支持。

        无奈降低qt的版本吧。银河麒麟默认安装的是Qt5.6.1版本,又交叉编译QT OK。发现编译现在程序缺少好几个模块的支持,哭啊

银河麒麟liunx安装java_目标机

。最后只能改程序了,看来跨平台移植还是要用低版本,怪不得QT4.8.6还有人用。下次还是先搞清楚目标机情况再开发吧。

        最后得出的结论: 移植效率 = 网速 + CPU核数

============再更新一下

        秉着不抛弃不放弃原则,查到GCC5.3.1可以编译QT5.7.0,  QT5.7支持我用到的qtchart模块,用gcc5.3.1把qt5.7.0源码再次交叉编译,再交叉编译程序,移植到麒麟V10上,运行又报错,但是感觉报错内容已经发生变化,于是交叉编译了一个qt示例analogclock,复制到麒麟上,运行成功了

银河麒麟liunx安装java_目标机_02

。再看我的程序报错是 /dev/fb0 权限拒绝,sudo -s切到root账号,重新source env.sh,程序启动起来了。界面没显示出来。。。

=============

        又经过不断测试验证,发现在麒麟V10用QPA设置为linuxfb行不通,学习了一下发现 linuxfb 只适用于嵌入式linux(液晶屏那种,没有桌面操作系统的),界面图像数据直接写到framebuffer就能显示。银河麒麟V10白皮书写的窗口系统基于Xserver 和 xwayland 实现的,wayland需要xcb的支持,我艹好大一个坑,qt又要重新交叉编译,还要支持xcb,xcb还需要一系列的库,可自行搜索。我推荐一个连接

===============

搞了好久也没编译全xcb相关的库,太难了,果断放弃。

起始不编译xcb软件也能在银河麒麟上运行,麒麟是基于xcb实现的,当然系统自带xcb的支持,就在 /usr/lib/aarch64-linux-gnu/qt5 里面。只需要补全自己用的其他库就好了。又东拼西凑了一把库,果然软件能运行了。结果又出了新问题,串口不能用,一关闭就崩溃,报段错误,实在是难定位,最后索性在麒麟上装了qt5.7,直接debug源码,提示报错 “ RTTI symbol not found for class 'QObject' ”,又挖着了个坑。

原因是在调用deleteLater() 后,调试执行到析构函数中 报错,调用了两次析构函数

为啥析构了两遍,

connect(m_serialThread,&QThread::finished,m_serialport,&MySerialport::deleteLater);
 connect(m_serialThread,&QThread::finished,m_serialThread,&QThread::deleteLater);

这是错误写法

connect(m_serialThread,&QThread::finished,m_serialport,&QObject::deleteLater);
 connect(m_serialThread,&QThread::finished,m_serialThread,&QObject::deleteLater);

正确写法,就差在QObject的deleteLater。我在qt5.14中不存在这个问题,但是移植后用qt5.7就有这个问题。 关键在于调用QObject的析构后会自动析构子类,如果调用的子类的deleteLater相当于进入了子类的析构函数中,会先执行父类析构,再执行子类析构,但是设备已经释放了就会报错。

=========================

后来还发现装个qmenu替代VMware可以直接跑arm64的麒麟系统,qmenu模拟硬件,不过弄起来也麻烦,据说还很卡,没走这条路。

最后总结一下,移植到aarch64,找到目标机gcc版本后,找个别人软件的包,包里有依赖的库,比如说海康的客户端MVS也是用qt开发的,然后查看一下他的库的版本,下载对应qt的源码交叉编译,把依赖的库凑一下就可以了

银河麒麟liunx安装java_linux_03

是不是捷径。如果还有差的库可以从目标机的/usr下找拷过来,比自己一个个编译强。