ubuntu20.04交叉编译QT5.15.12(RK3562+ubuntu20.04)

一、编译主机环境搭建

ubuntu20.04主机系统下载:https://releases.ubuntu.com/

编译主机依赖安装:

复制代码
sudo apt-get update
sudo apt-get install -y cmake gcc g++ vim iputils-ping net-tools \
openssh-server openssh-client gcc-aarch64-linux-gnu \
g++-aarch64-linux-gnu binutils-aarch64-linux-gnu qemu-user-static \

二、QT编译

1).QT下载:https://download.qt.io/archive/qt/

国内地址:https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/

2).解压QT源码:

复制代码
mkdir -p ~/project
tar -xvf qt-everywhere-opensource-src-5.15.12.tar.xz -C ~/project
cd ~/project/qt-everywhere-src-5.15.12/   #进入源码目录

3).创建QT配置脚本autoconfig.sh,内容如下:

复制代码
#!/bin/sh
./configure \
-sysroot /opt/sysroot/host  \
-extprefix /opt/qt5.15.12-aarch64 \
-confirm-license \
-opensource \
-release \
-make libs \
-xplatform linux-aarch64-gnu-g++ \
-pch \
-qt-libjpeg \
-qt-libpng \
-qt-zlib \
-no-sse2 \
-no-openssl \
-no-cups \
-no-separate-debug-info \
-gui \
-widgets \
-glib \
-opengl es2 \
-egl \
-eglfs \
-qpa eglfs \
-xcb \
-dbus \
-syslog \
-sqlite \
-tslib \
-fontconfig \
-no-harfbuzz \
-no-linuxfb \
-no-directfb \
-recheck-all

注:配置有变动修改这个文件即可,修改完成后运行"./autoconfig.sh"生效配置。另外不同版本这部分会有差异需根据实际情况修改。

4).修改qmake配置。

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)

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

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

QMAKE_INCDIR_OPENGL_ES2 = $$[QT_SYSROOT]/usr/include
QMAKE_LIBDIR_OPENGL_ES2 = /usr/lib/aarch64-linux-gnu

QMAKE_INCDIR_EGL        = $$[QT_SYSROOT]/usr/include
QMAKE_LIBDIR_EGL        = /usr/lib/aarch64-linux-gnu

QMAKE_LIBS_EGL         += -lEGL -lGLESv2
QMAKE_LIBS_OPENGL_ES2  += -lGLESv2 -lEGL

load(qt_config)

5).QT编译依赖

autoconfig.sh中的"-sysroot"指定了目标文件系统的位置, QT编译过程会从这个位置获取需要的依赖库。这里将目标文件系统复制到"-sysroot"指定的目录中。

复制代码
sudo chmod 777 /opt/
mkdir -p /opt/sysroot/host
rsync -avx 目标文件系统根目录 /opt/sysroot/host

目标文件系统可能因缺少某些库,导致配置阶段报错,如后面"编译过程遇到的问题章节"介绍。可以参考下面方法解决。

创建"/opt/sysroot/host/ch-mount.sh "内容如下:

复制代码
#!/bin/bash
# 
function mnt() {
    echo "MOUNTING..."
    sudo mount -t proc /proc ${2}proc
    sudo mount -t sysfs /sys ${2}sys
    sudo mount -o bind /dev ${2}dev
    sudo mount -o bind /dev/pts ${2}dev/pts
    echo "CHROOT..."
    sudo chroot ${2}
    echo "Success!"
}
function umnt() {
    echo "UNMOUNTING"
    sudo umount ${2}proc
    sudo umount ${2}sys
    sudo umount ${2}dev/pts
    sudo umount ${2}dev
}
if [ "$1" == "-m" ] && [ -n "$2" ] ;
then
    mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ];
then
    umnt $1 $2
else
    echo ""
    echo "Either 1'st, 2'nd or both parameters were missing"
    echo ""
    echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
    echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
    echo ""
    echo "For example: ch-mount -m /media/sdcard/"
    echo ""
    echo 1st parameter : ${1}
    echo 2nd parameter : ${2}
fi

cd /opt/sysroot/
chmod +x ch-mount.sh
./ch-mount.sh -m host     #进入文件系统,
./ch-mount.sh -u host     #exit退出后需要执行下面命令

通过"./ch-mount.sh -m host"进入后就可以通过apt-get下载软件包了。

6).openGL

前面我们在qmake.config中指定了openGL的依赖,但是这里的默认依赖关联的是mesa库,

