交叉编译并部署Qt5.14.1到树莓派4最新官方镜像-buster版本

写在最前面 呵呵。。

编译成功,完美支持:EGLFS、 EGLFS GBM,EGL on X11暂时不支持,不过我不打算在X11上实现EGL。效果上图:

后面几天我会更新这篇文章,详细说明整个编译过程遇到的坑。

完美支持QML控件的程序

支持QML程序

运行的程序是Qt自带的automotive.pro例子程序。 

Qt自带的例子程序(automotive)

  EGL .................................... yes
  OpenVG ................................. no
  OpenGL:
    Desktop OpenGL ....................... no
    OpenGL ES 2.0 ........................ yes
    OpenGL ES 3.0 ........................ yes
    OpenGL ES 3.1 ........................ yes
    OpenGL ES 3.2 ........................ yes
  Vulkan ................................. yes
  Session Management ..................... yes
Features used by QPA backends:
  evdev .................................. yes
  libinput ............................... yes
  INTEGRITY HID .......................... no
  mtdev .................................. yes
  tslib .................................. yes
  xkbcommon .............................. yes
  X11 specific:
    XLib ................................. yes
    XCB Xlib ............................. yes
    EGL on X11 ........................... no
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 ...................... no
    EGLFS GBM ............................ yes
    EGLFS VSP2 ........................... no
    EGLFS Mali ........................... no
    EGLFS Raspberry Pi ................... no
    EGLFS X11 ............................ no
  LinuxFB ................................ yes
  VNC .................................... yes
  XCB:
    Using system-provided XCB libraries .. yes
    XCB XKB .............................. yes
    XCB XInput ........................... no
    Native painting (experimental) ....... no
    GL integrations:
      GLX Plugin ......................... no
      EGL-X11 Plugin ..................... no

写在前面

这个教程将指导你如何在电脑的虚拟机上交叉编译Qt 5.14.1并安装到树莓派4B上面。这样你就可以在电脑上用Qt Creator设计和编译树莓派的应用,然后直接在树莓派上运行和调试。采用此方式开发出来的Qt窗口应用程序是为了在真正的嵌入式设备上运行的应用。应用程序可以不在X-server或桌面运行、应用程序使用eglfs接口直接调用OpenGL直接驱动GPU绘制窗口。eglfs是Qt的一个平台插件,使Qt程序可以利用OpenGL ES 画图而无需窗口系统。这种方式是在支持gpu的嵌入式设备主要采用的方式。一般需要gpu厂商提供egl和gles驱动模块。Qt可以利用eglfs插件实现直接画图(全屏),或者在有窗口管理系统(如wayland合成器weston或Qtwayland合成器)时通过窗口画图。前者只能全屏显示一个程序,后者可以实现多进程应用。

OpenGL ES(OpenGL for Embeded System)是OpenGL(Open Graphics Library)的精简子集,是以手持和嵌入式设备为目标的高级3D图形API

开发环境

1.[树莓派端]

树莓派型号:Raspberry Pi 4 Model B

CPU: ARM Cortex-A72 1.5GHz 64为四核

内存:2GB

TF卡:16GB

操作系统:2020-02-13-raspbian-buster-full (32位操作系统,因为树莓派官方只有32位操作系统)

raspbian常用的有两个版本Stretch和Buster,Stretch版一般安装在在树莓派3B和3B+上,Buster版安装在最新的树莓派4B上。查询当前操作系统版本的命令是 uname -a

uname -a

在 Raspberry Pi 官方网站的下载有 desktop和 Lite 两种版本,主要分别在于Lite 没有预设安装 X-server 与相关的套件,因此无法用 startx 启动视窗管理员。因为也没有安装 Qt 和 GTK+ 的函式库,因此也无法执行相关的视窗程式。采用本文方式编译出来的窗口程序原理上是不需要X-server即可运行,实际上能不能运行在Lite版本上待我后续试验后告诉大家(经过我的多次努力,我发现程序不能再Lite版本下运行)。
2. [PC端]

操作系统:Win7

虚拟机版本:VMware® Workstation 15 Pro

Linux版版本:Ubuntu 18.04.3 LTS   64位版


