树莓派4 + Qt5.14 PC端交叉编译

不知不觉树莓派都已经4代了,硬件接口和内核都发生了一些改变。最近需要在树莓派上开发一些软件,想利用PC端直接编译生成,鼓捣了半天,记录一下~~(因为肯定会忘...O(∩_∩)O)

编译的时候涉及到了EGLFS,EGLFS是一个Qt5的平台插件,它的作用就是让QT应用直接运行在EGL和OpenGL ES 2.0上(关于EGL和OpenGL ES 2.0的介绍具体可以看知乎上的这篇文章)。就是能让你绕过图形桌面,直接从显卡输出Qt图像到屏幕。(具体的我也不太懂~~)

准备工作

  1. 树莓派4系统烧录(可参考以前的博文) ,方法大体相同,不过要下载最新的系统镜像,3/4之间不能串用!!
  2. Qt5 源码下载(http://download.qt.io/archive/qt/),single文件夹里面的就是!
  3. 更换源(记得src的源的注释要取消掉)

1.树莓派固件更新

直接运行大概率不会成功(因为功夫网)。解决方法可以看知乎上这篇文章。推荐方法三(本地更新),魔法一下把文件下载下来。

sudo rpi-update

更新完毕以后重启一下就好

sudo reboot

1.1 安装树莓派相关依赖

# Qt base依赖的包
sudo apt-get install libboost1.58-all-dev libudev-dev libinput-dev libts-dev libmtdev-dev libjpeg-dev libfontconfig1-dev libssl-dev libdbus-1-dev libglib2.0-dev libxkbcommon-dev
# mesa gbm驱动
sudo apt-get install libgles2-mesa-dev libgbm-dev
# 蓝牙相关 可以不用安装
sudo apt-get install bluez libbluetooth-dev
# 中文字体
sudo apt-get install ttf-wqy-zenhei
# 用于远程调试的GDB Server
sudo apt-get install gdbserver

1.2【在树莓派上】建立文件夹并修改权限

sudo mkdir /usr/local/qt5pi   # 用来安装qt运行库
sudo chown -R pi:pi /usr/local/qt5pi
mkdir /home/pi/qt5  # 用来存放以后自己写的qt程序可执行文件

1.3【在树莓派上】开启GL Driver,并以命令行模式启动

sudo raspi-config
  • 选择 Boot Options —— Desktop/CLI —— Console Autologin —— OK
  • 选择Advanced Options —— GL Driver —— GL ( fake KMS ) —— OK

前者让你以命令行方式启动树莓派;后者启用GL Driver。完事之后Finish,重启就行。查看/dev/dri/目录是否存在,就知道GL Driver启用了。(我自己没用命令行方式,还是用的桌面,大家根据自己的喜好就好)

1.4【在树莓派上】把用户pi添加到渲染组(重要)

sudo gpasswd -a pi render

2 PC端配置环境(Ubuntu18.04)

2.1 【在PC上】下载交叉编译器并配置环境变量

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

在linaro网站下载交叉编译工具链放到~/raspi目录下,包括gcc、runtime、sysroot三项:

(因为树莓派官方的交叉编译工具链太老了,比Qt5.14要求的低很多,所以用linaro的)

​下载后解压,并且合并放在~/raspi/cross-compile-tool目录下(合并的意思是把压缩包的内容合并到一起,而不是把三个解压后的目录放在~/raspi/cross-compile-tool下)。

​然后设置环境变量:

echo 'export PATH=$PATH:~/raspi/cross-compile-tool/' | sudo tee -a /etc/profile
# echo后面一定要用单引号

source /etc/profile
# 刷新环境变量

​ 修改/etc/sudoers,来让你sudo的时候也能找到这个路径。不过你不能直接用编辑器修改这个文件,要用vim,nano这类编辑器。在secure_path后面的路径中追加一串:/home/你的用户名/raspi/cross-compile-tool/bin

检查配置是否正常:

arm-linux-gnueabihf-g++  -v
sudo arm-linux-gnueabihf-g++ -v
# 有版本信息输出就是正常

2.1 安装Qt5.14(源码安装)

​ 在这个链接下载源码和安装包,我下的是5.14.2。
qt-opensource-linux-x64-5.14.2.run是Qt Creator的安装包(我之前装过5.13,Qt Creator就没装,不过不耽误,Creator可以构建多种Kits)。single/qt-everywhere-src-5.14.2.tar.xz是Qt源码,都下载到~/raspi即可。安装包直接运行就能安装,不知道装啥组件的话就全装吧。源码解压就完事了。

2.2 【在PC上】创建并配置sysroot

​ 其实就是把树莓派上的库都弄到PC上来,形成一个和树莓派一样的环境,这样我们交叉编译的时候就可以链接到里面的库和头文件了。

执行以下命令把库和头文件拷贝到PC上:

cd ~/raspi
rsync -avz pi@your rpi IP address:/lib sysroot
rsync -avz pi@your rpi IP address:/usr/include sysroot/usr
rsync -avz pi@your rpi IP address:/usr/lib sysroot/usr
rsync -avz pi@your rpi IP address:/opt/vc sysroot/opt
# 记得改成你的树莓派的ip地址

树莓派地址的查看可以利用ifconfig

然后需要修改sysroot里面的软链接,里面有很多软连接使用的都是绝对路径,那就会直接链接到你PC的/usr/lib目录里面去,那肯定是错的,我们希望它们链接到sysroot里面对应的库。所以我们需要把绝对路径改成相对路径。直接用网上现成的python脚本完成。

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

如果下载不下来,没关系,贴给大家~~很精悍

#!/usr/bin/env python
import sys
import os

# Take a sysroot directory and turn all the abolute symlinks and turn them into
# relative ones such that the sysroot is usable within another system.

if len(sys.argv) != 2:
    print("Usage is " + sys.argv[0] + "")
    sys.exit(1)

topdir = sys.argv[1]
topdir = os.path.abspath(topdir)

def handlelink(filep, subdir):
    link = os.readlink(filep)
    if link[0] != "/":
        return
    if link.startswith(topdir):
        return
    #print("Replacing %s with %s for %s" % (link, topdir+link, filep))
    print("Replacing %s with %s for %s" % (link, os.path.relpath(topdir+link, subdir), filep))
    os.unlink(filep)
    os.symlink(os.path.relpath(topdir+link, subdir), filep)

for subdir, dirs, files in os.walk(topdir):
    for f in files:
        filep = os.path.join(subdir, f)
        if os.path.islink(filep):
            #print("Considering %s" % filep)
            handlelink(filep, subdir)

3. 配置并交叉编译Qt

在PC上,在配置之前可以看一下qt-everywhere-src-5.14.2/qtbase/mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf里面的注释,很多信息很重要的。里面给出了配置方法

cd ~/raspiqt-everywhere-src-5.14.2/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/sysroot -opensource -confirm-license -reduce-exports -make libs -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5pi-host -v

几个参数简单解释一下,可以看./config_help.txt:

-device linux-rasp-pi4-v3d-g++ :使用qtbase/mkspecs/device/linux-rasp-pi4-v3d-g++下的配置
-device-option CROSS_COMPILE=~/raspi/cross-compile-tool/bin/arm-linux-gnueabihf-: 交叉编译工具链的前缀,注意最后那个“-”号是不能少的
-prefix /usr/local/qt5pi: Qt最终安装到树莓派中的位置
-extprefix ~/raspi/qt5pi: PC上交叉编译好的Qt的位置
-hostprefix ~/raspi/qt5pi-host: 编译出来给PC用的交叉编译工具存放的位置

config.summary输出参考如下:(一部分)

Qt Gui:
...此处省略...
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 ........................... 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
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 ..................... yes
...
Note: Also available for Linux: linux-clang linux-icc

PS:
​ 注意几个要点:

  • EGLFS EGLDevice, EGLFS GBM, EGL on x11的后面必须都是yes,不然就出大问题。(我搞了好久都没把EGLDevice, EGLFS GBM变成yes,不过后面也能用,就是不能在PC机上显示软件,得跑到rpi上运行才行,先凑合用吧~)
  • EGLFS Raspberry Pi 后面是no是对的,因为它代表的是树莓派3以前的旧驱动(brcm),树莓派4不用的。

如果出了问题,检查config.log,挨个排查问题吧。排查完后删除config.log和config.cache,重新执行前面的./configure。如果你配置成了,直接make就完事了

make -j4 && sudo make install

然而这只是编译了qtbase,很多其他的组件都是没有的,比如Quick。如果你想要其他的module,可以到其他文件夹里编译。

举个例子:交叉编译quickcontrols2组件:

由于qtquick2依赖于qtquick,而quick属于qtdeclarative,所以先编译qtdeclarative
cd ~/raspi/qt-everywhere-src-5.14.2/qtdeclarative
用刚刚编译出来的qmake工具来配置
这个qmake的作用是沿用前面qtbase交叉编译时的配置
~/raspi/qt5pi-host/bin/qmake
make就完事了,会安装到~/raspi/qt5pi中
make -j4 && make install
然后再编译我们要的quickcontrols2,步骤一样
cd ~/raspi/qt-everywhere-src-5.14.2/qtquickcontrols2
~/raspi/qt5pi-host/bin/qmake
make -j4 && make install

最后把编译好的Qt安装到树莓派上去:

rsync -avz qt5pi pi@your rpi IP address:/usr/local
# 记得改成你的树莓派的ip地址

4. 配置编译器

4.1 打开Qt Creator选择工具–>选项–>设备–>添加–>通用Linux设备

4.2 生成秘钥

完成设备添加,点击右边Test按钮测试能否成功连接树莓派

4.3 Tools-->Options...-->Kits-->Compilers 添加(Add):GCC-->C 和 GCC-->C++

C的配置
Name: GCC(Rasp Pi4)
Compiler path: /home/[你的用户名]/raspi/cross-compile-tool/bin/arm-linux-gnueabihf-gcc
C++的配置
Name: GCC(Rasp Pi4)
Compiler path: /home/[你的用户名]/raspi/cross-compile-tool/bin/arm-linux-gnueabihf-g++

4.4 Tools-->Options...-->Kits-->Debuggers 添加(Add):

Name: GDB(Raspberry pi)
Path: /home/[你的用户名]/raspi/cross-compile-tool/bin/arm-linux-gnueabihf-gdb

4.5 Tools-->Options...-->Kits-->Qt Versions添加(Add):

version name: Qt 5.14.2(Raspberry Pi 4)
qmake location:~/raspi/qt5-host/bin/qmake

4.6 Tools-->Options...-->Kits-->Kits添加(Add):

Name: RaspberryPi4 Qt5.14.2 32bit
Device Type:Generic Linux Device

Device: 选你刚刚创建的那个 Sysroot: ~/raspi/sysroot
Compiler: 选你刚刚创建的那个
Debugger: 选你刚刚创建的那个
Qt version: 选你刚刚创建的那个
Qt mkspec: 留空

保存退出,重启Qt Creator。

5 配置运行环境并测试

5.1【在树莓派上】配置环境变量

把以下内容追加到/etc/profile最后,可以根据需求自行修改:

# 存放我们自己编写的qt程序的路径
export PATH=$PATH:/home/pi/qt5  

# 其他
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH # 链接库路径
export QTDIR=/usr/local/qt5pi
export QT_QPA_FONTDIR=$QTDIR/lib/fonts 
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins/ 
export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_HIDECURSOR=1
export QT_QPA_EGLFS_ALWAYS_SET_MODE="1" # 这个非常重要,我也不知道为啥,没有这条就不行
export QML_IMPORT_PATH=$QTDIR/qml
export QML2_IMPORT_PATH=$QTDIR/qml

完事后重启树莓派。

5.2 修改 .pro 文件

# 删去原来的target.path,改成树莓派上放程序的路径
target.path = /home/pi/qt5

[参考链接]
https://zhuanlan.zhihu.com/p/138021025
https://zhuanlan.zhihu.com/p/137745265
https://blog.csdn.net/fax0371/article/details/104649698/
https://zhuanlan.zhihu.com/p/137745265
https://www.raspberrypi.org/downloads/raspbian/
https://www.raspberrypi.org/forums/viewtopic.php?t=204778
https://blog.csdn.net/xi_gua_gua/article/details/53413930?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

你可能感兴趣的:(树莓派4 + Qt5.14 PC端交叉编译)