QT笔记--嵌入式QT交叉编译与移植(含OpenGL ES2)

介绍

本文记录了QT交叉编译并移植到开发板的过程,并在虚拟机上用QTcreater 开发程序,到开发板上运行。其中重点解决了一些过程中的BUG和坑。

准备工作

1、一个ubuntu系统的电脑(或虚拟机)
2、arm64位开发板
3、QT源代码软件包 qt-everywhere-opensource-src-5.9.6.tar.xz
4、linaro交叉编译器
5、tslib
6、sqlite3
7、开发板根文件系统,其中包含了OpenGL ES3的库文件和头文件。

步骤

一、交叉编译环境搭建

直接参考文章linux_ubuntu_gcc-linaro-7.4.1交叉编译器安装
其中建议安装aarch64最新版交叉编译器

二、tslib和sqlite3的交叉编译与移植

直接参考文章
ARM40之TSLIB移植
移植SQLite3到ARM40-A5

三、交叉编译QT

1、首先解压qt开源源码后,编辑相关的qmake.conf文件,由于我用的是arm64位的开发板,所以编译的是linux-aarch64-gnu-g++这个 目录下的qmake.conf

vim ~/qt-everywhere-opensource-src-5.9.6/qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf

参考以下代码

#
# qmake configuration for building with aarch64-linux-gnu-g++
#

MAKEFILE_GENERATOR      = UNIX
CONFIG                 += incremental
QMAKE_INCREMENTAL_STYLE = sublib

QMAKE_CFLAGS_RELEASE   += -O2 -march=armv8-a -mtune=cortex-a53      #指定处理器架构
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv8-a -mtune=cortex-a53
 
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)


QMAKE_INCDIR = $$[QT_SYSROOT]/usr/include                             #指定sysroot头文件
QMAKE_LIBDIR = $$[QT_SYSROOT]/usr/lib                                 #指定sysroot库文件
QMAKE_LIBDIR += $$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu              #指定sysroot库文件
QMAKE_LIBDIR += $$[QT_SYSROOT]/lib                                    #指定sysroot库文件

QMAKE_INCDIR += /opt/tslib/include /opt/sqlite3/include   #指定tslib和sqlite头文件,需预编译
QMAKE_LIBDIR += /opt/tslib/lib /opt/sqlite3/lib           #指定tslib和sqlite库文件,需预编译


QMAKE_CXXFLAGS += -ludev -lffi                                            #链接选项
QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/usr/lib                    #链接sysroot库文件
QMAKE_LFLAGS += -Wl,-rpath-link $$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu  #链接sysroot库文件
QMAKE_LFLAGS += -Wl,-rpath-link $$[QT_SYSROOT]/lib                        #链接sysroot库文件

QMAKE_INCDIR_OPENGL[_ES2] += \
     $$[QT_SYSROOT]/usr/include \
     $$[QT_SYSROOT]/usr/include/EGL \
     $$[QT_SYSROOT]/usr/include/GLES2 \
     $$[QT_SYSROOT]/usr/include/GLES3 \
     $$[QT_SYSROOT]/usr/include/KHR
QMAKE_LIBDIR_OPENGL[_ES2] += \
     $$[QT_SYSROOT]/usr/lib

QMAKE_INCDIR_EGL += $$QMAKE_INCDIR_OPENGL[_ES2]
QMAKE_LIBDIR_EGL += $$QMAKE_LIBDIR_OPENGL[_ES2]

QMAKE_INCDIR_OPENVG += $$QMAKE_INCDIR_OPENGL[_ES2]
QMAKE_LIBDIR_OPENVG += $$QMAKE_LIBDIR_OPENGL[_ES2]
# QMAKE_LIBS_OPENGL[_ES2] += -lEGL -lGLESv2
QMAKE_LIBS_EGL          = -lEGL -lGLESv2
QMAKE_LIBS_OPENGL[_ES2]   = -lglapi -lGLESv2 -lEGL
#QMAKE_LIBS_OPENGL[_ES2] += -lbrcmEGL -lbrcmGLESv2

# modifications to g++.conf
QMAKE_CC                = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc
QMAKE_CXX               = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++
QMAKE_LINK              = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++
QMAKE_LINK_SHLIB        = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++

# modifications to linux.conf
QMAKE_AR                = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-ar cqs
QMAKE_OBJCOPY           = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-objcopy
QMAKE_NM                = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-nm -P
QMAKE_STRIP             = /opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-strip
load(qt_config)

