移植Qt5.6到imx6系列處理器移植過程說明--支持qml

需要word版本的同學可自行下載:點此下載

由於項目需要,領導要求實現Qt5的移植,目標板是imx6sx,且界面一定要炫酷.....好吧,既然要炫酷,當然要利用Qt的qml,然而qml又需要opengl的支持。

於是便開始了虐心的Qt5.6移植之旅,我的移植過程大體可以分爲三個階段,也是自己探索的過程。

第一階段,我嘗試手動移植opengl和Qt,然而需要的第三方庫數不勝數,且中間錯誤頻出,所以改變策略,進入第二階段

第二階段,使用yocto移植Qt5,yocto很好用,但是編譯時間比較長,大部分時間用來下載,但不管怎麼說,使用這種方法成功了,但是缺點是yocto的每一個版本只有一個QT版本,而yocto版本又是隨着內核版本更新的,比如最新版本的yocto源碼包含的是Qt5.5.1,而我要移植的是Qt5.6版本,原因有兩點,1、5.6是LTS版本,2、5.6版本比5.5版本多了一些我需要的控件,比如Qt.lab.controls中的drawer。我試過直接替換其中Qt源碼爲5.6版本,但是仍然是錯誤頻出。所以進入第三階段

第三階段,我使用yocto生成opengl等相關庫,然後再手動編譯Qt5.6,最終測試成功。

移植過程如下:

開發環境說明

操作系統:windows7 x64

宿主機:vmware10+Ubuntu14.04LTS32bit

目標機:i.mx6sx

 

使用工具說明

Yocto是一個開源社區,它通過提供模版、工具和方法幫助開發者創建基於linux內核的定製系統。具體的yocto使用方法請參考YoctoProject Quick Start

 

Bitbakeyocto提供的構建工具,可以使用bitbake命令生成特定的鏡像、單獨編譯某一個模塊、清除生成的文件等等,它的功能類似於make

 

RepoGooglepython腳本寫的調用Git的腳本,它與git的區別是,repo可以一次性從多個倉庫獲取資源到本地。

 

Linaro是由ARM飛思卡爾IBMSamsungST-Ericsson 及德州儀器 (TI)等半導體廠商聯合創立的非營利性質的開源軟件公司。致力於開發不同半導體公司系統單芯片(SoC)平臺的共通軟件。在編譯Qt5的過程中,我們使用linaro提供的交叉編譯工具,經過測試4.6版本與3.10.17版本的sysroot可配合使用,4.6版本與4.1.15版本sysroot配合使用會出問題,找不到libc庫。4.84.9版本經過測試可以與4.1.15版本sysroot配合使用。目前linaro官方提供的最新版本是5.3版本,尚未測試。

 

依賴關係說明

Qt quick模塊需要opengl支持來生成libQt5OpenGL.so等相關庫文件,opengl庫由於涉及到gpu,所以又跟內核與設備樹息息相關,一個可用的opengl庫必須滿足兩點:1,可用於對應的目標機器 2、與對應的內核版本匹配。所以可以看到網上下載的gpu庫的命名格式爲gpu-viv-bin-machine-kernelVersion,例如:gpu-viv-bin-imx6q-3.10.17-1.0.0.tar.gz

由上所述,我們可以知道,Qt5的移植也需要與內核版本保持一致,換句話說,更換內核版本後意味着要重新移植與之匹配的Qt5

 

使用yocto移植Qt5過程說明

1、 安裝Ubuntu,也可以使用其他操作系統,但是yocto官方提供的手冊中都是以Ubuntu爲例,建議安裝Ubuntu14.04LTS版本,且最少分配100G的磁盤空間。安裝過程不做說明。

2、 安裝移植過程中Ubuntu系統所需要的軟件包

$ sudo apt-get installgawk wget git-core diffstat unzip texinfo gcc-multilib \

build-essential chrpath socat

$ sudo apt-get install libsdl1.2-dev xterm sed cvssubversion coreutils texi2html \

docbook-utils python-pysqlite2 help2man make gcc g++desktop-file-utils \

