Bootstrap

「qt交叉编译arm64」支持xcb、X11

完整的交叉编译好支持xcb的qt库(qt5.15.2、arm64、xcb、no-opengl)

已安装xcb、X11库的交叉编译器(x86_64-aarch64-linux-gnu)

1. 修改qmake.conf,指定交叉编译器

Qt教程3-Ubuntu(x86_64)上配置arm64(aarch64)交叉编译环境及QT编译arm64架构工程

/home/alexios/Qt/5.15.2目录下,有以下内容:

——sha1s.txt:包含文件或版本校验值的文本文件,方便验证文件完整性。

——Src:Qt 源代码所在的文件夹,用于自定义编译或查看代码。

——gcc_64:用于 64 位 GCC 编译器的 Qt 构建版本。

——wasm_32:Qt WebAssembly 的 32 位构建版本,用于将应用程序部署在 Web 浏览器中。

/home/alexios/Qt/5.15.2/Src/qtbase/mkspecs/linux-aarch64-gnu-g++编辑qmake.conf配置文件

# qmake configuration for building with aarch64-linux-gnu-g++
# 用于使用 aarch64-linux-gnu-g++ 工具链构建 Qt 的 qmake 配置文件

MAKEFILE_GENERATOR      = UNIX  # 指定 qmake 生成 Makefile 的类型,UNIX 表示为类 Unix 系统
CONFIG                 += incremental  # 启用增量构建,提升编译效率
QMAKE_INCREMENTAL_STYLE = sublib  # 设置增量构建的样式为子库模式(sublib)

# 包含公共配置文件,减少重复定义
include(../common/linux.conf)       # 包含特定于 Linux 平台的通用配置
include(../common/gcc-base-unix.conf)  # 包含 GCC 编译器的通用配置
include(../common/g++-unix.conf)   # 包含 G++ 编译器的通用配置

# 针对 aarch64-linux-gnu-g++ 的工具链配置
QMAKE_CC                = aarch64-linux-gnu-gcc        # 设置 C 编译器
QMAKE_CXX               = aarch64-linux-gnu-g++        # 设置 C++ 编译器
QMAKE_LINK              = aarch64-linux-gnu-g++        # 设置静态链接器
QMAKE_LINK_SHLIB        = aarch64-linux-gnu-g++        # 设置动态链接器

# 针对其他工具的配置
QMAKE_AR                = aarch64-linux-gnu-ar cqs     # 设置归档工具,用于创建静态库;cqs 表示创建时保持静默
QMAKE_OBJCOPY           = aarch64-linux-gnu-objcopy    # 设置对象文件复制与修改工具
QMAKE_NM                = aarch64-linux-gnu-nm -P      # 设置符号表工具,-P 参数显示原始符号表
QMAKE_STRIP             = aarch64-linux-gnu-strip      # 设置剥离工具,用于删除对象文件中的调试信息

# 加载 Qt 配置,用于包含额外的 Qt 构建规则和模块依赖
load(qt_config)

根据自己交叉编译器的名称修改,本机的交叉编译器已在/etc/profile添加了环境变量,且本机只有一个交叉编译器,故只需修改名称。所使用的交叉编译器是在arm官网下载的,gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu,名称中间需添加无厂家-none-

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

# modifications to linux.conf
QMAKE_AR                = aarch64-none-linux-gnu-ar cqs
QMAKE_OBJCOPY           = aarch64-none-linux-gnu-objcopy
QMAKE_NM                = aarch64-none-linux-gnu-nm -P
QMAKE_STRIP             = aarch64-none-linux-gnu-strip
load(qt_config)

校验交叉编译器的环境变量是否加载成功,显示版本号即为安装成功

~$ aarch64-none-linux-gnu-g++ -v
...
gcc 版本 10.2.1 20201103 (GNU Toolchain for the A-profile Architecture 10.2-2020.11 (arm-10.16))

2. 配置编译选项,执行configure

/home/alexios/Qt/5.15.2/Src/configure

该脚本 configure 是 Qt 源代码编译环境的入口,用于配置 Qt 构建参数,确保必要的环境和依赖正确设置。以下是逐行解释和相关注释:

