交叉编译Qt5.9.6中的问题及其解决

最近在做一个项目,需要在一块开发板上做一个界面,开发板是瑞芯微电子的RK3399,这种板子刚出时间不长,处理器是64位的ARMV8。

一开始完全不知道怎样下手,最初纠结的问题是:到底是直接在板子上安装Qt,直接在板子上开发还是在电脑上安装交叉编译环境(在电脑上开发,再移植在开发板上)。首先尝试了交叉编译,一头雾水,根本不知道怎样编译,之前做过一个在32位开发板上的小项目,尝试过交叉编译,用的是arm-linux-gcc编译器,时间过去很久了,也已经忘了,而现在是64位的板,肯定不能用arm-linux-gcc编译器了。然后又在板子上安装了Qt,用命令安装的,安装上之后根本不能用,qmake不能用,提示:No compiler can produce code for this Qt version. Please define one or more compilers.网上也找不到解决方法,只能又尝试交叉编译。

交叉编译过程:首先找了一篇博文(https://www.cnblogs.com/wanglouxiaozi/p/9521950.html)跟着文章一步步做,用的Qt版本是4.7.3,原文中说的的配置过程中用到了一个参数 -embedded armv8,意思就是嵌入式平台是ARMV8,而指定这样一个参数,会在配置完后出现一个警告:

NOTICE: Atomic operations are not yet supported for this
        architecture.

        Qt will use the 'generic' architecture instead, which uses a
        single pthread_mutex_t to protect all atomic operations. This
        implementation is the slow (but safe) fallback implementation
        for architectures Qt does not yet support.

Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into /opt/qt-4.7.3-arm64

To reconfigure, run 'make confclean' and 'configure'.

这个意思就是当前的Qt不支持这个架构(ARMV8),而博主似乎没有发现问题,而认为这是配置成功的标志,继续往下进行,也就是make,因为在ARMV8上编译Qt的文章很少,我也找不到其他的文章,于是继续跟着走,果然到了下面报错了:(作者也指出了一个可能出现的错误,但这里不是) 

 上网找了好长时间也没能找到解决办法,我想是不是Qt的版本太低,不支持ARMV8架构,就换了一个高一点的版本Qt5.6.0,又找了一篇CSDN的博文(移植QT5.7.0到64位fireflyPK3399开发板),跟着文章做,编译仍然会出错误

又出现了新的问题:Project ERROR: Unknown module(s) in QT: quick,也很难解决,上网搜了很长时间没有找到什么有效的解决办法。

后来实在没有了办法,又下载了一个更高版本的Qt5.9.6,编译不出意外仍然出错,这次的错误是一个文件中的函数找不到原型:

No matching function for call to qBound(double, qreal&, double)

这个问题更难找到了,网上几乎没有,只好自己看编译过程,跟着编译报的错找到了那个文件,然而并没有找到什么有价值的信息,又上网找啊找,各种改配置文件,改一次,编译一次,从开始到报错要一个多小时,还是通不过。最后在一篇博文里发现是qreal这个参数的问题,在usr/include/qt4/Qt/qglobal.h头文件中有qreal的定义:

// This logic must match the one in qmetatype.h
#if defined(QT_COORD_TYPE)
typedef QT_COORD_TYPE qreal;
#elif defined(QT_NO_FPU) || defined(QT_ARCH_ARM) || defined(QT_ARCH_WINDOWSCE) || defined(QT_ARCH_SYMBIAN)
typedef float qreal;
#else
typedef double qreal;
#endif

在这里可以看到,如果处理器架构是ARM的,那么qreal就会被设置为float,所以在编译的时候,类型为double的数据或者函数,就会与qreal关键字不匹配了。为什么设置为float就不可以呢?目前不清楚,但我猜想是因为ARMV8是64位的架构,float是单精度占32位,double是双精度,占64位(猜想而已)。

搞清楚了这一点,就都明白了,解决方法也很简单,只要在编译时加上参数:-qreal double,即可编译通过。解决问题过程中参照的一篇博文里是将参数设置为了-qreal float,也难怪会出现问题。

猜你喜欢

转载自blog.csdn.net/JLH94/article/details/82940678