libgl1-mesa-dev libglu1-mesa-dev mercurialautoconf automake groff curl lzop asciidoc

$ sudo apt-get install u-boot-tools

3、 安裝repo

$ mkdir ~/bin

$ curlhttp://php.webtutor.pl/en/wp-content/uploads/2011/09/repo > ~/bin/repo

$ chmod a+x ~/bin/repo

$ export PATH=~/bin:$PATH

4、  同步yocto工程

$ mkdir fsl-release-bsp

$ cd fsl-release-bsp

$ git config --globaluser.name "Your Name"

$ git config --globaluser.email "Your Email"

$ git config --list

$ repo init -ugit://git.freescale.com/imx/fsl-arm-yocto-bsp.git -b imx-3.14.28-1.0.0_ga

$ repo sync

5、  配置構建選項

3.14.28版本

$ MACHINE=imx6qsabreauto sourcefsl-setup-release.sh –bbuild-fb –e fb

4.1.15版本

$ MACHINE=imx6qsabreauto sourcefsl-setup-release.sh –bbuild-fb DISTRO=fsl-imx-fb

如上所示,不同的yocto工程版本的配置命令略有不同,具體的命令需要參考對應版本源碼中的README文件。

6、  構建鏡像

$ bitbake fsl-image-qt5

其中fsl-image-qt5爲配方名稱,可以使用如下命令查看配方。

$ bitbake –s

這個命令會列出所有的配方,但是由於yocto支持的廠家不止飛思卡爾一家,所以顯示出來的配方會特別多,可以使用下面命令查找自己所需要的配方。

$ bitbake –s | grep qt              列出所有可生成qt的配方

$ bitbake –s | grep fsl              列出所有飛思卡爾處理器可使用的配方

$ bitbake –s | grep toolchain    列出所有工具鏈的配方

在構建的過程中可能會出現錯誤,一個通用的解決辦法是,先清除構建出問題的任務,然後再重新構建。

$ bitbake –c cleanall taskname

$ bitbake –c build taskname

$ bitbake fsl-image-qt5

由於構建鏡像的過程,多個包之間存在依賴關係,有時候生成的構建隊列的順序會有問題,比如A依賴B,但是在構建隊列中,A在B之前構建,這個時候A就會找不到B,從而出現錯誤,這種問題的解決辦法是,先清除A,然後手動構建B,然後再重新bitbake。但是前提是要了解他們之間的依賴關係。

$ bitbake –c cleanall A

$ bitbake –c build B

$ bitbake fsl-image-qt5

7、 上一步成功之後,官方提供的u-boot、zImage、rootfs就已經生成了,它們所在的路徑是:BUILDDIR/tmp/deploy/image/imx6sxsabresd/,在生成的文件系統中,已經包含了移植好的Qt5,且gpu需要的相關庫也已經生成。但是Qt開發還需要qmake,而qmake可以使用生成工具鏈相關的配方構建,執行下面命令:

$ bitbake fsl-toolchain-qt5

這個命令執行成功後,會在BUILDDIR/tmp/deploy/路徑下生成sdk目錄,執行sdk目錄下的腳本文件

$ sh BUILDDIR/tmp/deploy/sdk/xxxxxxxxx.sh

運行該腳本後,會在/opt目錄下生成工具鏈和qmake。

 

至此,使用yocto移植Qt5就已經完成了,如果對Qt版本以及內核版本沒有特殊要求的話,就可以使用上面生成的SDK來進行Qt應用程序的開發了。如果對於Qt版本以及內核版本有特殊要求的話,那麼就需要繼續完成下面的操作,來獲取你想要的版本,因爲yocto工程的每一個分支都提供一個確定版本的Qt配方,比如,如果你選擇使用4.1.15版本內核,那麼意味着你就必須使用Qt5.5.1版本,我曾嘗試過直接替換yocto工程Qt5層的配方,但是最終生成的鏡像對於字體沒有很好的支持,通過查閱資料,我瞭解到,同一層的所有配方最好是隸屬於同一分支,否則可能會出問題,甚至無法生成鏡像,因爲各層之間是互相關聯的,且yocto工程源碼、補丁衆多,想要修改配方文件亦無從下手。所以最好的方法是,使用yocto生成sysroot,然後使用生成的sysroot手動移植Qt5。

 

