记录Qt交叉编译及在开发板上运行的问题

在嵌入式ARM开发板上运行QT程序,绕不过去要交叉编译QT库以及其它依赖库,网上的资料虽然很多,但是自己亲自实践起来还是磕磕绊绊,问题不断,这里记录一下自己的操作过程、问题、解决过程等,后续遇到新问题也继续在这里更新吧,还有些没解决的问题、疑惑也希望有大佬路过能指点一二。

虚拟机:ubuntu64 18.04
使用的交叉工具链是arm-linux-gnueabihf
注:其实在使用arm-linux-gnueabihf之前,还是用过aarch64-linux-gnu交叉编译过,也导致多踩了许多坑。。

tslib交叉编译

tslib 下载:git clone https://github.com/kergoth/tslib
tslib 编译参考:https://blog.csdn.net/singleroot/article/details/54344873?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-6&spm=1001.2101.3001.4242
注意将编译器更换为实际使用的编译器

./autogen.sh
echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache
./configure --host=arm-linux --prefix=/opt/tslib1.4 CC=arm-linux-gnueabihf-gcc --cache-file=arm-linux.cache
make
make install

注:之前有用其它工具链编译过的话,直接make & make install可能报错,可先make clean再make&make install

QT库交叉编译

参考:https://blog.csdn.net/hl1796/article/details/90205218
1、确定交叉工具链安装位置,由于之前进行linux开发时已经安装过,故不需重复安装,工具链位置:/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
交叉工具链位置

注:工具链下载地址:https://www.linaro.org/downloads/
主要版本如下:
在这里插入图片描述
2、在 /etc/profile中添加环境变量:

export PATH="/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin:$PATH"

3、配置qt运行库的编译环境:
到qt运行库的qtbase/mkspecs/ 路径下ls:
在这里插入图片描述

由于其只有gnueabi-g++目录,故复制一份gnueabihf-g++的路径:

cp -r linux-arm-gnueabi-g++/ ./linux-arm-gnueabihf-g++

在linux-arm-gnueabihf-g++文件夹中编辑 qmake.conf,添加如下内容

QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS_RELEASE += -O2 -march=armv7-a -lts
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv7-a -lts

同时修改对应的交叉编译器,即arm-linux-gnueabi修改为实际使用的arm-linux-gnueabihf
注:armv7还是armv8就看实际开发板了,我这边开发板采用32位 cortex-a7 cpu,应属armv7了吧,-lts表示需要链接ts库
完整的qmake.conf如下:
在这里插入图片描述

4、配置交叉编译自动配置脚本(进行编译选择等,即利用qt configure进行裁剪)
在qt库目录中, vi autoconfig.sh,添加内容如下:

#!/bin/sh
./configure \                              //运行configure脚本
-prefix /opt/qt5.12.10-arm \               //编译输出目录
-confirm-license \
-opensource \
-release \                                 //release版本
-make libs \
-optimize-size \                           //对库大小进行优化
-xplatform linux-arm-gnueabihf-g++ \      //交叉编译选项,对应第三步的路径
-pch \
-qt-libjpeg \
-qt-libpng \
-qt-zlib \
-no-opengl \                             //-no-xxx选项选择不编译xxx
-no-sse2 \
-no-openssl \
-no-cups \
-no-glib \
-no-dbus \
-no-xcb \
-no-separate-debug-info \
-no-ssl \
-nomake tests \
-nomake examples \
-nomake tools \
-no-sql-sqlite \
-no-iconv \
-skip qt3d \                          //-skip xxx选项选择跳过,xxx对应了qt库目录下的repo
-skip qtactiveqt \
-skip qtcanvas3d \
-skip qtcharts \
-skip qtconnectivity \
-skip qtdatavis3d \
-skip qtdeclarative \
-skip qtgamepad \
-skip qtandroidextras \
-skip qtdoc \
-skip qtwebchannel \
-skip qtwebengine \
-skip qtwebglplugin \
-skip qtwebview \
-skip qtvirtualkeyboard \
-tslib \
-I /opt/tslib1.4/include \                   //指定tslib库的头文件包含路径
-L /opt/tslib1.4/lib \                       //指定tslib库的路径
-recheck-all
exit

注:具体的配置选项可以通过./configure -embedded -help查看,摘选部分说明:

Top-level installation directories: 顶层安装目录
-prefix

… The deployment directory, as seen on the target device.
[/usr/local/Qt-$QT_VERSION; qtbase build directory if
-developer-build]

