qt编译 能在wayland上运行的版本

qt编译 能在wayland上运行的版本

1.编译环境

系统:ubuntu 20
qt版本:5.12.2
交叉编译工具链:通过yocto生成的交叉编译工具链,在进行编译前需要使用“source poky/oe-init-build-env”配置环境,若是其他工具链需要根据自己进行相关配置

2.修改相关文件

2.1 修改qmake.conf 文件

修改 qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf 文件(也可以改其他文件,但后面的-xplatform 要指定对应的文件)

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

MAKEFILE_GENERATOR      = UNIX
CONFIG                 += incremental
QMAKE_INCREMENTAL_STYLE = sublib

include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)

QMAKE_CXXFLAGS               += -I/opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/include/drm -I/opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/include
QMAKE_CFLAGS                 += -I/opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/include/drm  

# modifications to g++.conf
QMAKE_CC                = aarch64-poky-linux-gcc
QMAKE_CXX               = aarch64-poky-linux-g++
QMAKE_LINK              = aarch64-poky-linux-g++
QMAKE_LINK_SHLIB        = aarch64-poky-linux-g++

# modifications to linux.conf
QMAKE_AR                = aarch64-poky-linux-ar cqs
QMAKE_OBJCOPY           = aarch64-poky-linux-objcopy
QMAKE_NM                = aarch64-poky-linux-nm -P
QMAKE_STRIP             = aarch64-poky-linux-strip

# QMAKE_INCDIR_OPENGL_ES2 = /opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/include
# QMAKE_LIBDIR_OPENGL_ES2 = /opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/lib64

# QMAKE_INCDIR_EGL        = /opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/include
# QMAKE_LIBDIR_EGL        = /opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/lib64

# QMAKE_LIBS_EGL         += -lmali
# QMAKE_LIBS_OPENGL_ES2  += -lmali
load(qt_config)
  • 这里的交叉编译工具我用相对路径是因为前面的脚本配置好了环境变量,需要根据自己的情况进行配置
  • 我还添加QMAKE_CXXFLAGS和QMAKE_CFLAGS,这里主要是处理头文件找不到的情况,我这里主要是drm找不到,加了后就解决bug了,如果有头文件找不到的问题都可以用试试
  • 后面还有一些注释掉的东西,例如:QMAKE_LIBS_OPENGL_ES2 ,这里加了反而会出问题,编译出来的qt在运行时会去找mali库,而且还是在pc的路径动态库路径去找,而不是在运行的机器的动态库路径找。这个的添加是参考另外一位用瑞芯微的博主加的,好像有部分opengles的实现依赖mali所以必须添加,我这没这个问题。

2.2 添加run.sh脚本

在源码目录中添加qmake.conf 文件,用于保存configure编译的相关配置

#!/bin/sh  