手動移植Qt5過程說明

1、  下載所需源碼,清單如下:

qt-everywhere-opensource-src-5.6.0.tar.gz

gcc-linaro-arm-linux-gnueabihf-4.9-2014.07_linux.tar.gz

2、  使用yocto獲取sysroot,根據自己的需要可自行選擇內核版本。此步驟在上面已經介紹過了,此處不做贅述,我們需要的sysroot的路徑爲:build/tmp/sysroots/machieName/

3、  解壓已經下載的qt源碼以及交叉編譯工具,將交叉編譯工具的路徑添加到PATH,並聲明CROSS_COMPILE。

exportCROSS_COMPILE=${cross compile dir}/bin/arm-linux-gnueabihf-

export PATH=${cross compile dir}/bin

4、 編輯qmake.conf,路徑在Qt源碼下qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf,我的qmake.conf如下。

MAKEFILE_GENERATOR      = UNIX

CONFIG                 += incremental

QMAKE_INCREMENTAL_STYLE= sublib

 

include(../common/linux.conf)

include(../common/gcc-base-unix.conf)

include(../common/g++-unix.conf)

 

QMAKE_LIBS_EGL         += -lEGL

QMAKE_LIBS_OPENGL_ES2  += -lGLESv2 -lEGL -lGAL

QMAKE_LIBS_OPENVG      += -lOpenVG -lEGL -lGAL

 

IMX6_CFLAGS             = -march=armv7-a -mfloat-abi=hard-mfpu=neon -mtune=cortex-a9

QMAKE_CFLAGS           += $$IMX6_CFLAGS

QMAKE_CXXFLAGS         += $$IMX6_CFLAGS

 

DISTRO_OPTS+= hard-float

 

#Preferred eglfs backend

EGLFS_DEVICE_INTEGRATION= eglfs_viv

 

QT_QPA_DEFAULT_PLATFORM= eglfs

QMAKE_CFLAGS_RELEASE   += -O2 $$QMAKE_CFLAGS

QMAKE_CXXFLAGS_RELEASE+= -O2 $$QMAKE_CXXFLAGS

 

#modifications to g++.conf

QMAKE_CC                = arm-linux-gnueabihf-gcc

QMAKE_CXX               = arm-linux-gnueabihf-g++

QMAKE_LINK              = arm-linux-gnueabihf-g++

QMAKE_LINK_SHLIB        = arm-linux-gnueabihf-g++

 

#modifications to linux.conf

QMAKE_AR                = arm-linux-gnueabihf-ar cqs

QMAKE_OBJCOPY           = arm-linux-gnueabihf-objcopy

QMAKE_NM                = arm-linux-gnueabihf-nm -P

QMAKE_STRIP             = arm-linux-gnueabihf-strip

#include(../devices/common/linux_arm_device_post.conf)

load(qt_config)

5、 配置Qt,我的配置如下:

./configure--prefix=/QtInstall -c++std c++11 -debug-and-release -qt-zlib -qt-libpng \

-xplatformlinux-arm-gnueabi-g++ -qt-freetype -fontconfig -no-directfb -qt-pcre \

-sysconfdir/QtInstall/sysconf -nomake tests -nomake examples -no-xcb -no-iconv \

-eglfs-opengl es2 -pkg-config \

-device-optionCROSS_COMPILE=/opt/crossCompile-linaro-4.9/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07_linux/bin/arm-linux-gnueabihf-\

-sysroot/home/yocto/fsl-release-bsp/bld-fb/tmp/sysroots/imx6sxsabresd –v

 

   其中字體配置部分選項,如果配置了fontconfig,那麼freetype則使用系統提供的庫,如果沒有配置fontconfig,則freetype可以配置爲-qt-freetype,即使用qt提供的freetype。但是qt5.6的官網文檔中特別指出:

   Qt no longer ships anyfonts in thelib/fonts directory. This means thatit is up to the platform (the system image) to provide the necessary fonts.

   這意味着Qt雖然提供字體支持,但是不再集成字庫到lib下。所以,爲了避免因此產生的影響,我們使用系統提供的字體支持,但是前提是你已經獲取了libfreetype.so。通常這些庫文件sysroot已經提供。