Build options: 构建选项
-opensource … Build the Open-Source Edition of Qt
-release … Build Qt with debugging turned off [yes]
-optimize-size … Optimize release builds for size instead of speed [no]
-static … Build static Qt libraries [no] (yes for UIKit)
-shared … Build shared Qt libraries [yes] (no for UIKit)
-xplatform … Select target mkspec when cross-compiling [PLATFORM]

Build environment:构建环境
-I … Pass additional include path
-L … Pass additional library path

Component selection: 编译内容选择
-skip … Exclude an entire repository from the build.
-nomake … Exclude from the list of parts to be built. 等等

5、运行autoconfig.sh脚本:
./autoconfig.sh
sudo make & make install
时间较长,试错成本极大…
遇到问题(1):make时提示arm-linux-gnueabihf command not found
处理过程:参考:http://blog.sina.com.cn/s/blog_61d9be5a0101s5r5.html
在/root下的.bashrc文件也添加环境变量:

export PATH="/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin:$PATH"

然后 source .bashrc更新,仍然提示错误:

分析下有指定交叉编译器的地方,也就qtbase/mkspecs/qmake.conf咯,蛮检查一下arm-linux-gnueabihf有木有安装好吧:
在这里插入图片描述
没有问题,可能是某种原因导致无法正确识别到环境变量,直接配置成交叉编译工具的绝对路径总应该可以吧,如下:
在这里插入图片描述
测试解决了Command not found的问题
注:其实是因为make & make install的时候有sudo 一下,有个工作环境的切换,在root工作环境下识别不到arm-linux-gnueabihf,可以先sudo -i 获取root权限,然后再make,简单测试下,可以发现直接sudo确实无法识别到arm-linux-gnueabihf指令:
在这里插入图片描述

遇到问题(2)编译报错,提示:错误: static assertion failed: Required feature library for file /opt/qt-everywhere-src-5.12.10/qtbase/include/QtCore/…/…/src/corelib/plugin/qlibrary.h not available.
在这里插入图片描述
关于QT_REQUIER_CONFIG的解释,参考: https://my.oschina.net/u/4395961/blog/3851141
归结起来这里报错是没有定义feature library
autoconfig.sh配置中增加-feature-library试试,执行autoconfig.sh,结果如下:
在这里插入图片描述
提示前置条件失败:ERROR: Feature ‘library’ was enabled, but the pre-condition ‘config.win32 || config.hpux || (!config.nacl && features.dlopen)’ failed
再次检查,发现错误提示有那么一段话:
在这里插入图片描述
进一步,which llvm-config一下,将路径加入到环境变量,一个样,扎心啊

再次注意到 Note: No wayland-egl support detected. Cross-toolkit compatibility disabled.
把这个提醒消除掉试试,apt-get install libwayland-dev
安装完还是有这个提醒,没有改变,怎么办。。。
没辙了,尝试下重新解压一份新的qt源码来编译,结果、结果----------
没报错!没那么多p问题!
make 和make install都成功了,气啊,早干嘛去了,研究这些个错误干啥子。。

反思下:源码之前有使用aarch-linux-gnu-工具链交叉编译过,第一次编译的时候也是没那么多事,故更换工具链需要使用新的源码来,如果还在同一份源码上进行,仅仅更改配置,容易有乱七八糟的问题。(尝试过make distclean也是不行的)

应用程序在开发板上运行时出现的问题

1)This application failed to start because it could not find or load the Qt platform plugin “eglfs”
在这里插入图片描述
检查 开发板上 /etc/profile 的配置:

export PATH=/bin:/sbin:/usr/bin:/usr/sbin
export TSLIB_ROOT=/opt/tslib1.4
export QT_ROOT=/opt/qt_arm
export TSLIB_TSDEVICE=/dev/input/ts0
export TSLIB_TSEVENTTYPE=input
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export QWS_MOUSE_PROTO=tslib:/dev/input/ts0
export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:$QT_ROOT/lib:$TSLIB_ROOT/lib:$LD_LIBRARY_PATH
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_QPA_FONTDIR=$QT_ROOT/lib/fonts

