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
#......部分内容省略......
相关推荐
库玛西1 小时前
深入浅出Linux select网络模型:从底层位图原理到C++面向对象高级封装
linux·服务器·网络·c++·ubuntu
Tingjct1 小时前
线程详细讲解---聚焦linux
linux·服务器·jvm
ComputerInBook1 小时前
linux包管理工具——yum(YellowdogUpdaterModified)
linux·运维·服务器·yum·dnf
霸道流氓气质1 小时前
通义千问 Chat 模型高级用法:Function Calling / Structured Output / 多轮对话
linux·运维·windows
实心儿儿1 小时前
Linux —— epoll(1)
linux·网络
s_w.h2 小时前
【 计网 】序列化与反序列化
linux·服务器·网络·算法·bash
祖力552 小时前
网络编程:IO多路复用(select、poll、epoll)
linux·服务器·网络
迷路爸爸1802 小时前
在 Ubuntu / Linux 上轻量安装 LaTeX:TinyTeX 使用记录
linux·运维·ubuntu
tedcloud1232 小时前
OpenLogi 怎么搭建?用 Rust 打造一个轻量的 Logitech 外设管理工具
linux·运维·服务器·开发语言·后端·rust·开源