配置完成後,會有just run ‘make’的提示。我的配置結果如下:

Build options:

Configuration .......... accessibility alsa audio-backend c++11clock-gettime clock-monotonic compile_examples concurrent cross_compile dbusdbus-linked egl eglfs eglfs_gbm eglfs_viv enable_new_dtags evdev eventfdfontconfig full-config gbm getaddrinfo getifaddrs glib gstreamer-1.0 harfbuzzicu inotify ipv6ifname kms large-config largefile libudev linuxfb medium-configminimal-config mremap neon nis opengl opengles2 openssl openvg pcre pngposix_fallocate precompile_header pulseaudio qpa qpa reduce_exports releaserpath shared small-config system-freetype system-jpeg threadsafe-cloexecuse_gold_linker zlib

  Build parts ............ libs

  Mode ................... release

  Using sanitizer(s)...... none

  Using C++ standard ..... c++11

  Using gold linker....... yes

  Using new DTAGS ........ yes

  Using PCH .............. yes

  Using LTCG ............. no

  Target compiler supports:

    Neon ................. yes

 

Qt modules andoptions:

  Qt D-Bus ............... yes (linked todbus-1)

  Qt Concurrent .......... yes

  Qt GUI ................. yes

  Qt Widgets ............. yes

  Large File ............. yes

  QML debugging .......... yes

  Use system proxies ..... no

 

Support enabledfor:

  Accessibility .......... yes

  ALSA ................... yes

  CUPS ................... no

  Evdev .................. yes

  FontConfig ............. yes

  FreeType ............... yes (system library)

  Glib ................... yes

  GStreamer .............. yes (1.0)

  GTK theme .............. no

  HarfBuzz ............... yes (bundled copy)

  Iconv .................. no

  ICU .................... yes

  Image formats:

    GIF .................. yes (plugin, usingbundled copy)

    JPEG ................. yes (plugin, usingsystem library)

    PNG .................. yes (in QtGui, usingbundled copy)

  libinput................ no

  Logging backends:

    journald ............... no

    syslog  ............... no

  mtdev .................. no

  Networking:

    getaddrinfo .......... yes

    getifaddrs ........... yes

    IPv6 ifname .......... yes

    libproxy.............. no

    OpenSSL .............. yes (loadinglibraries at run-time)

  NIS .................... yes

  OpenGL / OpenVG:

    EGL .................. yes

    OpenGL ............... yes (OpenGL ES 2.0+)

    OpenVG ............... yes-auto

  PCRE ................... yes (bundled copy)

  pkg-config ............. yes

  PulseAudio ............. yes

  QPA backends:

    DirectFB ............. no

    EGLFS ................ yes

      EGLFS i.MX6 ........ yes

      EGLFS i.MX6 Wayland. no

      EGLFS EGLDevice .... no

      EGLFS GBM .......... yes

      EGLFS Mali ......... no

      EGLFS Raspberry Pi . no

      EGLFS X11 .......... no

    LinuxFB .............. yes

    Mir client............ no

    XCB .................. no

  Session management ..... yes

  SQL drivers:

    DB2 .................. no

    InterBase ............ no

    MySQL ................ no

    OCI .................. no

    ODBC ................. no

    PostgreSQL ........... no

    SQLite 2 ............. no

    SQLite ............... yes (plugin, usingbundled copy)

    TDS .................. no

  tslib .................. no

  udev ................... yes

  xkbcommon-x11........... no

  xkbcommon-evdev......... no

  zlib ................... yes (bundled copy)

 

 

NOTE: Qt is usingdouble for qreal on this system. This is binary incompatible against Qt 5.1.

Configure with'-qreal float' to create a build that is binary compatible with 5.1.

 

Qt is nowconfigured for building. Just run 'make'.

Once everythingis built, you must run 'make install'.

