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 = KaTeX parse error: Expected 'EOF', got '#' at position 204: … #̲指定sysroot头文件 QM…[QT_SYSROOT]/usr/lib #指定sysroot库文件
QMAKE_LIBDIR += KaTeX parse error: Expected 'EOF', got '#' at position 311: …u #̲指定sysroot库文件 QM…[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,KaTeX parse error: Expected 'EOF', got '#' at position 191: … #̲链接sysroot库文件 QM…[QT_SYSROOT]/usr/lib/aarch64-linux-gnu #链接sysroot库文件
QMAKE_LFLAGS += -Wl,-rpath-link $$[QT_SYSROOT]/lib #链接sysroot库文件

QMAKE_INCDIR_OPENGL[_ES2] +=
< s p a n c l a s s = " t o k e n p u n c t u a t i o n " > [ < / s p a n > Q T S Y S R O O T < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ] < / s p a n > < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > u s r < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > i n c l u d e   <span class="token punctuation">[</span>QT_SYSROOT<span class="token punctuation">]</span><span class="token operator">/</span>usr<span class="token operator">/</span>include \ <spanclass="tokenpunctuation">[</span>QTSYSROOT<spanclass="tokenpunctuation">]</span><spanclass="tokenoperator">/</span>usr<spanclass="tokenoperator">/</span>include [QT_SYSROOT]/usr/include/EGL
< s p a n c l a s s = " t o k e n p u n c t u a t i o n " > [ < / s p a n > Q T S Y S R O O T < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ] < / s p a n > < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > u s r < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > i n c l u d e < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > G L E S 2   <span class="token punctuation">[</span>QT_SYSROOT<span class="token punctuation">]</span><span class="token operator">/</span>usr<span class="token operator">/</span>include<span class="token operator">/</span>GLES2 \ <spanclass="tokenpunctuation">[</span>QTSYSROOT<spanclass="tokenpunctuation">]</span><spanclass="tokenoperator">/</span>usr<spanclass="tokenoperator">/</span>include<spanclass="tokenoperator">/</span>GLES2 [QT_SYSROOT]/usr/include/GLES3
< s p a n c l a s s = " t o k e n p u n c t u a t i o n " > [ < / s p a n > Q T S Y S R O O T < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ] < / s p a n > < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > u s r < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > i n c l u d e < s p a n c l a s s = " t o k e n o p e r a t o r " > / < / s p a n > K H R Q M A K E L I B D I R O P E N G L < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > [ < / s p a n > E S 2 < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ] < / s p a n > < s p a n c l a s s = " t o k e n o p e r a t o r " > + = < / s p a n >   <span class="token punctuation">[</span>QT_SYSROOT<span class="token punctuation">]</span><span class="token operator">/</span>usr<span class="token operator">/</span>include<span class="token operator">/</span>KHR QMAKE_LIBDIR_OPENGL<span class="token punctuation">[</span>_ES2<span class="token punctuation">]</span> <span class="token operator">+=</span> \ <spanclass="tokenpunctuation">[</span>QTSYSROOT<spanclass="tokenpunctuation">]</span><spanclass="tokenoperator">/</span>usr<spanclass="tokenoperator">/</span>include<spanclass="tokenoperator">/</span>KHRQMAKELIBDIROPENGL<spanclass="tokenpunctuation">[</span>ES2<spanclass="tokenpunctuation">]</span><spanclass="tokenoperator">+=</span> [QT_SYSROOT]/usr/lib

QMAKE_INCDIR_EGL += Q M A K E I N C D I R O P E N G L < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > [ < / s p a n > E S 2 < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ] < / s p a n > Q M A K E L I B D I R E G L < s p a n c l a s s = " t o k e n o p e r a t o r " > + = < / s p a n > QMAKE_INCDIR_OPENGL<span class="token punctuation">[</span>_ES2<span class="token punctuation">]</span> QMAKE_LIBDIR_EGL <span class="token operator">+=</span> QMAKEINCDIROPENGL<spanclass="tokenpunctuation">[</span>ES2<spanclass="tokenpunctuation">]</span>QMAKELIBDIREGL<spanclass="tokenoperator">+=</span>QMAKE_LIBDIR_OPENGL[_ES2]

QMAKE_INCDIR_OPENVG += Q M A K E I N C D I R O P E N G L < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > [ < / s p a n > E S 2 < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ] < / s p a n > Q M A K E L I B D I R O P E N V G < s p a n c l a s s = " t o k e n o p e r a t o r " > + = < / s p a n > QMAKE_INCDIR_OPENGL<span class="token punctuation">[</span>_ES2<span class="token punctuation">]</span> QMAKE_LIBDIR_OPENVG <span class="token operator">+=</span> QMAKEINCDIROPENGL<spanclass="tokenpunctuation">[</span>ES2<spanclass="tokenpunctuation">]</span>QMAKELIBDIROPENVG<spanclass="tokenoperator">+=</span>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 库文件以及头文件。这些在上述安装过程中,是已经安装好了的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Linux 系统下交叉编译OpenGLQt,主要分为以下几个步骤: 1. 安装交叉编译工具链。 你需要先下载并安装适当的交叉编译工具链,可以从交叉编译工具链提供商的网站上下载。安装后需要将交叉编译器的路径添加到环境变量中。 2. 下载 Qt 源码。 你需要从 Qt 的官方网站上下载适合你的交叉编译工具链的 Qt 源码,并解压到本地目录。 3. 配置 Qt。 进入 Qt 源码目录,执行以下命令: ``` ./configure -prefix /path/to/install/dir -embedded arm -hostlinux-g++ -xplatform linux-arm-gnueabi-g++ -no-pch -no-gui -opensource -confirm-license ``` 其中,`/path/to/install/dir` 为你想要安装 Qt 的目录。`-embedded arm` 表示你正在为嵌入式 ARM 平台编译 Qt。`-hostlinux-g++` 表示你的编译机是 Linux,使用 GCC 编译器。`-xplatform linux-arm-gnueabi-g++` 表示目标平台是 Linux ARM,使用 GCC 编译器。`-no-pch` 表示不使用预编译头文件,加快编译速度。`-no-gui` 表示不编译 Qt GUI 模块。`-opensource` 表示使用 Qt 的开源许可证。`-confirm-license` 表示确认使用开源许可证。 4. 编译 Qt。 执行 `make` 命令开始编译 Qt。 5. 安装 Qt。 执行 `make install` 命令将 Qt 安装到指定目录。 6. 生成 Qt 应用程序。 在交叉编译工具链下,使用 qmake 工具生成 Qt 应用程序的 Makefile,然后执行 `make` 命令进行编译。在编译时需要加上 `-opengl es2` 参数,表示使用 OpenGL ES 2.0。 以上就是在 Linux 系统下交叉编译OpenGLQt 的步骤。注意,在编译时可能会遇到一些问题,需要根据具体情况进行调试和解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值