准备工作

1. 在命令行界面使用以下命令更新固件,更新完成后重启系统。

sudo rpi-update
reboot

2. 确保树莓派上的SSH协议已经打开。后续Qt Creator需要通过SSH和树莓派通信。可以执行以下命令打开设置界面,选择Interfacing Options,选择ssh,选择yes然后finish。

sudo raspi-config

以下清单总结了交叉编译Qt 5.14.1的主要步骤,我们将在这篇文章中逐一介绍。[PI]表示在树莓派上操作,[PC]表示在电脑上操作。

    1. [PI] 安装开发包

    2. [PI] 准备目标文件夹

    3. [PI] 配置调试及运行环境

    4. [PC] 创建工作文件夹并设置工具链

    5. [PC] 创建和配置sysroot

    6. [PC] 下载Qt

    7. [PC] 配置Qt

    8. [PC] 编译、安装和部署Qt

    9. [PC]  配置Qt Creator实现交叉编译树莓派的应用

    10. [PI] 复制字体


1. [PI] 安装开发包
首先备份/etc/apt/sources.list(软件源配置文件)和 /etc/apt/sources.list.d/raspi.list(系统源配置文件)这两个文件。修改文件采用国内源的方式下载。

先备份文件原始文件
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.list.bak

修改/etc/apt/sources.list

s1:打开源文件

sudo nano /etc/apt/sources.list

s2:更换源
你需要将原来的源注释掉,然后加上新的源。注释的格式是在前面加一个#,当然也可以删掉原来的源。编辑好的文件如下,注意版本号是buster (source.list文件格式说明)。

# 编辑 `/etc/apt/sources.list` 文件,删除deb-src前的#号
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/ buster main non-free contrib
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/ buster main non-free contrib
 
ctrl+o保存文件, ctrl+x 退出nano编辑器

 修改/etc/apt/sources.list.d/raspi.list

s1:同样的,打开源文件

sudo nano /etc/apt/sources.list.d/raspi.list

s2:更换源,这里还是清华源

# 编辑 `/etc/apt/sources.list.d/raspi.list` 文件,,删除deb-src前的#号。
deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui

ctrl+o保存文件, ctrl+x 退出nano编辑器

下一步是使用apt-get命令更新和下载开发包。整个更新过程大概消耗了约1.3G的流量。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get build-dep qt4-x11
sudo apt-get build-dep libqt5gui5
sudo apt-get install libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0

有些教程说需要安装以下软件
sudo apt-get install libfontconfig1-dev libdbus-1-dev libfreetype6-dev libicu-dev libinput-dev libxkbcommon-dev libsqlite3-dev libssl-dev libpng-dev libjpeg-dev libglib2.0-dev libraspberrypi-dev libpq-dev libmariadbclient-dev bluez libbluetooth-dev build-essential

2. [PI] 准备目标文件夹
这步是在树莓派的pi用户下创建/usr/local/qt5pi文件夹,后面编译好的Qt库会从电脑部署到这个文件夹。

sudo mkdir /usr/local/qt5pi
sudo chown pi:pi /usr/local/qt5pi

3. [PI] 配置调试及运行环境
编译好的可执行文件会放在树莓派的/opt目录下,但默认的pi用户没有创建文件夹或文件的权限,需要在根目录执行:

sudo chmod -R 777 /opt

远程调试时需要安装gdbserver:

sudo apt-get install gdbserver

增加分辨率设置:

sudo leafpad ~/.profile

在其中增加:

# physical display properties
export QT_QPA_EGLFS_PHYSICAL_WIDTH=1920
export QT_QPA_EGLFS_PHYSICAL_HEIGHT=1080

然后执行:

source .profile

4. [PC] 创建工作文件夹并设置工具链
在电脑上创建交叉编译工具链工作文件夹。

mkdir ~/raspi
mkdir ~/raspi/cross-compile-tool/
cd ~/raspi

linaro网站下载交叉编译工具链到~raspi目录下,包括gcc、runtime、sysroot三项。提示:用迅雷下,迅雷下的快!

下载后解压,合并放在~/raspi/cross-compile-tool/目录下,tar命令详解