Qt will beinstalled into /QtInstall

 

Prior toreconfiguration, make sure you remove any leftovers from

the previous build.

需要確保opengl的選項是yes,否則無法運行QtQuick程序。

6、 編譯Qt。直接運行make,這個過程會出現一些錯誤,需要根據提示更改源碼,或安裝必要的軟件,編譯時間,不同的機器性能會有所差別,我的電腦編譯一次大約需要一下午。

7、 安裝Qt到配置目錄。直接運行make install,執行完成後,會在配置路徑下生成移植的Qt,內容如下:

8、 移植Qt。將生成的Qt目錄直接拷貝到文件系統目錄下,同時把sysroot下的icu相關的庫文件拷貝到文件系統的lib目錄下,因爲Qt程序依賴icu庫。拷貝完成後並不能直接運行Qt程序,還需要配置環境變量。我的配置腳本如下:

#!/bin/sh

export QTDIR=/QtInstall

exportQT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins

exportQT_QPA_PLATFORM=eglfs:fb=/dev/fb0

exportQT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/event1

exportQT_QPAFONTDIR=$QTDIR/lib/fonts

exportQML2_IMPORT_PATH=$QTDIR/qml

export LD_LIBRARY_PATH=$QTDIR/lib:/usr/lib:/lib:$LD_LIBRARY_PATH

export PATH=$QTDIR/bin:/bin:/usr/bin:/usr/bin/qt5:$PATH

執行完該腳本,就可以運行程序了。比如:

./QtDemo –platform eglfs

也可以:

qmlscene QtDemo.qml –platform eglfs

qmlscene用於執行一個qml文件。

至此,手動移植Qt完成,這種方法的優勢是,不在受限於內核版本,缺點是,每更換一次內核版本,就要重新編譯一次Qt。

 

附錄:燒寫u-boot、kernel、rootfs腳本

#!/bin/sh

 

echo image burn begin!

 

ORGSDCARD=`fdisk -l | awk'{if(($2=="/dev/sdb:")||($2=="/dev/sdc:")||($2=="/dev/sdd:")||($2=="/dev/sde:"))print $2;}'`

 

SDCARD=${ORGSDCARD%?}

FIR=1

SEC=2

SDCARDFIR=$SDCARD$FIR

SDCARDSEC=$SDCARD$SEC

 

echo--------------------------------------

echo ORGSDCARD = $ORGSDCARD

echo SDCARD    = $SDCARD

echo SDCARDFIR = $SDCARDFIR

echo SDCARDSEC = $SDCARDSEC

echo--------------------------------------

echo '\n\n'

 

 

umount $SDCARDFIR

umount $SDCARDSEC

sync

dd if=/dev/zero of=$SDCARDbs=10M count=1

sync

 

fdisk $SDCARD << EOF

p

n

p

1

 

+20M

p

n

p

2

 

 

p

w

EOF

 

#上面的腳本對SD卡進行了分區

 

#燒寫uboot

ddif=/home/yocto/nfs/board/u-boot.imx of=$SDCARD bs=512 seek=2

#對分區1進行FAT格式化

mkfs.vfat $SDCARDFIR

#掛載分區1

mount $SDCARDFIR ./mount_point1

#複製設備樹文件到分區1

cp/home/yocto/nfs/board/imx6sx-sdb.dtb ./mount_point1

#複製內核代碼到分區1

cp /home/yocto/nfs/board/zImage./mount_point1

#複製M4內核代碼到分區1

#cp./imx6sx-image/hello_world.bin ./mount_point1

sync

#取消掛載

echo umount $SDCARDFIR !

umount ./mount_point1

sync

#對分區2進行EXT4格式化

mkfs.ext4 $SDCARDSEC

#掛載分區2

mount $SDCARDSEC ./mount_point2

#複製根文件系統到分區2

cp -a/home/yocto/nfs/board/rootfs/* ./mount_point2

sync

#取消掛載

echo umount $SDCARDSEC!

umount ./mount_point2

sync

echo image burn ok!


發佈了23 篇原創文章 · 獲贊 16 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章