#! /bin/sh
# 指定使用 /bin/sh 作为脚本解释器

License Header
#############################################################################
## ...
## License header (省略)
#############################################################################

这部分是版权声明和许可证信息,明确了脚本使用的许可协议(商业许可或 GPLv3)。


获取脚本所在目录并定位 configure
srcpath=`dirname $0`  
# 获取脚本所在目录的相对路径

srcpath=`(cd "$srcpath"; pwd)`  
# 将相对路径转换为绝对路径,确保脚本运行时无论从哪里调用都能正确找到资源

configure=$srcpath/qtbase/configure  
# 设置目标配置工具的路径,位于源码目录的 `qtbase/configure`

if [ ! -e "$configure" ]; then  
    echo "$configure not found. Did you forget to run \"init-repository\"?" >&2  
    exit 1  
fi  
# 检查目标配置文件是否存在,如果没有找到,提醒用户是否忘记运行初始化命令 `init-repository`

创建 qtbase 目录并进入
mkdir -p qtbase || exit  
# 确保 `qtbase` 目录存在,如果无法创建则退出脚本

echo "+ cd qtbase"  
cd qtbase || exit  
# 进入 `qtbase` 目录,失败则退出

执行配置命令
echo "+ $configure -top-level $@"  
# 显示将要执行的命令,方便用户调试

exec "$configure" -top-level "$@"  
# 执行 `qtbase/configure`,并传递所有脚本参数(`$@`)
# `-top-level` 参数用于指示配置为顶层构建

使用方法

在Qt下新建build文件夹,存放构建文件;新建Qt5.15.2-arm64,存放编译好的库文件。

进入build文件夹,在命令行中运行该脚本时,可以通过附加参数控制 Qt 的构建选项。例如:

./../5.15.2/Src/configure -prefix /home/alexios/Qt/Qt5.15.2-arm64 -make libs -xplatform linux-aarch64-gnu-g++ -skip qtdeclarative -no-opengl -force-debug-info -mp
  • -prefix:指定安装路径。
  • -make libs:只编译库文件,不包含示例、测试或工具。
  • -platform linux-aarch64-gnu-g++: 指定目标平台为 aarch64,并使用 GNU 工具链,位于/home/alexios/Qt/5.15.2/Src/qtbase/mkspecs下,已在前面修改过qmake.conf,指定自定义的交叉编译器。
  • -skip qtdeclarative:跳过 qtdeclarative 模块的构建,减少编译时间或避免某些依赖。
  • -no-opengl:禁用OpenGL。
  • -static 生成静态库.a文件 -shared 生成动态库so文件(参数可选,默认是shared)
  • -force-debug-info :强制生成调试信息(参数可选)这个参数是让Qt release版本生成.pdb文件,若在release版本下设置了异常捕获信息函数,则打印出错堆栈信息必须要有.pdb文件。如果程序没用开启异常捕获选项,是不需要开启这个参数的。
  • -mp:启动多核编译。

3. 不直接运行命令,可创建脚本执行

步骤2是执行configure生成Makefile,但命令比较长,我们可以创建一个脚本文件,执行该脚本生成Makefile。在build目录下新建autoconfigure.sh脚本。