上述代码主要注意以下几点
(1)、QT_SYSROOT为你开发板的根文件系统,你可以拷贝到电脑上或者挂载到电脑上。下面./configure时会指定这个目录。
(2)、配置sysroot,tslib,sqlite。opengl es2的头文件,库文件,以及编译时的符号和库文件。
(3)、指定交叉编译器路径

2、在qt-everywhere-opensource-src-5.9.6下面新建autoconf.sh文件,保存编译选项

#!/bin/sh
./configure \
-v \
-confirm-license \
-prefix /opt/qt5.9.6 \
-release \
-opensource \
-accessibility \
-make libs \
-xplatform linux-aarch64-gnu-g++ \
-pch \
-tslib \
-sqlite \
-qt-libjpeg \
-qt-libpng \
-qt-zlib \
-qt-freetype \
-opengl es2 \
-nomake examples -nomake tools \
-sysroot ~/sysroot \               //sysroot为开发板的根文件系统
-I ~/sysroot/usr/include \
-L ~/sysroot/usr/lib \
-L ~/sysroot/usr/lib/aarch64-linux-gnu \
-L ~/sysroot/lib

之后sudo chmod a+x autoconf.sh,使其可执行。

3、交叉编译QT

这部分是最恶心的部分,bug尤其多

(1)执行./autoconf.sh,进行编译。

这部分一般不会出错

(2)make -j4

这部分会有问题,会出现.h或者.so缺失问题,举例:如下所示:

In file included from /home/wadexu/debian_buster_renesas_OpenGL_for_QT_15.1/usr/include/sys/stat.h:446,
                 from ../../mkspecs/linux-aarch64-gnu-g++/../linux-g++/qplatformdefs.h:75,
                 from ../../mkspecs/linux-aarch64-gnu-g++/qplatformdefs.h:40,
                 from global/qmalloc.cpp:40:
/opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/lib/gcc/aarch64-none-linux-gnu/10.2.1/include-fixed/bits/statx.h:48:10: fatal error: bits/statx-generic.h: 没有那个文件或目录
   48 | #include <bits/statx-generic.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

编译过程中报错,缺少<bits/statx-generic.h>。其实这个头文件是在sysroot中的,但是由于交叉编译器在搜索头文件路径时,会优先从自己的目录中搜索,导致引用的文件缺失。所以你需要在sysroot中,用find指令找到对应的头文件,并拷贝到/opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/lib/gcc/aarch64-none-linux-gnu/10.2.1/include-fixed/bits这个报错的目录中去。

这种情况大约会出现几十次,都以这种方式处理即可。

之后make执行完成,没有错误再出现(警告不用管)

(3)sudo make install

执行完成后,qt会安装到你~/sysroot/opt/qt5.9.6下面。把qt5.9.6拷贝到你开发板的/opt/下面即可。

四、开发QT程序

参考文章

linux下如何利用QtCreator编译ARM版本的Qt程序

注意以下几点

1、交叉编译QT程序,需要按照上述链接,指定构建环境、配置为交叉编译器,交叉编译后的gdb、交叉编译后的qt。
2、交叉编译的QT程序,选择为release模式,编译无报错即可。点击运行是运行不了的,因为你的电脑是X86的,引用arm64下面相关的.so会报错。

五、在开发板上运行QT程序

1、首先将电脑上交叉编译的qt5.9.6拷贝到开发板上,目录为/opt/qt5.9.6

2、配置开发板环境变量

sudo vim /etc/profile

export QTDIR=/opt/qt5.9.6
export QT_QPA_FONTDIR=$QTDIR/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export PATH=$QTDIR/bin:$PATH
export PKG_CONFIG_PATH=$QTDIR/lib/pkgconfig/$PKG_CONFIG_PATH

source /etc/profile 使其生效

3、链接缺失的fonts文件到qt下面

ln -snf /usr/share/fonts/truetype/dejavu /opt/qt5.9.6/lib/fonts

4、将电脑上编译好的release文件夹拷贝到开发板上,以root身份执行可执行文件。

我的QT程序叫QtDemo,我将其拷贝到开发板上后,如下图所示:
在这里插入图片描述
执行./QtDemo即可在显示屏上出现自己的QT界面。

简单聊聊

想要在开发板上显示界面,你需要安装一个显示服务器,X11或者wayland这种都可以。如果想要用opengl es,需要开发板上包含gpu,并且有gpu厂家提供的opengl es 库文件以及头文件。这些在上述安装过程中,是已经安装好了的。


版权声明:本文为weixin_40293570原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。