为树莓派4交叉编译QT5.14.2(带EGLFS支持)
0. 前言
我也不知道为什么我毕设要用QT,但是这都是我自己画的饼,哭着也要摊出来。
由于用的是树莓派4,而树莓派4恰好使用了和前几代都不一样的图形驱动(以前是博通的,现在是mesa的),所以网上资料很少,我一开始还陷入了旧教程之中导致各种各样的问题,坑了我好多时间。
然后再谈谈EGLFS,EGLFS是一个Qt5的平台插件,它的作用就是让QT应用直接运行在EGL和OpenGL ES 2.0上(关于EGL和OpenGL ES 2.0的介绍具体可以看 这篇文章 )。说白了,就是能让你绕过图形桌面,直接从显卡输出Qt图像到屏幕。如果想直观地体验我刚说的“绕过桌面直接输出”,可以看我的 这篇文章 。
当然也许你也想让Qt程序在图形界面中,以窗口形式运行。这当然也是可以的,后面会具体说。
本文的步骤如下:
- 在树莓派4上安装依赖包,并进行一些准备
- 在PC上安装QT Creator,下载源码,下载交叉编译工具工具链
- 将树莓派4上的库复制到到PC上做一个sysroot,交叉编译时用
- 配置,编译,安装到树莓派4上
- 在树莓派4上配置运行环境,运行例程
1. 在树莓派上的前期准备
换源之类的基本操作就不再多啰嗦了(记得src的源的注释要取消掉),只说重要的。
1.1.【在树莓派上】更新固件(重要)
使用
sudo rpi-update
,直接运行大概率不会成功(因为功夫网)。解决方法可以看我的
这篇文章
。
具体可以查看
/opt/vc/lib
目录下的内容,更新前是没有
libEGL.so
和
libGLESv2.so
的,只有
libbrcmEGL.so
和
libbrcmGLESv2.so
,brcm的意思是博通,而我们前面说了博通的驱动是以前的树莓派用的......所以老实更新吧。
完事之后重启
sudo reboot
【紧急补充】在换了树莓派官方7寸屏幕以后,发现rpi-update会导致屏幕只能显示而无法触摸。这是因为官网下载的树莓派系统自带rpi-ft5406触摸驱动,但是更新后的内核还没添加这个驱动支持。于是我用:
sudo apt --reinstall install raspberrypi-kernel
把内核版本改了回去,触摸屏又能用了;同时,/opt/vc/lib里面的libEGL.so和libGLESv2.so库还在,所以QT还能继续支持eglfs。
1.2.【在树莓派上】安装以下包:
# 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.3.【在树莓派上】建立文件夹并修改权限:
sudo mkdir /usr/local/qt5pi # 用来安装qt运行库
sudo chown -R pi:pi /usr/local/qt5pi
mkdir /home/pi/qt5 # 用来存放以后自己写的qt程序可执行文件
1.4.【在树莓派上】开启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.5 【在树莓派上】把用户pi添加到渲染组(重要)
sudo gpasswd -a pi render
2. 在PC上的前期准备
我使用的是Ubuntu 18.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的时候也能找到这个路径。不过你不能直接用编辑器修改这个文件,你必须:
sudo visudo
然后在
secure_path
后面的路径中追加一串
:/home/你的用户名/raspi/cross-compile-tool/bin
,比如我的就是这样:
secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/home/jayant/cross-compile-tool/bin"
检查配置是否正常:
arm-linux-gnueabihf-g++ -v
sudo arm-linux-gnueabihf-g++ -v
# 有版本信息输出就是正常
2.2.【在PC上】下载Qt Creator安装包和源码
在 这个链接 下载源码和安装包,我下的是5.14.2。
qt-opensource-linux-x64-5.14.2.run
是Qt Creator的安装包;
single/qt-everywhere-src-5.14.2.tar.xz
是Qt源码,都下载到
~/raspi
即可。
安装包直接运行就能安装,不知道装啥组件的话就全装吧。
源码解压就完事了。
2.2. 【在PC上】创建并配置sysroot
其实就是把树莓派上的库都弄到PC上来,形成一个和树莓派一样的环境,这样我们交叉编译的时候就可以链接到里面的库和头文件了。
执行以下命令把库和头文件拷贝到PC上:
cd ~/raspi
rsync -avz pi@192.168.0.105:/lib sysroot
rsync -avz pi@192.168.0.105:/usr/include sysroot/usr
rsync -avz pi@192.168.0.105:/usr/lib sysroot/usr
rsync -avz pi@192.168.0.105:/opt/vc sysroot/opt
# 记得改成你的树莓派的ip地址
然后需要修改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
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
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
Note: PKG_CONFIG_LIBDIR automatically set to /home/jayant/raspi/sysroot/usr/lib/pkgconfig:/home/jayant/raspi/sysroot/usr/share/pkgconfig:/home/jayant/raspi/sysroot/usr/lib/arm-linux-gnueabihf/pkgconfig
Note: PKG_CONFIG_SYSROOT_DIR automatically set to /home/jayant/raspi/sysroot
Note: -optimized-tools is not useful in -release mode.
注意几个要点:
-
EGLFS EGLDevice
,EGLFS GBM
,EGL on x11
的后面必须都是yes,不然就出大问题。 -
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@192.168.0.105:/usr/local
# 记得改成你的树莓派的ip地址
4. 配置Qt Creator
【在PC上】
-
4.1 点开菜单栏
Tools-->Options...--> Environment
可以更改语言和主题
我蛮喜欢Flat Dark这个主题的
-
4.2
Tools-->Options...--> Devices
添加(Add): Generic Linux Device
输入树莓派的ip地址,用户名
选择ssh私钥
(旧的Qt Creator是用密码验证的,但是都0202年了为什么不用私钥呢?? 利用 SSH 及其配置文件节省你的生命 )
Name:
pi4
-
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: 留空
(这里面Kit的图标是可以改的,我是网上找了个树莓派的png)
保存退出,重启Qt Creator。
5 配置运行环境并测试
【在树莓派上】配置环境变量
把以下内容追加到
/etc/profile
最后,可以根据需求自行修改:
# 存放我们自己编写的qt程序的路径
export PATH=$PATH:/home/pi/qt5
# eglfs屏幕物理尺寸,单位毫米
export QT_QPA_EGLFS_PHYSICAL_WIDTH=84
export QT_QPA_EGLFS_PHYSICAL_HEIGHT=56
# eglfs屏幕分辨率
export QT_QPA_EGLFS_WIDTH=480
export QT_QPA_EGLFS_HEIGHT=320
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