1. 程式人生 > >樹莓派開發筆記(二):qt開發環境搭建:樹莓派qt編譯和宿主機qt交叉編譯

樹莓派開發筆記(二):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/

安裝ubuntuqt(需要qmakeqtcreator

        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主機,主要是編譯編譯工具。