樹莓派4 + Qt5.14 PC端交叉編譯

不知不覺樹莓派都已經(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)備工作

  1. 樹莓派4系統(tǒng)燒錄(可參考以前的博文) ,方法大體相同护戳,不過要下載最新的系統(tǒng)鏡像,3/4之間不能串用4共恰媳荒!
  2. Qt5 源碼下載(http://download.qt.io/archive/qt/),single文件夾里面的就是!
  3. 更換源(記得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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市猎醇,隨后出現(xiàn)的幾起案子窥突,更是在濱河造成了極大的恐慌,老刑警劉巖硫嘶,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阻问,死亡現(xiàn)場離奇詭異,居然都是意外死亡沦疾,警方通過查閱死者的電腦和手機(jī)称近,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來曹鸠,“玉大人煌茬,你說我怎么就攤上這事〕固遥” “怎么了坛善?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長邻眷。 經(jīng)常有香客問我眠屎,道長,這世上最難降的妖魔是什么肆饶? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任改衩,我火速辦了婚禮,結(jié)果婚禮上驯镊,老公的妹妹穿的比我還像新娘葫督。我一直安慰自己,他們只是感情好板惑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布橄镜。 她就那樣靜靜地躺著,像睡著了一般冯乘。 火紅的嫁衣襯著肌膚如雪洽胶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天裆馒,我揣著相機(jī)與錄音姊氓,去河邊找鬼。 笑死喷好,一個(gè)胖子當(dāng)著我的面吹牛翔横,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梗搅,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼棕孙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蟀俊,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钦铺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后肢预,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矛洞,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年烫映,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沼本。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锭沟,死狀恐怖抽兆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情族淮,我是刑警寧澤辫红,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站祝辣,受9級特大地震影響贴妻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蝙斜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一名惩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧孕荠,春花似錦娩鹉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至槐瑞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阁苞,已是汗流浹背困檩。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留那槽,地道東北人悼沿。 一個(gè)月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像骚灸,于是被迫代替她去往敵國和親糟趾。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355