复制代码
root@ubuntu:/usr/lib/aarch64-linux-gnu# ls -la | grep "EGL"
lrwxrwxrwx  1 linaro linaro       20 Mar  9  2022 libEGL_mesa.so.0 -> libEGL_mesa.so.0.0.0
-rw-r--r--  1 linaro linaro   259072 Mar  9  2022 libEGL_mesa.so.0.0.0
lrwxrwxrwx  1 linaro linaro       11 Mar  8  2022 libEGL.so -> libEGL.so.1
lrwxrwxrwx  1 linaro linaro       15 Mar  8  2022 libEGL.so.1 -> libEGL.so.1.1.0
-rw-r--r--  1 linaro linaro    80312 Mar  8  2022 libEGL.so.1.1.0
root@ubuntu:/usr/lib/aarch64-linux-gnu# ls -la | grep "GLES"
lrwxrwxrwx  1 linaro linaro       17 Mar  8  2022 libGLESv1_CM.so -> libGLESv1_CM.so.1
lrwxrwxrwx  1 linaro linaro       21 Mar  8  2022 libGLESv1_CM.so.1 -> libGLESv1_CM.so.1.2.0
-rw-r--r--  1 linaro linaro   141408 Mar  8  2022 libGLESv1_CM.so.1.2.0
lrwxrwxrwx  1 linaro linaro       14 Mar  8  2022 libGLESv2.so -> libGLESv2.so.2
lrwxrwxrwx  1 linaro linaro       18 Mar  8  2022 libGLESv2.so.2 -> libGLESv2.so.2.1.0
-rw-r--r--  1 linaro linaro   149600 Mar  8  2022 libGLESv2.so.2.1.0

为了能正常使用mali库进行GPU加速,需要创建下面符号链接,让openGL关联的依赖变成mali库。

复制代码
ln -sf mali/libEGL.so libEGL.so.1
ln -sf mali/libGLESv2.so libGLESv2.so.2

root@ubuntu:/usr/lib/aarch64-linux-gnu# ls -la | grep "GLES"
lrwxrwxrwx  1 linaro linaro       17 Mar  8  2022 libGLESv1_CM.so -> libGLESv1_CM.so.1
lrwxrwxrwx  1 linaro linaro       21 Mar  8  2022 libGLESv1_CM.so.1 -> libGLESv1_CM.so.1.2.0
-rw-r--r--  1 linaro linaro   141408 Mar  8  2022 libGLESv1_CM.so.1.2.0
lrwxrwxrwx  1 linaro linaro       14 Mar  8  2022 libGLESv2.so -> libGLESv2.so.2
lrwxrwxrwx  1 root   root         17 Jun  3 08:41 libGLESv2.so.2 -> mali/libGLESv2.so
-rw-r--r--  1 linaro linaro   149600 Mar  8  2022 libGLESv2.so.2.1.0
root@ubuntu:/usr/lib/aarch64-linux-gnu# ls -la | grep "EGL"
lrwxrwxrwx  1 linaro linaro       20 Mar  9  2022 libEGL_mesa.so.0 -> libEGL_mesa.so.0.0.0
-rw-r--r--  1 linaro linaro   259072 Mar  9  2022 libEGL_mesa.so.0.0.0
lrwxrwxrwx  1 linaro linaro       11 Mar  8  2022 libEGL.so -> libEGL.so.1
lrwxrwxrwx  1 root   root         14 Jun  3 08:41 libEGL.so.1 -> mali/libEGL.so
-rw-r--r--  1 linaro linaro    80312 Mar  8  2022 libEGL.so.1.1.0

7).编译安装

复制代码
make
make install    #安装位置为配置中"-extprefix"指定的位置。

三、部署

将上面"-extprefix"指定目录下的文件进行压缩,然后复制到开发板上相同的目录下。

复制代码
#编译主机
cd /opt
tar -cvf qt5.15.12-aarch64.tar qt5.15.12-aarch64

#开发板
tar -xvf qt5.15.12-aarch64.tar -C /opt/

配置环境变量:

复制代码
export QT_QPA_PLATFORM=XCB
export QT_QPA_EGLFS_INTEGRATION=XCB_EGL  #没有这个有些应用会报0x03001错误。
export QTDIR=/opt/qt5.15.12-aarch64
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins
export QML2_IMPORT_PATH=$QTDIR/qml
#export QT_QPA_PLATFORM=eglfs  #直接配置它启动桌面可能有问题,要用到eglfs可以指定-platform参数