#!/bin/bash
./../5.15.2/Src/configure -prefix /home/alexios/Qt/Qt5.15.2-arm64 \  # 指定安装路径
# -static \                                  # 静态链接模式,Qt 库将被编译成静态库,而不是动态库(.so)
# -release \                                 # 构建发布版本,生成优化后的版本,适合生产环境
-opensource \                                # 使用开源许可证,适合非商业项目的开发和分发,通常采用 GPL 或 LGPL
-make libs \                                 # 只构建 Qt 核心库(libs),不包括其他工具、示例和测试程序
-xplatform linux-aarch64-gnu-g++ \          # 指定交叉编译平台,目标平台为 ARM64 架构,使用 GNU 工具链
# -optimized-qmake \                         # 优化后的 qmake 工具,提升构建效率
# -pch \                                     # 预编译头文件(PCH)功能,减少编译时间,尤其是包含大型头文件时
# -qt-zlib \                                 # Qt 对 zlib 库的支持,用于压缩和解压缩操作,通常用于处理数据压缩
# -skip qt3d \                               # 跳过 qt3d 模块的编译,如果不需要 3D 图形功能,可以禁用该模块
# -skip qtcanvas3d \                         # 跳过 qtcanvas3d 模块的编译,如果不需要 Canvas 3D 支持,可以禁用该模块
# -skip qtpurchasing \                       # 跳过 qtpurchasing 模块的编译,如果不需要购买相关功能,可以禁用该模块
# -no-sse2 \                                 # 禁用 SSE2 指令集,适用于较老的 CPU 或不需要使用这些指令的情况
# -no-sse3 \                                 # 禁用 SSE3 指令集,减少对该指令集的依赖
# -no-ssse3  \                               # 禁用 SSSE3 指令集(更高效的 SIMD 扩展)
# -no-sse4.1 \                               # 禁用 SSE4.1 指令集,减少对该指令集的依赖
# -no-sse4.2  \                              # 禁用 SSE4.2 指令集,进一步优化对特定硬件的支持
# -no-avx \                                  # 禁用 AVX(高级向量扩展)指令集
# -no-avx2 \                                 # 禁用 AVX2(更高级别的 AVX 指令集)支持
# -no-mips_dsp \                             # 禁用 MIPS DSP(数字信号处理)指令集,仅适用于 MIPS 架构的设备
# -no-mips_dspr2 \                           # 禁用 MIPS DSP R2 指令集,仅适用于 MIPS 架构的设备
# -qt-zlib \                                 # Qt 内置的 zlib 库,用于数据压缩和解压缩
# -no-openssl \                              # 禁用 OpenSSL 库,OpenSSL 用于处理加密和 SSL/TLS 操作
# -no-xcb \                                  # 禁用 X11 系统的 XCB 库,适用于没有桌面环境或使用其他图形系统的设备
# -no-cups \                                 # 禁用 CUPS(Common UNIX Printing System)打印支持
# -no-iconv \                                # 禁用字符集转换(iconv)库
# -no-evdev  \                               # 禁用 evdev(输入事件设备)支持,适用于不需要触摸屏或其他输入设备支持
# -no-icu  \                                 # 禁用 ICU(国际化字符库)支持
# -no-fontconfig \                           # 禁用 Fontconfig 库,Fontconfig 用于字体的配置和管理
# -nomake examples \                         # 禁用示例代码的编译,适合不需要示例代码的构建
# -nomake tools \                            # 禁用 Qt 工具的编译,通常仅需要 Qt 库而不需要工具时使用
# -skip qtvirtualkeyboard \                  # 跳过 Qt Virtual Keyboard 模块的编译
# -qpa linuxfb \                             # 设置 QPA(Qt Platform Abstraction)平台为 Linux framebuffer,适用于没有 X11 或其他图形界面的设备
-no-opengl \                                 # 禁用 OpenGL 图形渲染支持,适用于不需要图形硬件加速的嵌入式设备
# -no-libinput \                             # 禁用 libinput 输入设备支持
# -no-gstreamer \                            # 禁用 GStreamer 多媒体框架支持
# -no-system-proxies \                       # 禁用系统代理设置
# -no-slog2  \                               # 禁用 slog2 日志系统支持
# -no-lgmon \                                # 禁用 Linux 内核日志监控
# -linuxfb \                                 # 使用 Linux framebuffer 支持,适用于没有 X11 图形界面的设备
# -v \                                       # 显示详细的输出,显示更多的编译过程信息,适合调试和故障排除
-qt-libjpeg \                                # Qt 对 libjpeg 图像库支持,用于加载和保存 JPEG 格式的图像
-qt-libpng \                                 # Qt 对 libpng 库的支持,用于加载和保存 PNG 格式的图像
# -no-libproxy \                             # 禁用 libproxy 库,libproxy 用于管理网络代理设置
# -no-dbus	                                 # 禁用 D-Bus 支持,D-Bus 是一个用于进程间通信的消息总线系统
# -no-glib	                                 # 禁用 GLib 库,GLib 是一个跨平台的 C 库,通常用于桌面环境
# -no-compile-examples \                     # 禁用示例代码的编译,适合不需要示例代码的构建
-skip qtdeclarative \                        # 跳过 qtdeclarative 模块(如 QML 和 Qt Quick)的编译,如果不需要 QML 功能时可以禁用该模块