疑惑:看了下plugins中确实是没有eglfs,但是我配置的是linuxfb来着
尝试1: 编译qt运行库时候,增加选项 -no-eglfs, 没变化,还是一样错误
尝试2:难道是我这/etc/profile根本就没生效?之前有手动source过的来着,那就再手动 source /etc/profile,再运行应用程序试一下吧:结果-----真就可以,再次重启后也是直接运行会报错,必须source /etc/profile后才能运行,看起来是/etc/profile的配置上电没有被自动配置生效
注:了解到busybox生成的程序不会自动执行/etc/profile
注:编译出来的qt运行库,并不需要将整个复制到开发板上,看/etc/profile的配置就知道了,仅需要将/lib和/plugins复制到开发板上就基本能运行qt widget程序了,后续有需要用到其它的功能,再来吧
2)字体问题
字体问题1、不显示字符,如QPushButton只显示控件不显示字符
看提示:QFontDatabase: Cannot find font directory /opt/qt5.12.10-arm-linux-gnueabihf/lib/fonts.
Note that Qt no longer ships fonts. Deploy some (from https://dejavu-fonts.github.io/ for example) or switch to fontconfig.
即qt 的/lib中默认是不再有fonts的了,需要手动下载添加(将ttf文件放到qt目录的/lib/fonts文件夹下即可)
字体问题2、显示了英文字符,但是不显示中文字符
解决方法:首先程序中要支持中文字符,main函数中添加:
QTextCodec *codec = QTextCodec::codecForName(“UTF-8”);
QTextCodec::setCodecForLocale(codec);
其次确认开发板/lib/fonts中有中文字库,可将开发机上/usr/share/fonts/trutype/arphic中的ttf文件拷贝到开发板的qt目录的/lib/fonts目录下

果然QtQuick还是少不了

之前编译的时候想着先试试qt widget程序跑一跑吧没去考虑QtQuick啥的,现在该来的问题还是来了
Unknown module(s) in QT: quick ,编译qtquick程序时提示错误
在这里插入图片描述
qml需要依赖opengl,编译opengl,参考:https://blog.csdn.net/weixin_34315665/article/details/92085956
按照教程,需要交叉编译libxcb(libxcb又需要xcb-proto、X11等,X11又需要一堆东西,好烦~)、libdrm、Mesa,一个一个来吧。。

交叉编译libxcb

参考教程:https://my.oschina.net/u/1250206/blog/1068725

xcb-proto编译

1)交叉编译xcb-proto,下载地址https://xcb.freedesktop.org/dist/
使用的是1.6版本
2)进入源码根目录,vi autoconfig.sh:

#!/bin/bash
CC=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
CXX=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
./configure --prefix=/opt/xcb-proto_arminstall --host=arm-linux-gnueabihf

3)执行脚本

./autoconfig.sh
make
make install

4)安装完成后导出PKG_CONFIG_PATH:

export PKG_CONFIG_PATH=/opt/xcb-proto_arminstall/lib/pkgconfig

libxcb 编译

1)下载地址 https://xcb.freedesktop.org/dist/
使用的是 1.5版本,该版本要求xcb-proto 版本大于1.5 ,并且要求x11支持
2)进入libxcb源码根目录vi autoconfig.sh:

#!/bin/bash
CC=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
CXX=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++

./configure CPPFLAGS="-I /opt/libx11_arminstall/include" LDFLAGS="-L/opt/libx11_arminstall/lib" --prefix=/opt/libx11_arminstall --host=arm-linux-gnueabihf

3)执行脚本

./autoconfig.sh
make

提示错误:
在这里插入图片描述
需要x11支持,先交叉编译x11吧

交叉编译libX11

参考教程:https://blog.csdn.net/Q1302182594/article/details/42028985
下载libX11源码:https://www.x.org/releases/individual/lib/

vi autoconfig.sh:
#!/bin/bash
./configure CPPFLAGS="-I /opt/libx11_arminstall/include" LDFLAGS="-L/opt/libx11_arminstall/lib" --prefix=/opt/libx11_arminstall --host=arm-linux-gnueabihf