sudo tar jxvf gcc-linaro-7.5.01-2019.12-x86_64_gnueabif.tar.xz
sudo tar jxvf runtime-gcc-linaro-7.5.0-2019.12-arm-linux-gnueabihf.tar.xz
sudo tar jxvf sysroot-glibc-linaro-2.25-2019.12-arm-linux-gnueabihf.tar.xz

将交叉编译器路径写入PATH中(设置环境变量的方法和测试方法

修改方式和内容如下:

s1:修改/etc/profile

sudo nano /etc/profile

#profile文件最后一行增加下面这行代码:
export PATH=$PATH:~/raspi/cross-compile-tool/bin

#保存profile文件
ctrl+o保存文件, ctrl+x 退出nano编辑器

#刷新变量文件
source /etc/profile

#测试变量是否写入成功
echo $PATH

s2:修改/etc/sudoers

在sudos配置文件下把交叉编译器的bin路径也加入

sudo nano /etc/sudoers

#修改secure_path路径内容,将交叉编译器的绝对路径加在最后:
secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/home/yong/raspi/cross-compile-tool/bin"

#保存sudoers文件
ctrl+o保存文件, ctrl+x 退出nano编辑器

加入之后应该是这个样子,重点是红框的那部分内容。

检查配置是否完成(注意,两个都需要有正常输出,这一步才算完成)

arm-linux-gnueabihf-g++ -v
sudo arm-linux-gnueabihf-g++ -v

编译一个小程序试试效果

1、nano编辑一段代码:

#include <stdio.h>
int main(int argc, char **argv)
{
    printf("Hello, you do it succeed!!!\n");
    return 0;
}

2、编译代码

arm-linux-gnueabihf-g++ main.c

3、 将编译输出文件a.out复制到目标机用户主目录下,增加运行权限,执行代码。

sudo chmod ugo+x ./a.out
./a.out

#运行输出:
Hello, you do it succeed!!!

为什么一定要sudo aarch64-linux-gnu-g++ -v 也有正常输出?因为在下面的编译过程中make中没有用到sudo,但是安装的时候要sudo make install,这一步的操作也需要交叉编译器,如果不正确配置,会出现make成功,而sudo make install失败的情况。

如果输入sudo aarch64-linux-gnu-g++ -v,提示没有找到命令,而直接输入aarch64-linux-gnu-g++ -v可正常显示。解决方法是在sudos配置文件下把交叉编译器的bin路径也加在secure_path变量里面。

5. [PC] 创建和配置sysroot 
sysroot是树莓派上的文件在PC上的拷贝,编译过程中需要的头文件、库等会在这里查找,此文件夹创建在~/rasp目录下。

cd ~/raspi/cross-compile-tool
mkdir ./sysroot/opt

我们可以使用rsync将树莓派rootfs目录下的/lib、/usr/include、usr/lib、/opt的目录同步到PC端的sysroot目录下。如果电脑上的sysroot文件夹发生任何变化,都会被自动同步到树莓派上。raspberrypi_ip代表树莓派的网络名或IP地址。

rsync -avz pi@raspberrypi_ip:/lib sysroot
rsync -avz pi@raspberrypi_ip:/usr/include sysroot/usr
rsync -avz pi@raspberrypi_ip:/usr/lib sysroot/usr
rsync -avz pi@raspberrypi_ip:/opt/vc sysroot/opt

简述一下sysroot目录的作用:

将sysroot-glibc-linaro-2.25-2019.12-arm-linux-gnueabihf.tar解压出来的目录与树莓派合成一个文件系统,用来提供给交叉编译时编译器寻找头文件.h和库文件.so。这样才能提供一个基本与目标开发板一致的环境,有了这个环境之后,编译时找头文件就不在笔记本(ubuntu)的环境找了,只在sysroot这个目录里面找。

下一步,我们需要将sysroot中的符号链接调整为相对的,因为这个文件夹在电脑和树莓派上都会有。用wget工具将sysroot-relativelinks.py文件下载到 ~/raspi/cross-compile-tool目录下,增加可执行权限,并运行。

wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
chmod +x sysroot-relativelinks.py
./sysroot-relativelinks.py sysroot

到这里,这个交叉编译环境就基本OK了!

 6. [PC] 下载Qt
下载Qt 源代码文件,我下载的是5.14.1,当然其他版本也可以。进入QT官网下载网站,进入对应QT版本的目录(例如:5.14),子版本目录(5.14.1),single目录下载对应的Qt源代码文件:qt-everywhere-src-5.14.1.tar.xz。另外下载对应版本的PC端安装包。

安装包是用来给PC端装一个Qt,源码是用来编译一个 对应平台的Qt,即编译一个arm平台可用的Qt。

#源代码下载路径:
http://download.qt.io/archive/qt/5.14/5.14.1/single/qt-everywhere-src-5.14.1.tar.xz
#安装包下载路径:
http://download.qt.io/official_releases/qt/5.14/5.14.1/qt-opensource-linux-x64-5.14.1.run

 7. [PC] 配置Qt

~/rasp目录下解压缩Qt源代码文件,Qt源代码目录的qtbase/mkspecs文件夹下面放置着各种平台下的编译配置信息,本次需要编译的平台的文件夹是:~/rasp/qt-everywhere-src-5.14.1/qtbase/mkspecs/devices/linux-rasp-pi4-v3d-g++。编辑pi4平台下的qmake.conf文件。

#Qt源码包下载到~/rasp目录下,并在这个目录下解压缩,修改qmake.conf配置文件
tar xvf  qt-everywhere-src-5.14.1.tar.xz
sudo nano ./qt-everywhere-src-5.14.1/qtbase/mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf

qmake.conf的原始内容:

# qmake configuration for the Raspberry Pi 4 (32-bit) using the Mesa V3D
# graphics stack. (not the Broadcom stack)
#
# This supports accelerated OpenGL both for X11 and DRM/KMS.  Perhaps
# Wayland too.
#
# Tested with a sysroot created from Raspbian Buster and a gcc 7.4
# toolchain from Linaro.
#
# Example configure command line, assuming installation to
# /usr/local/qt5pi on device and ~/rpi/qt5 on the host:
#
# ./configure -release -opengl es2 -device linux-rasp-pi4-v3d-g++ -device-option CROSS_COMPILE=~/rpi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- \
#   -sysroot ~/rpi/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/rpi/qt5 -v
#
# Check the configure output carefully. EGLFS, EGLFS GBM, and EGL on X11
# should all be 'yes'. Otherwise something is wrong.
#
# If getting linker errors like "undefined reference to `_dl_stack_flags'" check the
# symlinks in the sysroot, they were probably not adjusted
# correctly. F.ex. sysroot/usr/lib/arm-linux-gnueabihf/libpthread.so must point to
# sysroot/lib/arm-linux-gnueabihf/libpthread.so.0. If it is a broken link instead, bad
# things will happen.

include(../common/linux_device_pre.conf)

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

QMAKE_CFLAGS            = -march=armv8-a -mtune=cortex-a72 -mfpu=crypto-neon-fp-armv8
QMAKE_CXXFLAGS          = $$QMAKE_CFLAGS

DISTRO_OPTS            += hard-float
DISTRO_OPTS            += deb-multi-arch

EGLFS_DEVICE_INTEGRATION = eglfs_kms

include(../common/linux_arm_device_post.conf)

load(qt_config)

就qmake.conf文件的注释有些需要重点说明一下

qmake configuration for the Raspberry Pi 4 (32-bit) using the Mesa V3D graphics stack. (not the Broadcom stack)

This supports accelerated OpenGL both for X11 and DRM/KMS.  Perhaps Wayland too.

qmake成支持V3D graphics stack 栈而不是之前的Broadcom 栈。这样Qt程序可以同时在窗口管理系统X11和DRM/KMS上支持OpenGL加速。没准Wayland窗口管理系统也可以。

Tested with a sysroot created from Raspbian Buster and a gcc 7.4  toolchain from Linaro.

编译Qt源码用到的sysroot目录和gcc编译器的最低版本是7.4,我下载的是高版本的7.5.0。 树莓派官方指定的git下载目录GitHub - raspberrypi/tools里面的版本太低,我记得应该是4.7.1吧。

Check the configure output carefully. EGLFS, EGLFS GBM, and EGL on X11 should all be 'yes'. Otherwise something is wrong.

完成配置后注意查看配置状态表上EGLFS, EGLFS GBM, 和 EGL on X11这几项是不是yes,否则编译会不成功。

If getting linker errors like "undefined reference to `_dl_stack_flags'" check the  symlinks in the sysroot, they were probably not adjusted  correctly. F.ex. sysroot/usr/lib/arm-linux-gnueabihf/libpthread.so must point to sysroot/lib/arm-linux-gnueabihf/libpthread.so.0. If it is a broken link instead, bad things will happen.

如果在make过程中出现 "undefined reference to `_dl_stack_flags'"错误,应该是sysroot目录下的libpthread.so库文件的软连接不对,用进入到文件目录下用 ls -l 命令查询一下,如果不是链接到“sysroot/lib/arm-linux-gnueabihf/libpthread.so.0.”需要用ln命令修复软链接: sudo ln -sf libpthread.so sysroot/lib/arm-linux-gnueabihf/libpthread.so.0.

配置Qt库:

进入Qt源代码文件夹的qtbase目录下运行./configure命令进行编译前配置。 因为./configure的配置参数很多,建议先阅读文章Qt源码编译configure配置参数

简单来说./configure作用是根据不同的设置参数和选项明确目标平台信息、要编译的库、不编译的库等一些列选项,来编译出一个我们需要的arm目标平台版本的Qt。一些关键选项看下面这张表:

-release 

加上此选项编译程序Qt不会做出优化,往往在开发过程使用此选项,是默认选项

-opengl es2 

表示编译带opengl es2的Qt

-device linux-rasp-pi4-v3d-g++

选择的目标设备,目标设备的配置文件可在/qtbase/mkspec/device找到

-device-option CROSS_COMPILE=
~/raspi/home/用户名/raspi/cross-compile-tool/bin/arm-linux-gnueabihf- 

交叉编译器的路径,注意最后那里的arm-linux-gnueabihf- ,确实有一杠,不要以为打错了

-sysroot ~/raspi//cross-compile-tool/sysroot 

刚刚构建的树莓派文件系统的路径

-opensource 

以开源版本发布程序

-confirm-license 

自动确认许可证(使用开源或是商业)

-make libs 

在make时添加要构建的组件. (默认为:libs tools examples)

-prefix /usr/local/qt5pi

目标板的Qt程序安装目录,默认路径是/usr/local/Qt-版本号 (make完成后看看PC端对应目录下是否有qt5pi目录)

-extprefix ~/raspi/qt5pi 

指定Qt 交叉编译库存放位置。默认路径是SYSROOT/PREFIX。此目录最后需要同步rsysc到目标板的/usr/local/目录下。

-hostprefix ~/raspi/qt5-host

指定Qt 编译的可执行工具存放的位置,比如 qmake,默认路径与-extprefix参数一致。

-no-use-gold-linker 

不要使用GNU gold linker进行链接。对于 5.9.1 或更高版本的 Qt必须添加此选项,不然编译会报错

-v 

显示每个步骤的详细信息

-no-gbm

不要编译 GBM 的后端

进入到源码的根目录下的qtbase目录输入如下命令,并运行./configure的完整指令,开始运行配置过程。

cd  ~/rasp/qt-everywhere-src-5.14.1/qtbase
./configure -release -opengl es2 -device linux-rasp-pi4-v3d-g++ -device-option CROSS_COMPILE=~/raspi/cross-compile-tool/bin/arm-linux-gnueabihf- -sysroot ~/raspi/cross-compile-tool/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5pi-host -v 


#qmake.conf注释中说这两项参数不需要
-no-use-gold-linker -no-gbm

8. [PC] 编译、安装和部署Qt
这一步大概需要2小时。

make -j4
make install

编译完成后使用rsync命令将Qt部署到树莓派上。我们只需同步~/raspi/qt5pi目录到到树莓派的/usr/local/qt5pi目录下。

cd ~/rasp
rsync -avz qt5pi pi@raspberrypi_ip:/usr/local

  • 4
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值