修改权限

sudo chmod +x autoconfigure.sh 

执行脚本

./autoconfigure.sh

提示选择版本,输入o;询问是否接受协议,输入y。

make -j12 		#编译
make install	#安装

如果要自定义配置模块,可以./configure -help查看具体命令。

  • 确保脚本开头是正确的 #!/bin/bash,并且选项是完整的命令的一部分。
  • 确保每行末尾的 \ 后无任何字符(包括空格或制表符)。
#!/bin/bash
./../5.15.2/Src/configure \
-prefix /home/alexios/Qt/Qt5.15.2-arm64 \
-opensource \
-make libs \
-xplatform linux-aarch64-gnu-g++ \
-no-opengl \
-qt-libjpeg \
-qt-libpng \
-skip qtdeclarative

4. QT官网关于交叉编译说明

QT官网关于交叉编译说明

  • 自Qt5.0发布以来,Qt不再包含自己的窗口系统(QWS)实现。对于单进程用例,Qt平台抽象是一个优秀的解决方案。Wayland可以支持多种图形流程。有多种平台插件可用于嵌入式Linux系统:EGLFS,LinuxFB,DirectFB,Wayland。

  • 如果默认值不合适,则可以使用QT_QPA_PLATFORM环境变量参数来请求另一个插件。或者,对于快速测试,可以使用相同的语法来使用-platform命令行。

    export QT_QPA_PLATFORM=wayland
    ./test
    或者
    ./test -platform wayland
    

    经测试,ubuntu x86_64 中qt使用xcb后端作为显示平台。

    ~$ echo $XDG_SESSION_TYPE
    x11
    
  • 配置特定设备,构建给定设备的Qt需要一个工具链和一个sysroot。

  • 通过指定-sysroot,configure的功能检测测试使用的包含文件和库以及Qt本身都是从指定位置取代,而不是主机PC的标准位置。这意味着在主机上安装开发包没有意义。例如,要获得libinput支持,在主机环境中安装libinput开发头文件和库是不够的或不必要的。相反,目标体系结构的头文件和库(例如ARM)必须存在于sysroot中。

  • 执行交叉编译时也支持pkg-config。 configure会自动设置PKG_CONFIG_LIBDIR以使pkg-config报告编译器和链接器设置基于sysroot而不是主机。

  • Qt不再在lib/fonts目录中提供任何字体。这意味着它需要平台(系统映像)来提供必要的字体。

  • 作为一般规则,不建议在嵌入式设备上使用XCB。像eglfs这样的插件可能会提供更好的性能和硬件加速。

  • Wayland是一个轻量级视窗系统,Qt Wayland模块提供了一个允许Qt应用程序连接Wayland合成器的路径平台插件。

5. 添加xcb支持

5.1 编译xcb

根据Configure meta

-xcb-xlib............. Enable Xcb-Xlib support [auto]
-xcb ............... Enable X11 support [auto] (Linux only)

在脚本中加入-xcb-xlib-xcb,执行脚本后报错:

ERROR: Feature 'xcb' was enabled, but the pre-condition 'features.thread && libs.xcb && tests.xcb_syslibs && features.xkbcommon-x11' failed.

ERROR: Feature 'xcb-xlib' was enabled, but the pre-condition 'features.xlib && libs.xcb_xlib' failed.

缺少依赖库

交叉编译QT6源码-支持xcb(二)

【ARM开发】交叉编译Qt源码之(1)编译xcb

【ARM开发】交叉编译Qt源码之(2)编译X11

【ARM开发】交叉编译Qt源码之(4)添加xcb支持

