qt5.10.1交叉編譯【帶opengl ES2】(armv8 64位)
本次交叉編譯是樹莓派學習::qt5交叉編譯(armv8 64位).的升級版,這次編譯帶opengl Es2的qt,原因是爲了可以在樹莓派上運行QtQuick2的程序。
結果:編譯倒是編譯出來了,但是
程序在目標板上跑不了,目測原因是該64位系統不支持opengl(或者說驅動沒弄對)。可以利用xcb運行,只是比較慢,因爲沒有了物理的opengl驅動支持,只有mesa的opengl了,畢竟是非官方系統。以linuxfb運行程序時,程序打開,界面也有了,但只是殘影,鼠標晃一下就沒了,產生這個情況的原因是qt5.9對linuxfb做出了修改,qt5.9之後linuxfb只能在純命令行下打開程序顯示gui,否則會花屏。。還不如直接用xcb。雖然是半成品,但是這個過程對我的下一步(qt5.10.1交叉編譯到樹莓派官方系統)有很大幫助。
測試環境(與樹莓派學習::qt5交叉編譯(armv8 64位)一致)
(1)硬件設備
- msi筆記本,I7-4710H,16G內存
- 樹莓派3b+,armv8(64位),16Gsd卡
(2)系統環境
- 筆記本:ubuntu16.04 x64位
- 樹莓派3b+:debian9 x64位
環境配置及編譯過程
一、樹莓派環境配置
(1)由於還是用那個非官方的64位系統,就不再贅述系統的安裝步驟了
(2)安裝opengl
sudo apt-get install libgles2-mesa
sudo apt-get install libgles2-mesa-dev
(3)安裝編譯QT所需的環境【儘管我們不是在開發板上編譯QT,但是我們需要這些庫來構建sysroot】
sudo apt-get install libxcb-xinerama0-dev
sudo apt-add-repository ppa:u-szeged/sedkit
sudo apt-get update
sudo apt-get install sedkit-env-qtwebkit
sudo apt-get install build-essential perl python git
sudo apt-get install libx11-dev libxcb1-dev libxkbcommon-x11-dev libx11-xcb-dev libxext-dev
sudo apt-get install flex bison gperf libicu-dev libxslt-dev ruby
sudo apt-get install libssl-dev libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev libfontconfig1-dev libcap-dev libxtst-dev libpulse-dev libudev-dev libpci-dev libnss3-dev libasound2-dev libxss-dev libegl1-mesa-dev gperf bison
sudo apt-get install libbz2-dev libgcrypt11-dev libdrm-dev libcups2-dev libatkmm-1.6-dev
sudo apt-get install libasound2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
(4)檢查系統的編譯器版本
二、筆記本(ubuntu16.04)環境配置
(1)交叉編譯器下載
https://releases.linaro.org/components/toolchain/binaries/6.3-2017.05/aarch64-linux-gnu/
下載下圖兩個東西:
一個是編譯器,一個是sysroot
(2)配置交叉編譯器
不贅述,可參見 樹莓派學習::qt5交叉編譯(armv8 64位). 中的配置過程
(3)我們還下了另外一個東西,就是sysroot
簡述一下這個東西的作用:用來構造文件系統,我們還需要把開發板上的opt、lib、usr等目錄覆蓋上去,二者合成一個文件系統,用來提供給交叉編譯時編譯器尋找頭文件.h和庫文件.so等東西用的。這樣才能提供一個基本與目標開發板一致的環境,給出這個環境之後,編譯時找頭文件就不在筆記本(ubuntu16.04)的環境找了,只在sysroot這個目錄裏面找。
1)找個地方,創個目錄
mkdir pi pi/sysroot
2)將下載下來的東西解壓到sysroot目錄下,效果如下:
3)取出樹莓派sd卡,在sd卡的rootfs目錄下,將lib、opt、usr/include、usr/lib目錄的東西覆蓋到這個/home/msi/pi/sysroot的對應目錄。
選擇合併、遇到相同的選擇覆蓋即可
【只要想着要構造出開發板的文件環境,你就知道怎麼辦了】
4)複製完成之後,回到pi目錄下,新建一個sysroot.py文件,內容如下:
#!/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)
5)保存後,給權限
sudo chmod +x sysroot.py
6)在pi目錄下,執行如下,用來解決該目錄下的符號鏈接問題
./sysroot.py sysroot
7)到這裏,就基本環境配置完成
三、編譯QT
(1)下載源碼,這裏我要編譯的版本是qt5.10.1
http://download.qt.io/archive/qt/
選擇對應的源碼下載即可
(2)將源碼解壓,位置隨意
(3)進入解壓目錄,新建一個autoconfig.sh文件,用來修改配置參數,內容如下
- 其中,-prefix 後的路徑爲輸出路徑,但由於我們給了sysroot這個路徑,所以最終的輸出路徑爲sysroot/prefix,即我們最終的編譯結果在/home/msi/pi/sysroot/home/msi/arm/qt5101_64/qt_sdk,這裏
- -sysroot爲我們剛剛構建開發板文件系統的路徑
- -linuxfb表示編譯這個插件,這個是軟件渲染的插件,用於顯示qtgui程序
- -eglfs 爲硬件渲染插件,用這個運行程序,將會強制程序全屏化
- -openg es2表示編譯帶opengl es2的qt
#!/bin/sh
./configure -prefix /home/msi/arm/qt5101_64/qt_sdk \
-verbose \
-opensource \
-release \
-confirm-license \
-xplatform linux-arm-gnueabi-g++ \
-shared \
-qt-zlib \
-qt-libjpeg \
-qt-libpng \
-make libs \
-linuxfb \
-eglfs \
-no-cups \
-no-iconv \
-no-pch \
-no-opengl \
-opengl es2 \
-no-openssl \
-nomake examples \
-sysroot /home/msi/pi/sysroot
(4)從qt源碼根目錄中,進入
1)修改qmake.conf文件
- QMAKE_INCDIR_OPENGL[_ES2]、QMAKE_LIBDIR_OPENGL[_ES2]、QMAKE_LIBS_OPENGL[_ES2]這些用來指定opengl es2的頭文件和庫文件等,路徑可根據自身實際修改,關鍵要找到opengl es2和egl的頭文件庫文件路徑
- 然後將編譯器改成剛剛在前面配置的交叉編譯器,(看不懂的請參見: 樹莓派學習::qt5交叉編譯(armv8 64位).中的描述)即修改成下圖的框框內容:
2)修改後的內容如下
#
# qmake configuration for building with arm-linux-gnueabi-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
QMAKE_INCDIR_POST += \
$$[QT_SYSROOT]/usr/include \
$$[QT_SYSROOT]/usr/include/aarch64-linux-gnu
QMAKE_LIBDIR_POST += \
$$[QT_SYSROOT]/usr/lib \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu
QMAKE_RPATHLINKDIR_POST += \
$$[QT_SYSROOT]/usr/lib \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu/tegra \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu
QMAKE_INCDIR_OPENGL[_ES2] += \
$$[QT_SYSROOT]/include \
$$[QT_SYSROOT]/include/EGL \
$$[QT_SYSROOT]/include/GLES2 \
$$[QT_SYSROOT]/include/GLES3 \
$$[QT_SYSROOT]/include/KHR \
$$[QT_SYSROOT]/usr/include \
$$[QT_SYSROOT]/usr/include/EGL \
$$[QT_SYSROOT]/usr/include/GLES2 \
$$[QT_SYSROOT]/usr/include/GLES3 \
$$[QT_SYSROOT]/usr/include/KHR
QMAKE_LIBDIR_OPENGL[_ES2] += \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu/mesa-egl \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu/tegra-egl \
$$[QT_SYSROOT]/lib/aarch64-linux-gnu \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu/mesa-egl \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu/tegra-egl \
$$[QT_SYSROOT]/usr/lib/aarch64-linux-gnu
QMAKE_LIBS_OPENGL[_ES2] += -lEGL -lGLESv2
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC = aarch64-linux-gnu-gcc
QMAKE_CXX = aarch64-linux-gnu-g++
QMAKE_LINK = aarch64-linux-gnu-g++
QMAKE_LINK_SHLIB = aarch64-linux-gnu-g++
# modifications to linux.conf
QMAKE_AR = aarch64-linux-gnu-ar cqs
QMAKE_OBJCOPY = aarch64-linux-gnu-objcopy
QMAKE_NM = aarch64-linux-gnu-nm -P
QMAKE_STRIP = aarch64-linux-gnu-strip
load(qt_config)
(5)開始配置qt編譯參數,即在qt源碼根目錄下,運行autoconfig.sh即可
sudo chmod +x autoconfig.sh
./autoconfig.sh
配置結果有可能會提示opengl function test failed ,大概像這樣
#opengl es2頭文件、庫文件配置有錯誤:
ERROR: Feature 'opengles2' was enabled, but the pre-conditio
#EGL 頭文件或庫文件路徑配置有錯誤:
ERROR: Feature 'eglfs' was enabled, but the pre-conditio
這時候 ,可以在qt源碼根目錄下找到config.log,這個是configure配置時生成的日誌,慢慢找是什麼錯誤即可。
重新修改完後,還不能直接重新運行autoconfig.sh,需刪除之前的配置文件config.cache和config.log,即刪除下圖的兩個文件:
直到配置成功,大概會有如下輸出:
(6)開始編譯
make -j4
編譯過程中,如果因出錯而停止,而錯誤信息又看不到的時候,可再次運行一次make,這時候錯誤信息就很容易找到了
如果提示缺少什麼頭文件、庫文件這些,查到對應問題後,
(1)可以將sd卡插回到板子上,用apt-get進行安裝之後,
(2)重新配置sysroot,(即重新拷貝lib、usr/include、usr/lib等文件夾到sysroot對應目錄),
(3)然後重新修正符號鏈接(即再次運行 ./sysroot.py sysroot)
(4)重新回到qt源碼根目錄,接着make -j4即可繼續編譯
編譯完成輸出:
(7)編譯完成之後,運行make install
make install
(8)全部完成之後,可以看到生成的東西在sysroot目錄下的prefix路徑,即
四、開發板再配置
(1)將編譯後的結果複製到開發板/home/pi目錄下,我的目錄是
編譯結果的路徑如下:/home/msi/pi/sysroot/home/msi/arm/qt5101_64
複製到樹莓派下:/home/pi/qt5101_64
(2)開發板qt庫路徑配置
配置Qt的運行時環境,打開/etc/profile,在最後一行輸入一下內容:
export QTDIR=/home/pi/qt5101_64/qt_sdk #qtsdk在系統上的路徑
export QT_QPA_FONTDIR=$QTDIR/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins/
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0 #framebuffer驅動
export QWS_MOUSE_PROTO=/dev/input/event0
如果配置了qml,要運行qtquick程序,還要加上下面的配置(否則會提示QTQUICK模塊沒有安裝,具體可參見:
https://lemirep.wordpress.com/2013/06/01/deploying-qt-applications-on-linux-and-windows-3/):
export QML_IMPORT_PATH=$QTDIR/qml
export QML2_IMPORT_PATH=$QTDIR/qml
(3)刷新配置
source /etc/profile
(4)庫文件配置
1)在/etc/ld.so.conf.d/目錄下,新建一個qt5.conf
sudo gedit /etc/ld.so.conf.d/qt5.conf
2)加入qt_sdk的路徑,即
/home/pi/qt5101_64/qt_sdk/lib/
3)刷新
sudo ldconfig
五、 測試
測試結果:
- 編譯qt成功
- 筆記本下編譯程序有的會報錯提示找不到stdlib.h,有的程序又沒報錯
- 將交叉編譯的程序複製到開發板
- 檢查庫文件是否都齊全:
ldd 文件名
- 運行文件,可直接./文件名運行,也可後面加參數 -platform linuxfb或者 -platform eglfs,來指定平臺運行
運行結果:程序打開後,只留下程序界面的殘影,鼠標滑動就沒了。。。可能 是該系統 不支持opengl?
(1)關於提示#include_next<stdlib.h>no such file stdlib.h 的解決方案:
如果構建時,提示#include_next<stdlib.h>找不到 stdlib.h文件,那麼,可嘗試在.pro文件中加入一行:
QMAKE_CFLAGS_ISYSTEM=
相關可參見:https://github.com/voidlinux/void-packages/issues/5254
(2)運行測試
1)瞭解到qt5.9後關於linuxfb渲染插件的變化後,我重新嘗試使用linuxfb運行
2)在xcb渲染插件下運行,速度較慢,但是可以完美顯示qtquick2的程序,可能用了xcb調用了mesa的opengl