樹莓派開發筆記(二):qt開發環境搭建:樹莓派qt編譯和宿主機qt交叉編譯
樹莓派開發筆記(二):qt開發環境搭建:樹莓派qt編譯和宿主機qt交叉編譯
前話
前面已經成功執行樹莓派,下面使用qt開發樹莓派產品。
搭建樹莓派qt編譯環境(不推薦:開發編譯速度慢)
安裝樹莓派的桌面版本,可以直接配置qt環境,此種方法總是卡卡的,所以筆者不太推薦。
sudo apt-get update
sudo apt-get install qt5-default
sudo apt-get install qtcreator
(如果需要支援qml,需要下載qml的開發環境,使用以下命令)
sudo apt-get install qtdeclarative5-dev
直接進入qtcreator
需要自己手動配置構建套件,配置qmake,gcc,g++,gdb。
配置qmake
配置c和c++編譯器
配置套件
建立一個GUI程式,執行如下圖:
建立一個QtQuick程式,執行失敗,如下圖:
因為缺少相應的庫,輸入如下命令:
sudo apt-get install qtdeclarative5-dev
安裝完成後,執行如下圖:
搭建樹莓派qt交叉編譯環境(推薦:開發編譯速度快)
安裝ubuntu,是直接裝系統還是使用虛擬機器,大家看著辦,筆記上虛擬機器,筆者使用的系統是ubuntu14.04amd64。下載樹莓派的交叉編譯工具鏈
cd
mkdir ~/work
cd ~/work
sudo apt-get install git
git clone git://github.com/raspberrypi/tools.git
git時間有點漫長,請繼續等待,總共約1.3GB(壓縮包是800MB)左右,建議去其他地方下。
下載下來後我們直接放到~/work/tools
該工具鏈中包含了製作映象的工具,編譯器,測試程式碼等等,其實我們只用到了編譯器,因ubuntu是64位的,所以使用x64的,若是32位,則直接使用不帶x64尾綴下的即可。
檢測下編譯器是否執行成功:
將路徑引入系統環境變數:
export PATH=$PATH:~/work/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
測試
mkdir ~/work/project/testHello -p
cd ~/work/project/testHello
sudo apt-get install gedit
gedit main.c
輸入程式,並退出,儲存
#include <stdio.h>
int main(int argc, char **argv)
{
printf("Hello, you do it succeed!!!\n");
return 0;
}
然後編譯
arm-linux-gnueabihf-g++ main.c
輸出a.out,準備放到目標機驗證,使用FileZilla(參照FileZilla遠端傳送)傳送a.out檔案到是樹莓派桌面(樹莓派需要啟動ssh服務,可參照筆記一,配置樹莓派ssh服務)。
下面開啟另外一個終端,使用ssh遠端登入,作為交叉編譯的登入,我們建立測試資料夾,操作樹莓派:
mkdir ~/qtProject/testCrossCompile -p
cd ~/qtProject/testCrossCompile
cp ~/Desktop/a.out .
./a.out
輸出語句,交叉編譯程式成功。
使用FileZilla遠端傳送檔案(使用sftp)
ubunt上安裝sftp工具,ubuntu軟體中心搜尋filezilla並進行安裝。
樹莓派和ubuntu在同一個區域網,開啟filezilla軟體,登入樹莓派傳送
登入成功,可以傳送檔案了。
掛載樹莓派檔案系統
此處掛載樹莓派檔案系統,主要是對qt原始碼進行交叉編譯時,需要的一些標頭檔案和庫的依賴。在後面使用qt的qmake交叉編譯qt應用程式時,也會依賴一些庫,如操作樹莓派gpio則需要樹莓派自帶的本地庫。
將《筆記一》下載的樹莓派系統2018-03-13-raspbian-stretch.img拷貝到ubuntu的桌面上,操作ubuntu。
mkdir ~/work/img
cd ~/ work /img
mv ~/Desktop/2018-03-13-raspbian-stretch.img .
sudo mkdir /mnt/rasp-pi-rootfs
掛載主要分割槽,使用fdisk –l檢視掛載分割槽
此處,若offset不對,mount會提示需要指定檔案系統格式,所以要fdisk檢視。
sudo mount -o loop,offset=$((98304*512)) 2018-03-13-raspbian-stretch.img /mnt/pi-rootfs/
安裝ubuntu的qt(需要qmake和qtcreator)
qmake預設會使用系統的qmake,因為版本等問題,可能會直接影響後面qt編譯原始碼出現奇葩錯誤,所以下載直接可安裝的包,並且同時安裝了qctreaor用於開發樹莓派qt程式的IDE。
sudo apt-get update
sudo apt-get install g++
sudo apt-get install libgl1-mesa-dev
直接安裝qt5.9.3
安裝完成後,先建立一個gui程式,配置編譯構建套並跑起來。
此時如下命令:
ls -l /usr/bin/qmake
可發現連線的檔案不存在。
建立軟連線
sudo ln -sf /home/yang/Qt5.7.1/5.7/gcc_64/bin/qmake /usr/bin/qmake
檢查確認一次
下載qt原始碼
桌面版本安裝了qt5,那麼我們就沒必要自己配置了,下次也可以直接裝qt5,最關鍵的點是,下載交叉編譯的qt原始碼需要和樹莓派對應,我們檢視樹莓派qt的版本,如下圖,樹莓派的qt版本是5.7.1。
下載5.7.1的原始碼,如果讀者版本不一樣自己下載對應版本的原始碼。
將原始碼拷貝到~/work下,沒有該目錄就建立。
cd ~/work
tar xvf qt-everywhere-opensource-src-5.7.1.tar.gz
mv qt-everywhere-opensource-src-5.7.1 qt5.7.1
此處配置下系統,如果是32位則無需配置,是64位則需要新增32位支援
sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0
獲取交叉編譯
git clone https://github.com/darius-kim/cross-compile-tools.git
矯正庫檔案
cd cross-compile-tools
sudo ./fixQualifiedLibraryPaths /mnt/rasp-pi-rootfs/ ~/work/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc
配置qt編譯引數
下面對qt進行配置
cd ~/work/qt5.7.1/qtbase
./configure -opengl es2 -device linux-rasp-pi-g++ -device-option CROSS_COMPILE=arm-linux-gnueabihf- -sysroot /mnt/pi-rootfs -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -prefix /usr/local/qt5pi -hostprefix /usr/local/qt5pi -v
注意:-sysroot是編譯時參照的根目錄,-prefix是帶上sysroot相對參照根目錄的目錄,而-hostprefix是對於主機系統的目錄。所以以上配置路徑詳解為下:
編譯時查詢/usr/inclue/test.h標頭檔案,會查詢/mnt/pi-rootfs/usr/include/test.h
安裝時安裝到檔案路徑(prefix):/mnt/pi-rootfs/usr/local/qt5pi,主要是目標機的庫檔案,外掛等等,會自動分開裝為prefix和hostprefixe
安裝時安裝到檔案路徑(hostprefix):/usr/local/qt5pi,主要是主機編譯用。
配置過程出現錯誤如下:
切換一個終端查詢樹莓派下的libglesv2,是有的,如下圖
建立一個軟連線
cd /mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf
sudo ln -sf libGLESv2.so.2 libGLESv2.so
切回配置qt的終端,繼續配置,配置完成
編譯並安裝qtbase
使用make –j4,make過程也是先前出現g++,後續為arm-linux-gnueabihf-g++。
出現錯誤,找不到libz.so,librt.so,libm.so,如下圖:
經過檢視其實是有這三個庫的,只是因為他們是符號連結到/usr/lib所以出錯了,如下圖:
執行指令:
cd /mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf
sudo ln -sf /mnt/rasp-pi-rootfs/lib/arm-linux-gnueabihf/libm.so.6 libm.so
sudo ln -sf /mnt/rasp-pi-rootfs/lib/arm-linux-gnueabihf/librt.so.1 librt.so
sudo ln -sf /mnt/rasp-pi-rootfs/lib/arm-linux-gnueabihf/libz.so.1.2.8 libz.so
繼續make -j4,編譯完成
安裝sudo make install,安裝完成,下面編譯其他模組,最好按照順序編,之前筆者一直整體編譯,總是出現各種問題,入坑約1天多的時間。
檢查qmake
檢查qmake是否成功安裝(應該是有引數-hostprefix決定,不帶sysroot字首,而prefix帶sysroot)。
ls /usr/local/qt5pi/bin/qmake
找到qmake,可以交叉編譯其他模組。
先把qmake資料夾複製到/mnt/rasp-pi-roofs/usr/local/qt5pi
sudo cp -arf ~/work/qt5.7.1/qtbase/bin /mnt/rasp-p-rootfs/usr/local/qt5pi/
/mnt/rasp-pi-rootfs/usr/local/qt5pi/bin/qmake -v
在交叉編譯其他模組前,驗證以下qt交叉編譯是否可以成功編譯目標機上的程式。
編譯目標機程式並執行驗證(qml缺少模組,需要編譯其他模組)
下面開啟qtcreator建立一個工程,來檢測是否可以交叉編譯。
先配置構建套
主要是qmake最為關鍵:
建立一個testWidget專案交叉編譯。
編譯後無法執行,開啟終端執行檔案並檢視檔案
表示我們成功了一大半,然後放到樹莓派上桌面上執行,如下圖:
執行成功,如下圖:
編譯其他模組
下面,我們編譯其他交叉編譯的模組,這裡筆者將交纏編譯所有模組,因為作為開發機全一點比較好,部署時需要哪個就哪個,避免其他專案可能導致的需要重新編模組,對於大部分人,交叉編譯都是有點麻煩的。
cd ~/work/qt5.7.1/
/usr/local/qt5pi/bin/qmake
make -j4
sudo make install
重新使用目標平臺的qmake掃一遍所有模組(之前qtbase已配置好),然後make,編譯。
在編譯模組qtdeclarattive過程中,出現錯誤,如下圖:
修改原始碼
cd ~/work/qt5/qt-everywhere-opensource-src-5.7.1/qtdeclarative/src/qml/qml
gedit qqmlmemoryprofiler.cpp
搜尋static bool openLibrary()
在#ifndef QT_NO_LIBRARY上新增一句#define QT_NO_LIBARRY
編譯完成
建議多make兩次,僅make。
然後make install
至此5.7.1所有原始碼交叉編譯完美完成。
檢視prefix目標機,sysroot/prefix,bin是用於宿主機編譯目標機的,實際不能直接編,缺少mkspec配置編譯器,我們忽略bin目錄(以hostprefix為主)。
檢視hostprefix主機,主要是編譯編譯工具。