交叉编译libxcb与X11

根据以上博客,下载所有的依赖包,注意需要按顺序,以下是我的包编译脚本:

#!/bin/sh

# 添加交叉编译工具链路径
export PATH=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin:$PATH

# 设置交叉编译器和库路径
export SYSROOT=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu
export CFLAGS="-I$SYSROOT/include -std=c99"
export LDFLAGS="-L$SYSROOT/lib -Wl,-rpath-link,$SYSROOT/lib"
export PKG_CONFIG_PATH=$SYSROOT/lib/pkgconfig:$SYSROOT/share/pkgconfig

# 运行配置脚本
echo "运行配置脚本..."
./configure \
  --prefix=$SYSROOT \
  --host=aarch64-none-linux-gnu \
  --enable-option-checking

# 检查配置是否成功
if [ $? -ne 0 ]; then
  echo "配置失败,请检查日志。"
  exit 1
fi

# 开始编译
echo "开始编译..."
make -j$(nproc)

# 检查编译是否成功
if [ $? -ne 0 ]; then
  echo "编译失败,请检查日志。"
  exit 1
fi

# 安装编译结果
echo "安装编译结果..."
make install

# 检查安装是否成功
if [ $? -ne 0 ]; then
  echo "安装失败,请检查日志。"
  exit 1
fi

echo "编译和安装完成!"

在编译libxkbcommon中

--cross-file cross.txt \
-Denable-x11=false \
-Denable-wayland=false \
-Denable-docs=false \
-Denable-xkbregistry=false \

x11禁用,故不会有libxkbcommon-x11,若要生成该库,还需要x11的相关依赖库。

编译之前查看交叉编译器中是否有相关库

ls /usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/lib | grep libxkbcommon-x11

将qmake.conf中的QMAKE_LIBS += -lxkbcommon-x11删除,否则会报错!

QMAKE_LIBS              += -lXau
QMAKE_LIBS              += -lxcb
QMAKE_LIBS              += -lxcb-xkb
QMAKE_LIBS              += -lxkbcommon
QMAKE_LIBS              += -lxkbcommon-x11

执行./configure后的输出

Features used by QPA backends:
  evdev .................................. yes
  libinput ............................... no
  INTEGRITY HID .......................... no
  mtdev .................................. no
  tslib .................................. no
  xkbcommon .............................. yes
  X11 specific:
    XLib ................................. no
    XCB Xlib ............................. no
    EGL on X11 ........................... no
    xkbcommon-x11 ........................ no
QPA backends:
  DirectFB ............................... no
  EGLFS .................................. no
  LinuxFB ................................ yes
  VNC .................................... yes

缺少XCB后端!正常来说应该是

 QPA backends:
	XCB:
		Using system-provided-xcb-input......yes

为什么没有 XCB 后端?

  1. 缺少 xkbcommon-x11XCB 后端依赖于 xkbcommon-x11,用于处理与 X 服务器的键盘输入。由于你没有启用 xkbcommon-x11,Qt 配置过程中未能检测到它,从而无法启用 XCB 后端。
  2. 配置中缺少 xkbcommon-x11:你提供的配置参数中明确包括了 xkbcommon,但是没有显式启用 xkbcommon-x11xkbcommon-x11 是 X11 的扩展,它处理与 xcb 的交互,如果缺少该库,XCB 后端无法完全工作。
  3. 系统中没有安装 xkbcommon-x11:如果系统中没有正确安装 xkbcommon-x11,Qt 在配置时也无法找到它,并因此禁用 XCB 后端。

5.2 编译X11

编译X11报错:

/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/include/X11/Xtrans/Xtranslcl.c:84:11: fatal error: sys/stropts.h: 没有那个文件或目录
   84 | # include <sys/stropts.h>
      |           ^~~~~~~~~~~~~~~
compilation terminated.

fatal error:stropts.h:没有那个文件或目录-CSDN博客

  • 工具链运行在一个现代系统中,而 sys/stropts.h 是一个老旧的头文件,现代 Linux 系统已经移除了它。如果你的代码不实际使用 stropts.h 的功能,那么伪造一个空的头文件是最简单的解决方法。

