1.安装编译器与工具
sudo apt-get install g++-4.8-multilib-arm-linux-gnueabihf binutils-arm-linux-gnueabihf
2.查看是否安装完成
root@vm-zinc:/home/zeno# arm-linux-gnueabihf-g++-4.8 -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-g++-4.8
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v –with-pkgversion=’Ubuntu/Linaro 4.8.2-16ubuntu4′ –with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs –enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ –prefix=/usr –program-suffix=-4.8 –enable-shared –enable-linker-build-id –libexecdir=/usr/lib –without-included-gettext –enable-threads=posix –with-gxx-include-dir=/usr/arm-linux-gnueabihf/include/c++/4.8.2 –libdir=/usr/lib –enable-nls –with-sysroot=/ –enable-clocale=gnu –enable-libstdcxx-debug –enable-libstdcxx-time=yes –enable-gnu-unique-object –disable-libmudflap –disable-libitm –disable-libquadmath –enable-plugin –with-system-zlib –disable-browser-plugin –enable-java-awt=gtk –enable-gtk-cairo –with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf-cross/jre –enable-java-home –with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf-cross –with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf-cross –with-arch-directory=arm –with-ecj-jar=/usr/share/java/eclipse-ecj.jar –disable-libgcj –enable-objc-gc –enable-multiarch –enable-multilib –disable-sjlj-exceptions –with-arch=armv7-a –with-fpu=vfpv3-d16 –with-float=hard –with-mode=thumb –disable-werror –enable-checking=release –build=x86_64-linux-gnu –host=x86_64-linux-gnu –target=arm-linux-gnueabihf –program-prefix=arm-linux-gnueabihf- –includedir=/usr/arm-linux-gnueabihf/include
Thread model: posix
gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-16ubuntu4)
3.利用交叉编译器编译QT
如果是交叉编译,需要配置 xplatform选项,比如要在arm-linux平台上移植Qt的话,就在配置项中加上 -xplatform linux-arm-gnueabi-g++ ,Qt5支持的交叉平台都可在源码顶层目录中的 /qtbase/mkspecs/ 下找到,每个子目录名代表一个交叉平台的名字,移植Qt时应根据自己的实际情况修改平台对应的子目录下的qmake.conf文件,它定义了一些与平台相关的环境变量,如交叉编译器等;
最好不要在编译Qt时使能 c++11,一方面你的编译器可能不支持,另一方面使能这一项后可能出现一部分编译错误;
如果需要openGL,就需要用 -opengl选项指定opengl的api,对于嵌入式平台,一般使用 opengl ES2,配置选项中加入” -opengl es2 ” 。不过想使用openGL可能会比较麻烦,因为openGL一般在有硬件图形加速的条件下才能高效运行,而这需要显卡或Soc厂家提供openGL的支持库,但并不是所有Soc都能找到对应的支持库,比如三星就没有提供S5PV210的openGL库,所以我这里编译的Qt也是没有opengl的。(openGL的替代方案:如果没有厂家提供的硬件图形库,可以考虑使用纯软件实现的opengl,这样的软件库有很多是开源的,如mesa3D库等,不过纯软件实现的opengl在效率方面肯定要比带硬件加速的低很多,而且要想在嵌入式平台上使用,必须将opengl的软件库也交叉编译出来,我在交叉编译mesa3D时遇到了些问题,所以目前还没能在开发板上用上openGL);
如果想让Qt程序支持多点触摸,在配置时可能需要加上 -mtdev 和 -xinput2 选项,在help中可以找到这两个选项。mtdev包含了应用程序对多点触摸协议的支持,xinput2实现了Linux的输入子系统对多点触摸的支持。在我这里加上这两个选项的话配置会出错,可能还缺乏一些库,所以最后我没有使用这两个选项;
另外,Qt5默认的qreal类型是64bit的double,如果希望用float类型定义qreal,则在配置选项中加入”-qreal float”。
我们是在arm板上移植,需要知道芯片的架构。我的是Cortex-A7,其架构是armv7-a。安装Host上的QT的时候选择安装源代码,然后进入到源码目录,进入~/Qt5.4.1/5.4/qtbase/Src/qtbase/mkspecs/linux-arm-gnueabi-g++目录下,需要修改qmake.conf文件。如下
# # qmake configuration for building with arm-linux-gnueabi-g++ # MAKEFILE_GENERATOR = UNIX CONFIG += incremental QMAKE_INCREMENTAL_STYLE = sublib //添加的内容 QT_QPA_DEFAULT_PLATFORM = linux #eglfs QMAKE_CFLAGS_RELEASE += -O2 -march=armv7-a QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv7-a include(../common/linux.conf) include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) # modifications to g++.conf QMAKE_CC = arm-linux-gnueabihf-g++-4.8 QMAKE_CXX = arm-linux-gnueabihf-g++-4.8 QMAKE_LINK = arm-linux-gnueabihf-g++-4.8 QMAKE_LINK_SHLIB = arm-linux-gnueabihf-g++-4.8 # 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 load(qt_config)
仅使用framebuffer,如果支持opengl es,可以使用eglfs。qt5将显示都做成了插件形式,这提供了更多的灵活性,详细的内容可以去看qt5的文档。
在Src目录下建立编译脚本build.sh
我编译使用的脚本
#!/bin/sh echo 'build Qt5 for embedded linux Author Zhong Chen' mkdir ~/Qt5.4.1/5.4/armlinux_armv7 $PWD/configure -v \ -prefix /home/zeno/Qt5.4.1/5.4/armlinux_armv7/ \ -confirm-license \ -opensource \ -release \ -make libs \ -xplatform linux-arm-gnueabi-g++ \ -pch \ -qt-sql-sqlite \ -qt-zlib \ -qt-libjpeg \ -qt-libpng \ -qt-freetype -no-opengl \ -no-sse2 \ -no-openssl \ -no-nis \ -no-cups \ -no-glib \ -no-xcursor -no-xfixes -no-xrandr -no-xrender \ -no-separate-debug-info \ -no-phonon \ -no-xkb -no-sm -no-xinerama -no-xshape \ -no-qvfb -no-gfx-qvfb -no-kbd-qvfb -no-mouse-qvfb -qt-kbd-usb \ -nomake examples -nomake tools make -j2 && make install -j2
你可以详细的根据自己的需要配置,在文件夹下运行这个脚本就行。
4.添加 tslib 支持
为了使单点触摸屏可用,还需要编译Qt的tslib插件,查阅相关资料:
一般的开发板都会提供,仅需要在板子上设置TSLIB的环境变量,主要的几个变量如下:
#! /bin/sh # "source" this file when wanna run a Qt application on the ARM Board. ############### the below lines are for stardard TSLIB ################## export TSLIB_ROOT=/opt/tslib export TSLIB_CALIBFILE=$TSLIB_ROOT/etc/pointercal export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts export TSLIB_TSDEVICE=/dev/touchscreen-1wire #export TSLIB_TSDEVICE=/dev/input/event2 ################ the below lines are optional ############## #export TSLIB_FBDEVICE=/dev/fb0 #export TSLIB_CONSOLEDEVICE=none
此外还要修改 ts.conf文件:
#module_raw one_wire_ts_input module_raw friendlyarm-ts-mtinput #使用友善提供的电容屏TSLIB插件。需要先将friendlyarm-ts-mtinput.so拷贝到TSLIB_PLUGINDIR目录中 module pthres pmin=1 module variance delta=30 module dejitter delta=100 module linear
到此为止 tslib 就基本能用了,首次使用时应先运行 ts_calibrate 进行触摸屏校准。我用的这个版本的tslib自带的ts_calibrate程序不太好用,所以我依然使用友善提供的ts_calibrate进行校准。
有了tslib后,进入Qt源码目录中的 “qtbase/src/plugins/generic/tslib/”,运行 qmake 生成 Makefile,并在Makefile中将tslib的头文件和库文件路径添加到编译链接选项中(-I /…tslib/include -L/…/tslib/lib);然后运行 make 和 make install即可。这时,Qt5安装目录的 “plugins/generic/”目录下就出现”libqtslibplugin.so”这个库文件了。
5.运行Qt程序
需要说明的是,Qt5.0开始,Qt自身不再单独实现窗口系统,QWS不复存在,取而代之的新机制是QPA(Qt平台抽象),QPA使得Qt对不同平台的支持变得更加灵活,当需要支持一个新平台时,只需为该平台编写一个QPA插件。
With the release of Qt 5.0, Qt no longer contains its own window system implementation: QWS is no longer a supported platform. For single-process use cases, theQt Platform Abstraction is a superior solution……参考 http://qt-project.org/doc/qt-5/embedded-linux.html
编译完Qt后,只需将生成的lib和plugins文件夹拷贝到开发板,另外,当在嵌入式Linux平台上运行应用程序前,应根据自己平台的实际情况提前设置好下面几个环境变量:
export QT_QPA_PLATFORM_PLUGIN_PATH=/opt/Qt-5.3.2/armv7-a/plugins/platforms export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0 export QT_QPA_FONTDIR=/opt/Qt-5.3.2/armv7-a/lib/fonts export QT_QPA_GENERIC_PLUGINS=tslib:/dev/touchscreen-1wire #使用tslib插件
然后就可以运行Qt程序了
以前Qt4的程序在嵌入式Linux平台运行时,需要在命令行输入-qws选项以启动Qt窗口系统服务,如” ./HelloWorld -qws”;而使用Qt5后,不再需要-qws,而需要通过-platform来指定要使用的QPA插件,如” ./HelloWorld -platform linuxfb”,如果不指定,则用默认的QPA插件,默认的QPA插件通过上面的QT_QPA_PLATFORM变量指定。