四、编译过程遇到的问题

注意下面需要安装的软件包都是安装在目标文件系统中。

  • xcb报错
    ERROR: Feature 'xcb' was enabled, but the pre-condition 'features.thread && libs.xcb && tests.xcb_syslibs && features.xkbcommon-x11' failed.
    解决方法:

    apt-get install libxcb1-dev libx11-xcb-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libxcb-icccm4-dev
    libxcb-image0-dev libxcb-keysyms1-dev libxcb-util-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-shape0-dev
    libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev

  • sqlite3报错
    ERROR: Feature 'system-sqlite' was enabled, but the pre-condition 'features.sql-sqlite && libs.sqlite3' failed.
    解决方法:

    apt-get install -y libsqlite3-dev

  • tslib报错:
    ERROR: Feature 'tslib' was enabled, but the pre-condition 'libs.tslib' failed.
    解决方法:

    apt-get install libts-dev

  • 缺少fbdev_window.h

    main.cpp:2:10: fatal error: EGL/fbdev_window.h: No such file or directory
    2 | #include <EGL/fbdev_window.h>
    | ^~~~~~~~~~~~~~~~~~~~
    compilation terminated.
    make: *** [Makefile:169: main.o] Error 1
    test config.qtbase_gui.tests.egl-mali FAILED
    executing config test egl-mali-2

解决方法:

创建文件/usr/include/EGL/fbdev_window.h写入下面内容:

复制代码
/*
 1. This confidential and proprietary software may be used only as
 2. authorised by a licensing agreement from ARM Limited
 3. (C) COPYRIGHT 2008-2011 ARM Limited
 4. ALL RIGHTS RESERVED
 5. The entire notice above must be reproduced on all authorised
 6. copies and copies may only be made to the extent permitted
 7. by a licensing agreement from ARM Limited.
 */
 
/**
 8. @file fbdev_window.h
 9. @brief A window type for the framebuffer device (used by egl and tests)
 */
 
#ifndef _FBDEV_WINDOW_H_
#define _FBDEV_WINDOW_H_
 
#ifdef __cplusplus
extern "C" {
#endif
 
typedef enum
{
	FBDEV_PIXMAP_DEFAULT = 0,
	FBDEV_PIXMAP_SUPPORTS_UMP = (1<<0),
	FBDEV_PIXMAP_ALPHA_FORMAT_PRE = (1<<1),
	FBDEV_PIXMAP_COLORSPACE_sRGB = (1<<2),
	FBDEV_PIXMAP_EGL_MEMORY = (1<<3)        /* EGL allocates/frees this memory */
} fbdev_pixmap_flags;
 
typedef struct fbdev_window
{
	unsigned short width;
	unsigned short height;
} fbdev_window;
 
typedef struct fbdev_pixmap
{
	unsigned int height;
	unsigned int width;
	unsigned int bytes_per_pixel;
	unsigned char buffer_size;
	unsigned char red_size;
	unsigned char green_size;
	unsigned char blue_size;
	unsigned char alpha_size;
	unsigned char luminance_size;
	fbdev_pixmap_flags flags;
	unsigned short *data;
	unsigned int format; /* extra format information in case rgbal is not enough, especially for YUV formats */
} fbdev_pixmap;
 
#ifdef __cplusplus
}
#endif