创建伪造的 stropts.h 文件以绕过错误:

sudo mkdir /usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/include/sys #创建sys文件夹
cd sys
sudo gedit stropts.h
#ifndef SYS_STROPTS_H
#define SYS_STROPTS_H

// 伪造文件,仅用于绕过编译错误
// 实际功能未实现,若相关功能被调用可能导致运行时问题

#endif // SYS_STROPTS_H

libX11链接库报错:

make[3]: 进入目录“/home/alexios/Qt/xcb_packages/libX11-1.7.2/src”
  CCLD     libX11.la
/usr/bin/ld: /usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/lib/libxcb.so: error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status
make[3]: *** [Makefile:907:libX11.la] 错误 1

--host=aarch64-none-linux-gnu不要去掉none,确保前后编译的库的选项一致!

/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/10.2.1/../../../../aarch64-none-linux-gnu/bin/ld: xlibi18n/.libs/libi18n.a(lcDynamic.o): error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status
make[3]: *** [Makefile:907:libX11.la] 错误 1

删除包文件夹所有文件重新编译,终于成功生成libX11库了!

编译X11的脚本myconfigure.sh

#! /bin/sh
export PATH=$PATH:/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/lib/pkgconfig:/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/share/pkgconfig
./configure --prefix=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu \
--host=aarch64-none-linux-gnu \
--enable-option-checking \
--enable-unix-transport \
--enable-tcp-transport \
--enable-ipv6 \
--enable-local-transport \
--enable-malloc0returnsnull
make
make install

5.3 编译xkbcommon-x11

libxkbcommon通过附带选项编译libxkbcommon-x11

#! /bin/sh
export PKG_CONFIG_PATH=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/lib/pkgconfig:$PKG_CONFIG_PATH
meson setup build --prefix=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu \
--buildtype release \
--cross-file cross.txt \
-Denable-x11=true \
-Denable-wayland=false \
-Denable-docs=false \
-Denable-xkbregistry=false \
-Dxkb-config-root=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/lib/pkgconfig
#编译安装
ninja -C build install

将-Denable-x11改为true,添加pkgconfig 路径,确保pkgconfig 工具找到xcb-xkb.pc等依赖文件。

5.4 qt配置和构建

/home/alexios/Qt/5.15.2/Src/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

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

QMAKE_INCDIR            += /usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/include
QMAKE_LIBDIR            += /usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/lib
QMAKE_LIBS              += -lXau
QMAKE_LIBS              += -lxcb
QMAKE_LIBS              += -lxcb-xkb
QMAKE_LIBS              += -lxkbcommon
QMAKE_LIBS              += -lxkbcommon-x11

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

# modifications to linux.conf
QMAKE_AR                = aarch64-none-linux-gnu-ar cqs
QMAKE_OBJCOPY           = aarch64-none-linux-gnu-objcopy
QMAKE_NM                = aarch64-none-linux-gnu-nm -P
QMAKE_STRIP             = aarch64-none-linux-gnu-strip
load(qt_config)

执行配置脚本

~/Qt/build$ ./autoconfigure.sh

输出结果

Features used by QPA backends:
  evdev .................................. yes
  libinput ............................... no
  INTEGRITY HID .......................... no
  mtdev .................................. no
  tslib .................................. no
  xkbcommon .............................. yes
  X11 specific:
    XLib ................................. no
    XCB Xlib ............................. no
    EGL on X11 ........................... no
    xkbcommon-x11 ........................ no
QPA backends:
  DirectFB ............................... no
  EGLFS .................................. no
  LinuxFB ................................ yes
  VNC .................................... yes

弄了好久,xkbcommon-x11依然没有启用,QPA后端依然没有XCB

构建加上-skip qtdeclarative,不然编译报错。

交叉编译qt以及相关依赖软件_WenCoo的技术博客_51CTO博客

