Qt5.12.9库交叉编译指南——RK3568
参考链接
https://doc.embedfire.com/linux/rk356x/Qt/zh/latest/lubancat_qt/install/install_arm_2.html#
1 核心思想
1.2 基本架构
本指南基于以下架构实现交叉编译:
- 编译环境:x86 PC主机
- 工具链:armv8交叉编译链
- 依赖系统:RK3568根文件系统
- 产出目标:
- 可在x86主机上使用的交叉编译qmake工具
- ARM板上Qt程序运行所需的库文件
1.3 关键问题解析
- 为什么需要交叉编译qmake工具?
- 性能考量:利用x86主机的强大计算能力进行编译
- 开发便利:在开发主机上完成编译过程,而非在资源有限的ARM板上
- 效率提升:显著加快编译速度,提高开发效率
- 为什么需要RK3568的根文件系统?
- 环境一致性:确保编译环境与目标运行环境一致
- 依赖解决:提供必要的库文件和头文件
- 兼容性保证:避免因系统差异导致的运行问题
2 根文件系统准备
安装下面的软件:
# x11相关
sudo apt-get install -y libx11-dev freetds-dev libxcb-xinput-dev libpq-dev libiodbc2-dev firebird-dev \
libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev \
libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev \
libxcb-icccm4 libxcb-icccm4-dev libxcb-sync1 libxcb-sync-dev libxcb-render-util0 \
libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev \
libxcb-glx0-dev libxi-dev libdrm-dev libxcb-xinerama0 libxcb-xinerama0-dev libatspi2.0-dev \
libxcursor-dev libxcomposite-dev libxdamage-dev libxss-dev libxtst-dev libpci-dev libcap-dev \
libxrandr-dev libdirectfb-dev libaudio-dev libxkbcommon-x11-dev
# gst相关
sudo apt-get install -y libgstreamer1.0-0 gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools libunwind-dev
# opengl相关
sudo apt-get install -y libegl1-mesa-dev libgbm-dev libgles2-mesa-dev libgles2-mesa
# 其他等等
sudo apt-get install -y libfreetype6-dev libicu-dev libsqlite3-dev libasound2-dev libnss3-dev \
libxss-dev libxtst-dev libpci-dev libcap-dev libsrtp0-dev libxrandr-dev libdirectfb-dev libaudio-dev \
libavcodec-dev libavformat-dev libswscale-dev libts-dev libfontconfig1-dev
sudo apt-get install -y libssl-dev libdbus-1-dev libglib2-dev rsyslog libjpeg-dev
# 安装可能需要相关工具
sudo apt-get install gcc g++ gdbserver rsync
sudo apt install build-essential libgl1-mesa-dev libxkbcommon-dev libxkbcommon-x11-dev \
libxcb-xinerama0-dev libxcb-xinerama0 libxcb-icccm4-dev libxcb-image0-dev \
libxcb-keysyms1-dev libxcb-render-util0-dev libxcb-shape0-dev libxcb-sync-dev \
libxcb-xfixes0-dev libxcb-xkb-dev libxcb1-dev libxcb1 libxrender-dev libx11-dev \
libx11-xcb-dev libxi-dev libxext-dev libfontconfig1-dev libfreetype6-dev \
libpng-dev libjpeg-dev libssl-dev libdbus-1-dev libicu-dev libpulse-dev \
libasound2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt install libwayland-dev
sudo apt install python
sudo apt install libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-xinerama-dev libxkbcommon-dev libxkbcommon-x11-dev
# 下面这几个包在Ubuntu20.04中安装失败,原因是改名了
sudo apt install libglib2-dev libsrtp0-dev libxcb-xinerama-dev
# 更新为
sudo apt install libglib2.0-dev libsrtp2-dev libxcb-xinerama0-dev
sudo apt install qemu-user-static
3 x86编译主机软件安装
- 基本软件
sudo apt-get update sudo apt-get install gcc git bison python gperf pkg-config gdb-multiarch sudo apt install build-essential - 交叉编译链,Ubuntu20.04使用apt直接安装,版本要求如下 ```bash ➜ qt-everywhere-src-5.12.9 /usr/bin/aarch64-linux-gnu-gcc –version aarch64-linux-gnu-gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
➜ qt-everywhere-src-5.12.9 /usr/bin/aarch64-linux-gnu-g++ –version aarch64-linux-gnu-g++ (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
➜ qt-everywhere-src-5.12.9 /usr/bin/aarch64-linux-gnu-ld –version GNU ld (GNU Binutils for Ubuntu) 2.34 Copyright (C) 2020 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) a later version. This program has absolutely no warranty. ➜ qt-everywhere-src-5.12.9 /usr/bin/aarch64-linux-gnu-ar –version GNU ar (GNU Binutils for Ubuntu) 2.34 Copyright (C) 2020 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) any later version. This program has absolutely no warranty.
## 4 Qt源码准备
[https://download.qt.io/archive/qt/5.12/5.12.9/single/](https://download.qt.io/archive/qt/5.12/5.12.9/single/)
下载qt-everywhere-src-5.12.9.tar.xz
## 5 配置编译
### 5.1 挂载根文件系统
- 挂载根文件系统到sysroot
### 5.2 增加版型
复制`qt-everywhere-src-5.12.9/qtbase/mkspecs/devices/linux-generic-g++`,改名为`qt-everywhere-src-5.12.9/qtbase/mkspecs/devices/linux-rk3568-g++`
修改qmake.conf,根据根文件系统的实际路径去改(涉及$$[QT_SYSROOT]的路径)
```bash
#
# qmake configuration for the rk3568-HW running Linux for Ubuntu 20.04
#
include(../common/linux_device_pre.conf)
QMAKE_LIBS_EGL += -lEGL -lmali
QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL -lmali
QMAKE_CFLAGS = -march=armv8-a
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_LFLAGS += -static-libstdc++
QMAKE_INCDIR_POST += \
$$[QT_SYSROOT]/usr/include \
$$[QT_SYSROOT]/usr/include/aarch64-linux-gnu
QMAKE_LIBDIR_POST += \
$$[QT_SYSROOT]/usr/lib \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu
QMAKE_RPATHLINKDIR_POST += \
$$[QT_SYSROOT]/usr/lib \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu
DISTRO_OPTS += aarch64
DISTRO_OPTS += deb-multi-arch
include(../common/linux_arm_device_post.conf)
load(qt_config)
5.3 配置编译选项
- 进入Qt源码根目录,使用以下配置
configure选项: ./configure \ -sysroot "/home/hw/hdd/rk3568_qt_5129/sysroot" \ -hostprefix "/home/hw/hdd/rk3568_qt_5129/qt-everywhere-src-5.12.9/host" \ -extprefix "/home/hw/hdd/rk3568_qt_5129/qt-everywhere-src-5.12.9/ext" \ -device "linux-rk3568-g++" \ -device-option CROSS_COMPILE="/usr/bin/aarch64-linux-gnu-" \ -release \ -opensource \ -confirm-license \ -nomake tests \ -make libs \ -opengl es2 \ -eglfs \ -xcb \ -dbus \ -syslog \ -sqlite \ -tslib \ -fontconfig \ -pkg-config \ -skip qtscript \ -skip qtwebengine \ -no-use-gold-linker \ -v \ -recheck-all主要是修改sysroot(根文件系统路径)、hostprefix(交叉编译qmake路径)、extprefix(目标库路径)、device(增加rk3568版型)、-device-option CROSS_COMPILE(指定交叉编译链路径)
配置成功后,将会输出config.summary文件,由于我们配置了-opengl es2,需要关注EGLFS和openGL ES系列是否是yes
QPA backends:
DirectFB ............................... no
EGLFS .................................. yes
EGLFS details:
EGLFS OpenWFD ........................ no
EGLFS i.Mx6 .......................... no
EGLFS i.Mx6 Wayland .................. no
EGLFS RCAR ........................... no
EGLFS EGLDevice ...................... yes
EGLFS GBM ............................ yes
EGLFS VSP2 ........................... no
EGLFS Mali ........................... no
EGLFS Raspberry Pi ................... no
EGLFS X11 ............................ yes
...
Qt Gui:
OpenGL:
Desktop OpenGL ....................... no
OpenGL ES 2.0 ........................ yes
OpenGL ES 3.0 ........................ yes
OpenGL ES 3.1 ........................ yes
OpenGL ES 3.2 ........................ yes
5.4 编译安装
如果配置成功,在源码路径下make就可以了。
如果make成功,使用make install安装到刚刚配置的hostprefix和extprefix下,至此Qt交叉编译成功,hostprefix下存放可在x86主机上使用的交叉编译qmake工具,ext下存放ARM板上Qt程序运行所需的库文件。
6 bug解决
在make的时候,可能会报类似的错误
/home/hw/hdd/rk3568_qt_5129/sysroot/lib/aarch64-linux-gnu/libicuuc.so /home/hw/hdd/rk3568_qt_5129/sysroot/lib/aarch64-linux-gnu/libicudata.so /usr/aarch64-linux-gnu/lib/libdl.so /home/hw/hdd/rk3568_qt_5129/sysroot/usr/lib/aarch64-linux-gnu/libpcre2-16.so /home/hw/hdd/rk3568_qt_5129/sysroot/usr/lib/aarch64-linux-gnu/libgthread-2.0.so /home/hw/hdd/rk3568_qt_5129/sysroot/usr/lib/aarch64-linux-gnu/libglib-2.0.so -L/home/hw/hdd/rk3568_qt_5129/sysroot/usr/lib -L/home/hw/hdd/rk3568_qt_5129/sysroot/lib/aarch64-linux-gnu -L/home/hw/hdd/rk3568_qt_5129/sysroot/usr/lib/aarch64-linux-gnu -Wl,-Bdynamic -lpthread
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /home/hw/hdd/rk3568_qt_5129/sysroot/lib/aarch64-linux-gnu/libpthread.a(pthread_create.o): in function `allocate_stack':
/build/glibc-kCnsjY/glibc-2.31/nptl/allocatestack.c:525: undefined reference to `_dl_stack_flags'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/allocatestack.c:525: undefined reference to `_dl_stack_flags'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/allocatestack.c:647: undefined reference to `_dl_stack_flags'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/allocatestack.c:647: undefined reference to `_dl_stack_flags'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /home/hw/hdd/rk3568_qt_5129/sysroot/lib/aarch64-linux-gnu/libpthread.a(unwind.o): in function `_jmpbuf_sp':
/build/glibc-kCnsjY/glibc-2.31/nptl/../sysdeps/aarch64/jmpbuf-offsets.h:52: undefined reference to `__pointer_chk_guard_local'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/../sysdeps/aarch64/jmpbuf-offsets.h:52: undefined reference to `__pointer_chk_guard_local'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /home/hw/hdd/rk3568_qt_5129/sysroot/lib/aarch64-linux-gnu/libpthread.a(nptl-init.o): in function `__pthread_initialize_minimal_internal':
/build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:335: undefined reference to `_dl_pagesize'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:335: undefined reference to `_dl_pagesize'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:344: undefined reference to `_dl_pagesize'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:360: undefined reference to `_dl_init_static_tls'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:362: undefined reference to `_dl_wait_lookup_done'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:360: undefined reference to `_dl_init_static_tls'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:362: undefined reference to `_dl_wait_lookup_done'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /home/hw/hdd/rk3568_qt_5129/sysroot/lib/aarch64-linux-gnu/libpthread.a(nptl-init.o): in function `__pthread_get_minstack':
/build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:393: undefined reference to `_dl_pagesize'
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /build/glibc-kCnsjY/glibc-2.31/nptl/nptl-init.c:393: undefined reference to `_dl_pagesize'
collect2: error: ld returned 1 exit status
make[3]: *** [Makefile:1193: ../../lib/libQt5Core.so.5.12.9] Error 1
make[3]: Leaving directory '/mnt/hdd/rk3568_qt_5129/qt-everywhere-src-5.12.9/qtbase/src/corelib'
make[2]: *** [Makefile:200: sub-corelib-make_first] Error 2
make[2]: Leaving directory '/mnt/hdd/rk3568_qt_5129/qt-everywhere-src-5.12.9/qtbase/src'
make[1]: *** [Makefile:51: sub-src-make_first] Error 2
make[1]: Leaving directory '/mnt/hdd/rk3568_qt_5129/qt-everywhere-src-5.12.9/qtbase'
make: *** [Makefile:84: module-qtbase-make_first] Error 2
错误信息显示在链接阶段出现了多个未定义的引用,如_dl_stack_flags, __pointer_chk_guard_local, _dl_pagesize等,这些符号通常由动态链接器提供。而在链接过程中使用了静态链接的pthread库(libpthread.a)而不是动态链接的版本(libpthread.so)。需要检查sysroot目录中libpthread的动态库是否存在。
发现是因为sysroot中的软链接使用了绝对路径,导致x86在使用交叉编译链编译时使用了错误的路径:
➜ sysroot ls -al ./usr/lib/aarch64-linux-gnu/libpthread.so
lrwxrwxrwx 1 root root 38 5月 1 2024 ./usr/lib/aarch64-linux-gnu/libpthread.so -> /lib/aarch64-linux-gnu/libpthread.so.0
➜ sysroot ls -al lib/aarch64-linux-gnu/libpthread.so.0
lrwxrwxrwx 1 root root 18 5月 1 2024 lib/aarch64-linux-gnu/libpthread.so.0 -> libpthread-2.31.so
➜ sysroot
将该软链接改为相对路径即可。
留下评论