不知不覺樹莓派都已經(jīng)4代了啥箭,硬件接口和內(nèi)核都發(fā)生了一些改變怀浆。最近需要在樹莓派上開發(fā)一些軟件,想利用PC端直接編譯生成搀别,鼓搗了半天丹擎,記錄一下~~(因?yàn)榭隙〞?..O(∩_∩)O)
編譯的時(shí)候涉及到了EGLFS,EGLFS是一個(gè)Qt5的平臺插件歇父,它的作用就是讓QT應(yīng)用直接運(yùn)行在EGL和OpenGL ES 2.0上(關(guān)于EGL和OpenGL ES 2.0的介紹具體可以看知乎上的這篇文章)蒂培。就是能讓你繞過圖形桌面,直接從顯卡輸出Qt圖像到屏幕榜苫。(具體的我也不太懂~~)
準(zhǔn)備工作
- 樹莓派4系統(tǒng)燒錄(可參考以前的博文) ,方法大體相同护戳,不過要下載最新的系統(tǒng)鏡像,3/4之間不能串用4共恰媳荒!
- Qt5 源碼下載(http://download.qt.io/archive/qt/),single文件夾里面的就是!
- 更換源(記得src的源的注釋要取消掉)
1.樹莓派固件更新
直接運(yùn)行大概率不會成功(因?yàn)楣Ψ蚓W(wǎng))驹饺。解決方法可以看知乎上這篇文章钳枕。推薦方法三(本地更新),魔法一下把文件下載下來赏壹。
sudo rpi-update
更新完畢以后重啟一下就好
sudo reboot
1.1 安裝樹莓派相關(guān)依賴
# 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驅(qū)動
sudo apt-get install libgles2-mesa-dev libgbm-dev
# 藍(lán)牙相關(guān) 可以不用安裝
sudo apt-get install bluez libbluetooth-dev
# 中文字體
sudo apt-get install ttf-wqy-zenhei
# 用于遠(yuǎn)程調(diào)試的GDB Server
sudo apt-get install gdbserver
1.2【在樹莓派上】建立文件夾并修改權(quán)限
sudo mkdir /usr/local/qt5pi # 用來安裝qt運(yùn)行庫
sudo chown -R pi:pi /usr/local/qt5pi
mkdir /home/pi/qt5 # 用來存放以后自己寫的qt程序可執(zhí)行文件
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啟用了硬爆。(我自己沒用命令行方式欣舵,還是用的桌面,大家根據(jù)自己的喜好就好)
1.4【在樹莓派上】把用戶pi添加到渲染組(重要)
sudo gpasswd -a pi render
2 PC端配置環(huán)境(Ubuntu18.04)
2.1 【在PC上】下載交叉編譯器并配置環(huán)境變量
mkdir ~/raspi
mkdir ~/raspi/cross-compile-tool
cd ~/raspi
在linaro網(wǎng)站下載交叉編譯工具鏈放到~/raspi
目錄下缀磕,包括gcc缘圈、runtime、sysroot三項(xiàng):
(因?yàn)闃漭晒俜降慕徊婢幾g工具鏈太老了袜蚕,比Qt5.14要求的低很多糟把,所以用linaro的)
?下載后解壓,并且合并放在~/raspi/cross-compile-tool目錄下(合并的意思是把壓縮包的內(nèi)容合并到一起牲剃,而不是把三個(gè)解壓后的目錄放在~/raspi/cross-compile-tool下)遣疯。
?然后設(shè)置環(huán)境變量:
echo 'export PATH=$PATH:~/raspi/cross-compile-tool/' | sudo tee -a /etc/profile
# echo后面一定要用單引號
source /etc/profile
# 刷新環(huán)境變量
? 修改/etc/sudoers,來讓你sudo的時(shí)候也能找到這個(gè)路徑凿傅。不過你不能直接用編輯器修改這個(gè)文件缠犀,要用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(源碼安裝)
? 在這個(gè)鏈接下載源碼和安裝包聪舒,我下的是5.14.2辨液。
qt-opensource-linux-x64-5.14.2.run
是Qt Creator的安裝包(我之前裝過5.13,Qt Creator就沒裝箱残,不過不耽誤滔迈,Creator可以構(gòu)建多種Kits)。single/qt-everywhere-src-5.14.2.tar.xz
是Qt源碼被辑,都下載到~/raspi
即可燎悍。安裝包直接運(yùn)行就能安裝,不知道裝啥組件的話就全裝吧盼理。源碼解壓就完事了谈山。
2.2 【在PC上】創(chuàng)建并配置sysroot
? 其實(shí)就是把樹莓派上的庫都弄到PC上來,形成一個(gè)和樹莓派一樣的環(huán)境宏怔,這樣我們交叉編譯的時(shí)候就可以鏈接到里面的庫和頭文件了勾哩。
執(zhí)行以下命令把庫和頭文件拷貝到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
目錄里面去,那肯定是錯(cuò)的妨猩,我們希望它們鏈接到sysroot
里面對應(yīng)的庫潜叛。所以我們需要把絕對路徑改成相對路徑。直接用網(wǎng)上現(xiàn)成的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
如果下載不下來威兜,沒關(guān)系销斟,貼給大家~~很精悍
#!/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] + "<directory>")
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
幾個(gè)參數(shù)簡單解釋一下,可以看./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-: 交叉編譯工具鏈的前綴笔宿,注意最后那個(gè)“-”號是不能少的
-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:
? 注意幾個(gè)要點(diǎn):
- EGLFS EGLDevice, EGLFS GBM, EGL on x11的后面必須都是yes犁钟,不然就出大問題。(我搞了好久都沒把EGLDevice, EGLFS GBM變成yes泼橘,不過后面也能用涝动,就是不能在PC機(jī)上顯示軟件,得跑到rpi上運(yùn)行才行炬灭,先湊合用吧~)
- EGLFS Raspberry Pi 后面是no是對的醋粟,因?yàn)樗淼氖菢漭?以前的舊驅(qū)動(brcm),樹莓派4不用的。
如果出了問題重归,檢查config.log米愿,挨個(gè)排查問題吧。排查完后刪除config.log和config.cache鼻吮,重新執(zhí)行前面的./configure吗货。如果你配置成了,直接make就完事了
make -j4 && sudo make install
然而這只是編譯了qtbase狈网,很多其他的組件都是沒有的,比如Quick笨腥。如果你想要其他的module拓哺,可以到其他文件夾里編譯。
舉個(gè)例子:交叉編譯quickcontrols2組件:
由于qtquick2依賴于qtquick脖母,而quick屬于qtdeclarative士鸥,所以先編譯qtdeclarative
cd ~/raspi/qt-everywhere-src-5.14.2/qtdeclarative
用剛剛編譯出來的qmake工具來配置
這個(gè)qmake的作用是沿用前面qtbase交叉編譯時(shí)的配置
~/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選擇工具–>選項(xiàng)–>設(shè)備–>添加–>通用Linux設(shè)備
4.2 生成秘鑰
完成設(shè)備添加烤礁,點(diǎn)擊右邊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: 選你剛剛創(chuàng)建的那個(gè) Sysroot: ~/raspi/sysroot
Compiler: 選你剛剛創(chuàng)建的那個(gè)
Debugger: 選你剛剛創(chuàng)建的那個(gè)
Qt version: 選你剛剛創(chuàng)建的那個(gè)
Qt mkspec: 留空
保存退出,重啟Qt Creator肥照。
5 配置運(yùn)行環(huán)境并測試
5.1【在樹莓派上】配置環(huán)境變量
把以下內(nèi)容追加到/etc/profile最后脚仔,可以根據(jù)需求自行修改:
# 存放我們自己編寫的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" # 這個(gè)非常重要,我也不知道為啥舆绎,沒有這條就不行
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