Qt移植:Ubuntu18.04 交叉编译qt5.12.7详细教程配置编译qt-everywhere-src-5.12.7

  • export只用于当前终端!对于运行的configure,还需要-L和-I显示指定库文件和头文件路径!它并不会自动传递环境变量!

    怪不得在config.log中会报错找不到xkbcommon-x11和xcb-icccm等相关库!路径为空[ ]

  • 关于 -sysroot可以不指定,不然会报很多缺少依赖库的错误,直接指定库文件和头文件路径即可。

  • 关于缺少依赖文件的报错,如undefined ***,可以检查并下载相关库;若已经成功编译并安装相关库,检查安装目录下是否有对应的头文件、库文件和pc文件,检查脚本中的路径是否正确。

完整的qt构建脚本:

#!/bin/bash

# 设置交叉编译工具链路径
export PATH=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin:$PATH

# 设置交叉编译器和库路径
export SYSROOT=/usr/local/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu
export CFLAGS="-I$SYSROOT/include -I$SYSROOT/include/xcb -I$SYSROOT/include/xkbcommon -I$SYSROOT/include/X11 -std=c99"
export LDFLAGS="-L$SYSROOT/lib"
export PKG_CONFIG_PATH=$SYSROOT/lib/pkgconfig:$SYSROOT/share/pkgconfig

# 设置 pkg-config 和库路径
export PKG_CONFIG_SYSROOT_DIR=$SYSROOT
export PKG_CONFIG_LIBDIR=$SYSROOT/lib/pkgconfig
export LD_LIBRARY_PATH=$SYSROOT/lib:$LD_LIBRARY_PATH

./../5.15.2/Src/configure \
-prefix /home/alexios/Qt/Qt5.15.2-arm64 \
-xplatform linux-aarch64-gnu-g++ \
-opensource \
-release \
-shared \
-confirm-license \
-make libs \
-nomake examples \
-nomake tools \
-nomake tests \
-no-opengl \
-qt-libjpeg \
-qt-libpng \
-qt-zlib  \
-qt-pcre \
-xkbcommon \
-xcb \
-qpa xcb \
-skip qtdeclarative \
-I$SYSROOT/include \
-I$SYSROOT/include/xcb \
-I$SYSROOT/include/xkbcommon \
-I$SYSROOT/include/X11 \
-L$SYSROOT/lib \
-recheck-all

构建成功!xkbcommon-x11已启用,QPA后端有XCB了!

Features used by QPA backends:
  evdev .................................. yes
  libinput ............................... no
  INTEGRITY HID .......................... no
  mtdev .................................. no
  tslib .................................. no
  xkbcommon .............................. yes
  X11 specific:
    XLib ................................. no
    XCB Xlib ............................. no
    EGL on X11 ........................... no
    xkbcommon-x11 ........................ yes
QPA backends:
  DirectFB ............................... no
  EGLFS .................................. no
  LinuxFB ................................ yes
  VNC .................................... yes
  XCB:
  	  Using system-provided-xcb-input......yes

插件也有libqxcb.so了

~/Qt/Qt5.15.2-arm64/plugins/platforms$ ls
libqlinuxfb.so  libqminimal.so  libqoffscreen.so  libqvnc.so  libqxcb.so

6. 添加wayland支持

  • x86_64架构上需要X11和xcb,而在arm64运行qt更倾向于使用 EGLFS、Wayland 或 Linux Framebuffer,而非 X11。

    • 但目标开发板RK3588基于debian的桌面系统,使用的是X11显示平台。

    • RK3588的buildroot是wenton桌面,基于wayland。

    • ubuntu x86_64是使用 GNOME桌面环境,从 Ubuntu 17.10 开始 GNOME 成为默认桌面系统。

      ~$ echo $XDG_CURRENT_DESKTOP
      ubuntu:GNOME
      
  • -platform linuxfb 运行 Qt 程序时,界面没有立即显示,而是在重启后才短暂出现,可能是因为没有安装或启用了Framebuffer平台的插件,导致应用程序无法正常运行。

  • Framebuffer性能过低,应选择在Wayland平台上运行qt程序。

  • /Qt5.15.2-arm64/plugins/platforms上有linuxfb、minimal、offscreen、vnc插件。

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

;