直接make会提示错误,还需要下载其依赖项源码解压到libX11源码目录中,并分别编译,配置脚本都使用跟libx11中一样的autoconfig.sh,直接复制过来就好了, 依赖源码:
xproto-7.0.23.tar.bz2 https://xorg.freedesktop.org/archive/individual/proto/
xtrans-1.2.7.tar.bz2 https://xorg.freedesktop.org/archive/individual/proto/
kbproto-1.0.6.tar.bz2 https://www.x.org/releases/individual/proto/
inputproto-2.2.tar.bz2 https://www.x.org/releases/individual/proto/
libxcb-1.8.1.tar.bz2 https://www.x.org/releases/individual/lib/
xorgproto-2020.1.tar.bz2 https://www.x.org/releases/individual/proto/
编译完后:export PKG_CONFIG_PATH=/opt/libx11_arminstall/lib/pkgconfig
X11编译成功后,再返回去编译libxcb就可以了。
注:也是蛮奇怪的,前面libxcb也说需要X11,这里X11又来需要libxcb,一度搞晕,反正就configure的时候-I -L路径不一样吧,就这么说服自己了。。。
注:最后安装libxcb时,由于Prefix是在/usr/local,需要root权限,直接sudo make install会报错:找不到交叉编译工具链
在这里插入图片描述
在这里插入图片描述
也是一样,先sudo -i ,再make install就可以了

交叉编译libdrm

下载地址 https://dri.freedesktop.org/libdrm/
vi autoconfig.sh:

#!/bin/bash
CC=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
CXX=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
./configure --prefix=/opt/drm_arminstall --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf --disable-cairo-tests
./autoconfig.sh
make 
make install

没遇到啥问题,飘过~

交叉编译mesa

下载地址 ftp://ftp.freedesktop.org/pub/mesa
这个可真是难搞啊,折腾地吐血。。。
使用的也是12.0.0版本
#!/bin/bash

CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ \
PREFIX=/opt/mesa_arminstall \
LIBPEFIX=/opt/drm_arminstall \
./configure --prefix=$PREFIX \
--target=arm-linux-gnueabihf \
--host=arm-linux-gnueabihf \
--enable-gles2 \
--enable-gles1 \
--disable-glx \
--disable-egl \
--disable-dri \
--enable-shared-glapi  \
--with-dri-drivers=swrast  \
LIBDRM_CFLAGS="-I $LIBPREFIX/include -I $LIBPREFIX/include/libdrm" \
LIBDRM_LIBS="-L $LIBPREFIX/lib"

./autoconfig.sh
make
问题来了。。。缺少 <openssl/sha.h>
在这里插入图片描述

注:后续尝试发现mesa-13.0.0也一样的错误
注:若make distclean后运行./autoconfig.sh会提示错误:configure: error: Python mako module v0.3.4 or higher not found
在这里插入图片描述
排查记录:
1)sudo apt-get install libssl-dev 无效(网上去搜基本上都让这么做)
2)sudo apt-get install libssl-ocaml-dev 无效
3)参照 https://bugs.freedesktop.org/show_bug.cgi?id=91898 大神们的讨论,窥探一番
在这里插入图片描述
在这里插入图片描述
如果我没理解错的话,这问题应该是11.1.0开始引入的,修复也只需要改下宏的位置,查看12.0版本源码,看出已经是修改了的啊,什么鬼。。。
在这里插入图片描述
4)尝试更换版本,
使用10.6.9版本,编译结果如下:提示没有 libudev.h文件
在这里插入图片描述
没有那就安装吧,怪我咯
sudo apt-get install libusb-1.0-0-dev
sudo apt-get install libudev-dev (这个本来就已安装了)
再执行make,还是报错,什么鬼啊。。
5)使用17.0.0版本,提示缺少expat.h文件:
在这里插入图片描述
6)使用18.0.0版本,运行.autoconfig.sh时提示xcb需要>1.11.1:
在这里插入图片描述
当场晕倒。。不想再碰它了,求拯救啊。。。
7)冷静一下反思:被网上的一些文章搞乱了,既然是交叉编译,肯定是要交叉编译器有对应头文件,一直apt-get install xxx对交叉编译器又没改变,显然是无用的,故正确的做法应当是去交叉编译一下openssl等程序,再把lib和include包含进mesa中来

8)交叉编译openssl

参考:https://blog.csdn.net/fangye945a/article/details/86658621
使用的是openssl-1.0.2版本
./config no-asm no-async --prefix=/opt/openssl_arminstall
修改Makefile中CC=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc,但是文中说的删除-m64这里并没有找到

9)交叉编译libudev

参考:https://blog.csdn.net/xqhrs232/article/details/110059423
注:试了下libudev编译确实是坑,一堆错误,还是跟文中所说一样,直接编译eudev问题少
CC=/mnt/data/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

./configure --prefix=/opt/eudev_arminstall
–host=arm-linux-gnueabihf
–disable-blkid
–disable-kmod
10)返回去编译Mesa,还是用的12.0版本,修改Mesa中的autoconfig.sh,把编译的openssl\eudev相关头文件和库包含进去:

#!/bin/bash
CC=arm-linux-gnueabihf-gcc
CXX=arm-linux-gnueabihf-g++
PREFIX=/opt/mesa_arminstall
LIBDRMPREFIX=/opt/drm_arminstall
LIBOPENSSLPREFIX=/opt/openssl_arminstall
LIBUDEVPREFIX=/opt/eudev_arminstall

./configure --prefix=$PREFIX \
--target=arm-linux-gnueabihf \
--host=arm-linux-gnueabihf \
--enable-gles2 \
--enable-gles1 \
--disable-glx \
--disable-egl \
--disable-dri \
--enable-shared-glapi  \
--with-dri-drivers=swrast  \
LIBDRM_CFLAGS="-I$LIBDRMPREFIX/include -I$LIBDRMPREFIX/include/libdrm" \
LIBDRM_LIBS="-L$LIBDRMPREFIX/lib" \
OPENSSL_CFLAGS="-I$LIBOPENSSLPREFIX/include" \
OPENSSL_LIBS="-L$LIBOPENSSLPREFIX/lib" \
LIBUDEV_CFLAGS="-I$LIBUDEVPREFIX/include" \
LIBUDEV_LIBS="-L$LIBUDEVPREFIX/lib"

再次编译,提示错误:隐式申明函数’major’:
在这里插入图片描述
对应文件添加#include <sys/sysmacros.h>
继续编译,提示错误xf86drm.h:没有哪个文件或目录:
在这里插入图片描述
检查:文件明明是有的,且configure里面也有包含进来,Makefile中也有保存到LIBDRM_CFLAGS变量,为什么还是会找不到头文件呢?
有对应文件:
有对应文件的
configure也添加了包含:
在这里插入图片描述
生成的Makefile也有保存到LIBDRM_CFLAGS变量:
在这里插入图片描述
排查1)#include 改成"“包含试一试? 不行
在这里插入图片描述
排查2)CC 和CXX改成绝对路径?试了下一样的,不是这个问题
排查3)查看src/gallium/winsys/radeon/drm/Makefile:
在这里插入图片描述
在这里插入图片描述
可知需要的是RADEON_CFLAGS ,故autoconfig.sh增加
RADEON_CFLAGS=”-I L I B D R M P R E F I X / i n c l u d e − I LIBDRMPREFIX/include -I LIBDRMPREFIX/includeILIBDRMPREFIX/include/libdrm"
RADEON_LIBS="-L$LIBDRMPREFIX/lib"
解决问题!编译通过啦
看起来QT Quick需要的一些依赖源码都编译好了的样子,回去重新配置编译一下qt源码吧

修改qmake.conf

返回去修改qt中的qmake.conf,增加:
QMAKE_INCDIR_OPENGL_ES2 = /opt/mesa_arminstall/include
QMAKE_LIBDIR_OPENGL_ES2 = /opt/mesa_arminstall/lib

QMAKE_INCDIR_EGL= Q M A K E I N C D I R O P E N G L E S 2 Q M A K E L I B D I R E G L = QMAKE_INCDIR_OPENGL_ES2 QMAKE_LIBDIR_EGL= QMAKEINCDIROPENGLES2QMAKELIBDIREGL=QMAKE_LIBDIR_OPENGL_ES2

QMAKE_INCDIR_OPENVG= Q M A K E I N C D I R O P E N G L E S 2 Q M A K E L I B D I R O P E N V G = QMAKE_INCDIR_OPENGL_ES2 QMAKE_LIBDIR_OPENVG= QMAKEINCDIROPENGLES2QMAKELIBDIROPENVG=QMAKE_LIBDIR_OPENGL_ES2

QMAKE_LIBS_EGL = -lEGL -lGLESv2
QMAKE_LIBS_OPENVG = -lEGL -lOpenVG -lGLESv2

#QMAKE_LIBS_OPENGL_ES2 = -lglapi -lGLESv2 -lEGL
在这里插入图片描述

修改qt源码中autoconfig.sh

去掉-no-openssl -no-sse2 ,增加 -opengl es2
运行./autoconfig.sh,报错:
Feature ‘opengles2’ was enabled, but the pre-condition ‘config.win32 || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)’ failed
在这里插入图片描述
吐血。。看错误提示的这些个include和library路径也已经在qmake.conf中添加了
。。。。心累,怎么办呢?

未完待续—

**

Logo

更多推荐