#endif
  • openGL报错

    ERROR: Feature 'opengles2' was enabled, but the pre-condition '(config.win32 && !features.opengl-dynamic) || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)' failed.

    ERROR: Feature 'egl' was enabled, but the pre-condition '(features.opengl || features.openvg) && (features.angle || libs.egl) && (features.dlopen || !config.unix || config.integrity)' failed.

    ERROR: Feature 'eglfs' was enabled, but the pre-condition '!config.android && !config.darwin && !config.win32 && !config.wasm && features.egl' failed.

    ERROR: The OpenGL functionality tests failed!

    /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: main.o: in function main': main.cpp:(.text.startup+0x10): undefined reference to glUniform1f'
    /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: main.cpp:(.text.startup+0x18): undefined reference to `glClear'
    collect2: error: ld returned 1 exit status
    make: *** [Makefile:67: opengl_es2] Error 1

解决办法:

通过下面命令可以查到,这两个函数位于libmali.so中,所以我们需要在qmake.conf给openGL把这个依赖也要加上。

复制代码
QMAKE_LIBS_EGL         += -lEGL -lGLESv2 -lmali
QMAKE_LIBS_OPENGL_ES2  += -lGLESv2 -lEGL -lmali
  • 配置正常,执行QT编译过程报函数未定义错误。

    /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: .obj/qlibrary_unix.o: in function QLibraryPrivate::load_sys()': qlibrary_unix.cpp:(.text+0xbb0): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: /opt/sysroot/host/usr/lib/aarch64-linux-gnu/libpthread.a(pthread_create.o): in function allocate_stack':
    /build/glibc-fci4Zo/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-fci4Zo/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-fci4Zo/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-fci4Zo/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: /opt/sysroot/host/usr/lib/aarch64-linux-gnu/libpthread.a(unwind.o): in function _jmpbuf_sp': /build/glibc-fci4Zo/glibc-2.31/nptl/../sysdeps/aarch64/jmpbuf-offsets.h:52: undefined reference to __pointer_chk_guard_local'

解决办法:

这个是因为目标系统的"/usr/lib/aarch64-linux-gnu"下有部分库的符号链接连接的是绝对路径。当被复制到编译主机上时这个绝对路径就指向了编译主机lib库。这里只需要将绝对路径全部替换成相对路径即可。

目标文件系统执行下面命令修改:

复制代码
cd /usr/lib/aarch64-linux-gnu
ls -la | grep "lib/"  #会查到下面内容
lrwxrwxrwx  1 root   root         39 Jun  2 16:36 libanl.so -> /lib/aarch64-linux-gnu/libanl.so.1
lrwxrwxrwx  1 root   root         45 Jun  2 16:36 libblkid.so -> /lib/aarch64-linux-gnu/libblkid.so.1.1.0
lrwxrwxrwx  1 root   root         48 Jun  2 16:36 libBrokenLocale.so -> /lib/aarch64-linux-gnu/libBrokenLocale.so.1
lrwxrwxrwx  1 root   root         45 Jun  2 16:36 libcrypt.so -> /lib/aarch64-linux-gnu/libcrypt.so.1.1.0
lrwxrwxrwx  1 root   root         48 Jun  2 16:36 libdbus-1.so -> /lib/aarch64-linux-gnu/libdbus-1.so.3.19.11
lrwxrwxrwx  1 root   root         38 Jun  2 16:36 libdl.so -> /lib/aarch64-linux-gnu/libdl.so.2
#......部分内容省略......

#以第一个为例,执行下面命令,修改成相对路径。
ln -sf ../../lib/aarch64-linux-gnu/libanl.so.1 libanl.so 
ls -la | grep "lib/"  #再次查到下面内容
lrwxrwxrwx  1 root   root         39 Jun  2 16:36 libanl.so -> ../../lib/aarch64-linux-gnu/libanl.so.1
lrwxrwxrwx  1 root   root         45 Jun  2 16:36 libblkid.so -> ../../lib/aarch64-linux-gnu/libblkid.so.1.1.0
lrwxrwxrwx  1 root   root         48 Jun  2 16:36 libBrokenLocale.so -> ../../lib/aarch64-linux-gnu/libBrokenLocale.so.1
lrwxrwxrwx  1 root   root         45 Jun  2 16:36 libcrypt.so -> ../../lib/aarch64-linux-gnu/libcrypt.so.1.1.0
lrwxrwxrwx  1 root   root         48 Jun  2 16:36 libdbus-1.so -> ../../lib/aarch64-linux-gnu/libdbus-1.so.3.19.11
lrwxrwxrwx  1 root   root         38 Jun  2 16:36 libdl.so -> ../../lib/aarch64-linux-gnu/libdl.so.2
#......部分内容省略......
相关推荐
未济3 天前
linux 配置环境变量
linux
傲世仙尊3 天前
目录即文件-Ext文件系统收尾篇
linux·c语言
_艾伦 耶格尔.3 天前
进程间通信
linux
Liuqy-053 天前
Linux IO编程——静态库、动态库
linux
彧azz3 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
-梅3 天前
linux(8) 软硬链接
linux·运维·服务器
慧都小项3 天前
当边缘AI上产线:QtitanDocking 如何让工业 HMI 实现多视图协同
人工智能·qt·ui·边缘计算·qt6.3
AIgorithmGEEK3 天前
[Linux]线程三部曲(上):一个执行流的诞生——从操作系统一路拆到 pthread_create
linux·线程·pid
琥珀色糖3 天前
SimlpeHttp
linux·服务器
qeen873 天前
【Linux】操作系统之进程介绍(二)
linux·笔记·学习·进程