#PREFIX=/用户目录/qt5.12.2_aarch64_linux/ 
SYSROOT=/opt/poky/3.1.14/sysroots/aarch64-poky-linux
# export LD_LIBRARY_PATH=${SYSROOT}/usr/lib64:$LD_LIBRARY_PATH
export PKG_CONFIG_SYSROOT_DIR=${SYSROOT}
export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig:${SYSROOT}/lib/aarch64-linux-gnu/pkgconfig:${SYSROOT}/usr/share/pkgconfig
export PKG_CONFIG_PATH=${PKG_CONFIG_LIBDIR}
# export STAGING_DIR=${STAGING_DIR}:${SYSROOT}
# export CPLUS_INCLUDE_PATH=/opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/include/c++/8.3.0:$CPLUS_INCLUDE_PATH
./configure -extprefix /home/cwf/qt-sdk  \
-xplatform linux-aarch64-gnu-g++ \
-sysroot  /opt/poky/3.1.14/sysroots/aarch64-poky-linux \
-R /usr/lib64 \
-opensource \
-release \
-shared \
-opengl es2 \
-confirm-license \
-qt-zlib  \
-qt-libpng \
-qt-libjpeg \
-qt-pcre \
-pkg-config \
-nomake examples \
-nomake tests \
-no-pch \
-recheck-all
  • PKG_CONFIG相关的环境变量,执行configure后会去检查各种东西,如果没配PKG_CONFIG相关变量会有警告,我这考虑到pkg-config能帮忙自动找很多包,加上能减少出错的可能性。

  • configure 相关配置
    (1)extprefix :设置输出的SDK目录,prefix也可以设,但会加上sysroot,交叉编译时还是用extprefix 比较方便
    (2)sysroot :交叉编译工具链的根目录,不设置大概报错,qt的依赖基本从这找
    (3)R /usr/lib64 \:指定运行时动态库搜索路径,理论可以不加,一般都找得到,我这里时处理前面找mali库得bug,但没起作用。
    (4)opensource :使用qt开源版本
    (5)release :使用qt发布版本
    (6)shared :编译出动态库
    (7)opengl es2:编译Opengles ,要注意别再后面添加-no-opengl, 会屏蔽opengles的
    (8)-confirm-license: 自动确认许可。
    (9)-qt-zlib -qt-libpng -qt-libjpeg -qt-pcre:我超的一些组件,这种按需加,理论上讲但你知道你缺什么组件,就会加了。
    (10)pkg-config:启动pkg-config,一般交叉编译工具链都带pkg-config,加上能自动找包,减少bug
    (11)-nomake examples -nomake tests :例子和测试,sdk弄好后配qt create,然后编译例子,再传到板子,这样其实也挺快的
    (12)-no-pch :好像和一些预编译相关,我遇到个bug和这个选项有点关系,加着一般不碍事
    (13)recheck-all:丢弃所有缓存的配置测试结果。加着一般不碍事

  • 到这为止会发现好像没有wayland的配置项,不过好像configure也没有wayland的配置项,但运行时会自动检测wayland,成功检测到wayland会有以下输出。(可能不同的工具链会有些区别,我这个只作为能在wayland上运行的一种参考配置。另外,一般用wayland的都支持opengl,所以opengles的选项一般都要加上)

Qt Wayland Drivers:
 EGL .................................... yes
 Raspberry Pi ........................... no
 XComposite EGL ......................... no
 XComposite GLX ......................... no
 DRM EGL ................................ yes
 libhybris EGL .......................... no
 Shm emulation server buffer integration . yes
Qt Wayland Client ........................ yes
Qt Wayland Compositor .................... yes
  • 运行成功后会出现以下输出
Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into '/home/cwf/qt-sdk'.

3. qt运行环境配置

export PATH=$PATH:/qt-sdk/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/ota:/qt-sdk/lib
export QT_PLUGIN_PATH=/qt-sdk/plugins/
export QT_QPA_PLATFORM=wayland
export QML_IMPORT_PATH=/qt-sdk/qml
export QML2_IMPORT_PATH=/qt-sdk/qml
  • PATH 加上qt的执行文件目录
  • LD_LIBRARY_PATH 加上qt库的目录
  • QT_PLUGIN_PATH 设置插件目录,这里的插件主要是各个平台的插件例如wayland插件,x11插件,linuxfb插件
  • QT_QPA_PLATFORM 要设置运行环境,这里是跑在wayland下,所以设置wayland
  • QML_IMPORT_PATH和QML2_IMPORT_PATH 我用上了qml,所以要配置qml

4.编译时的一些错误

4.1 重编建议

编译时有时会出现非常多奇怪的错误,如果发现错误一环扣一环,建议删掉现在的源码,重新复制一份新的来编译,这样很多莫名其妙的错误都会消失。我用make clean,make distclean都是清理不干净的

4.2 头文件找不到

前面讲qmake.conf有提到如何处理

4.3 特殊bug,# include_next 报错

以下是报错logo

linux/usr/include/c++/8.3.0/algorithm:62,
                 from ../../include/QtCore/../../src/corelib/global/qglobal.h:142,
                 from ../../include/QtCore/qglobal.h:1,
                 from ../../include/QtGui/../../src/gui/kernel/qtguiglobal.h:43,
                 from ../../include/QtGui/qtguiglobal.h:1,
                 from accessible/qaccessible.h:40,
                 from accessible/qaccessible.cpp:40:
/opt/poky/3.1.14/sysroots/aarch64-poky-linux/usr/include/c++/8.3.0/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
 #include_next <stdlib.h>

报错位置是交叉编译工具链的源码,而非qt源码,我是没找到一些官方推荐的修改办法,我的修改方法应该可以让qt正常编译下去,仅作为一种修改参考
cstdlib源码

// Need to ensure this finds the C library's <stdlib.h> not a libstdc++
// wrapper that might already be installed later in the include search path.
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next <stdlib.h>
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include <bits/std_abs.h>

修改后

// Need to ensure this finds the C library's <stdlib.h> not a libstdc++
// wrapper that might already be installed later in the include search path.
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
//#include_next <stdlib.h>
#include <stdlib.h>
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include <bits/std_abs.h>

还有另外一种修改方法
fenv.h源码

#include <bits/c++config.h>
#if _GLIBCXX_HAVE_FENV_H
# include_next <fenv.h>
#endif

修改后

#include <bits/c++config.h>
#if _GLIBCXX_HAVE_FENV_H
//# include_next <fenv.h>
# include "../../fenv.h"
#endif

从cstdlib源码注释可以看出用# include_next是希望去找c相关的头文件而不是C++的(stdlib.h,c
++的头文件路径下有份,c下也有份)。我这里报错感觉是# include_next没起作用,没有在排除当前的目录的情况下去寻找c对应的文件。
话虽然是这样说,但改#include <stdlib.h>又不能像# include "…/…/fenv.h"这样指向c的文件,这里#include <stdlib.h>找的还是当前目录下的stdlib.h,如果有遇到类似问题可以试试我的这样的修改,至少能编下去,也能在板子上运行

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要使Qt5.9.6支持Wayland,需要按照以下步骤进行操作: 1. 确保你的系统安装了Wayland和EGL的相关库和驱动程序。 2. 获取Qt5.9.6源代码,并在编译时添加Wayland支持。 3. 在项目代码中使用QtWayland模块,该模块提供了Wayland协议的实现和客户端API。 具体的操作步骤如下: 1. 安装Wayland和EGL的相关库和驱动程序 在Linux系统中,可以使用包管理器安装Wayland和EGL的相关库和驱动程序。例如,在Ubuntu系统中,可以使用以下命令安装: ``` sudo apt-get install libwayland-dev libegl1-mesa-dev ``` 2. 获取Qt5.9.6源代码,并在编译时添加Wayland支持 下载Qt5.9.6源代码,并解压到指定目录中。然后,在终端中进入该目录,并执行以下命令: ``` ./configure -developer-build -opensource -confirm-license -nomake examples -nomake tests -qpa -qt-xcb -qt-wayland -opengl es2 ``` 这条命令会对Qt进行配置,并将Wayland支持添加到编译选项中。其中,-qt-wayland选项启用Wayland支持,-opengl es2选项启用OpenGL ES 2.0支持。 接着,执行以下命令进行编译: ``` make ``` 3. 在项目代码中使用QtWayland模块 在项目代码中,可以使用QtWayland模块提供的API来与Wayland服务器进行交互。例如,可以使用以下代码创建一个Wayland客户端: ``` #include <QtWaylandClient/QtWaylandClient> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); // Create a Wayland client QWaylandClientConnection *connection = new QWaylandClientConnection; QWaylandCompositor *compositor = new QWaylandCompositor(connection); QWaylandShellSurface *shellSurface = new QWaylandShellSurface(compositor); // Show the window shellSurface->setTopLevel(true); shellSurface->setWindowTitle("Hello, Wayland!"); shellSurface->show(); return app.exec(); } ``` 在这个例子中,使用了QtWayland模块提供的QWaylandClientConnection、QWaylandCompositor和QWaylandShellSurface类来创建一个Wayland客户端,并显示一个窗口。 这样,就可以在Qt5.9.6中使用Wayland了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值