这个手记写到这里,am335x的软件平台已经能够正常工作了, tslib也已经能够进行正确的触摸屏校正,自己编写一个hello world的程序,并交叉编译后,能够在am335x上运行,并在超级终端上打印出“hello world”。本文引用地址:http://www.eepw.com.cn/article/201603/287664.htm
那么,我们正式开始搭建qt的开发平台,我的ubuntu上安装的是qt5.4.1,并已经写了一个hello world的qt程序,这个程序非常简单,就是运行后在桌面上显示一个窗口,窗口中显示一行文字“hello world”,以及一个按键。鼠标点击按键退出程序。
ubuntu的qt安装在/home/XXXX/qt5.4.1目录下,QtCreator也安装在相同目录下,上述的qtdemo程序用QtCreator创建并编译通过。
为保证和ubuntu平台的一致性,决定am335x的平台移植qt5.4.1,首先到qt的官网下载源代码:http://download.qt.io/official_releases/qt/5.4/5.4.1/single/qt-everywhere-opensource-src-5.4.1.tar.gz。下载可以使用git,也可以用浏览器直接打开这个连接。将下载到的压缩文件解压缩到./source目录下,进入到./source目录下执行configure工具生成编译选项,这里要进行三步工作:
A、设置交叉编译的环境变量。这里需要注意一点,我们在交叉编译qt5.4.1的工具包时,涉及到2种不同的编译:第一种是使用ubuntu安装的GCC和G++编译qmake工具,这些qmake工具将运行在ubuntu下,用于将后续自己编写的qt应用程序的源代码编译成能够运行在arm平台上的目标可执行程序;第二种是使用arm-linux-gnueabihf编译器,将qt5.4.1的库编译成运行于arm平台的静态库或者共享库。
export QT_INSTALL_DIR=/home/XXXX/Qt541arm #设定编译好的qt包的安装路径
export ARCH=arm #设定目标cpu架构
export LIBRARY_PATH=$LIBRARY_PATH:/usr/lib/i386-linux-gnu #为后续的编译设定库路径
B、编辑./qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf。mkspecs目录下有很多的保存.conf文件的目录,分别对应不同的操作系统和交叉编译平台,我这里使用linux-arm-gnueabi-g++平台的配置文件进行交叉编译。
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental gdb_dwarf_index
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
QT_QPA_DEFAULT_PLATFORM=linuxfb
COMPILER_FLAGS += -o3 -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard
QMAKE_CFLAGS_RELEASE += -O3 -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard
QMAKE_CXXFLAGS_RELEASE += -O3 -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard
QT_INSTALL_DIR = /home/XXXX/Qt541arm
QMAKE_INCDIR += /usr/tslib/include
QMAKE_LIBDIR += /usr/tslib/lib
LIBS += -ldl -fPIC -lts
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++
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)
一定要正确设置QMAKE_INCDIR和QMAKE_LIBDIR,指向正确的编译后tslib安装目录下的include和lib目录。否则交叉编译qt5.4.1时会出现找不到头文件的错误。
LIBS的几个设置比较重要,-lts是在后续的交叉编译应用时增加tslib库。-fPIC用于在编译时生产位置无关代码,-ldl设置用显示方法调用相关的函数调用。
这里额外提一句,交叉编译器中有一个工具arm-linux-gnueabihf-readelf,非常实用,利用这个工具能够查看应用程序的可执行文件的各种信息,例如使用arm-linux-gnueabihf-readelf -d qtdemo,可以查看qtdemo中包含并使用哪一些共享库。
C、执行./configure进行配置:
我编辑了一个sh文件,用于进行配置,这样方便后续使用:
#!/bin/sh
./configure -v \
-release \
-opensource \
-confirm-license \
-make libs \
-optimized-qmake \
-platform linux-g++ \
-xplatform linux-arm-gnueabi-g++ \
-prefix /home/XXXX/Qt541arm \
-pch \
-qt-libjpeg \
-qt-libpng \
-qt-zlib \
-qt-sql-sqlite \
-tslib \
-qreal float \
-linuxfb \
-no-evdev \
-no-egl \
-no-eglfs \
-no-opengl \
-no-directfb \
-no-sql-db2 \
-no-sql-ibase \
-no-sql-mysql \
-no-sql-oci \
-no-sql-odbc \
-no-sql-psql \
-no-sql-sqlite2 \
-no-sql-tds \
-no-xcb \
-no-xcb-xlib \
-no-icu \
-no-c++11 \
-no-cups \
-no-iconv \
-no-android-style-assets \
-nomake examples \
-nomake tests \
这里重点地方是:
1、用-platform指定交叉编译的平台,这个是错误的,这个选项是指定编译qmake工具的平台,由于我的qmake是需要运行在ubuntu上,所以这个选项指定的qmake.conf中必须将编译工具指向ubuntu的GCC和G++;
而-xplatform才是指定共享库等,以及最终的qt应用程序的运行平台的。-xplatform告诉configure使用哪一个交叉编译工具编译qt5.4.1开发包的lib。这个选项指定的qmake.conf中必须将编译工具指向arm的交叉编译工具,并设定相关的编译选项。
2、第一次编译好arm的qt5.4.1开发包,并将这个qt5.4.1开发包中的lib和plugins目录下的内容全部拷贝到arm目标平台的nfs文件系统中的/opt/qt541arm目录中。用这个包的qmake编译我的qtdemo程序,然后将可执行文件拷贝到arm板的nfs文件系统中。正确设定运行环境后,运行qtdemo出错,提示could not
find or load a platform。不能打开显示平台,这个错误我大约花了2天时间,后来发现关键在上面的configure时,如果使用了-linuxfb,则必须-no-egl,-no-eglfs,-no-directfb,-no-opengl将其他的显示平台关闭,要不然后续编译qtdemo并运行时,就会出现不能找到或者装载显示平台,有效地显示平台是:......的错误。
当然,运行qt应用程序之前,需要保证你的qt的运行环境变量设置是正确的。使用上述的configure成功配置好编译环境后,最后应该显示出qt5.4.1开发包的包含项,以及编译后的安装位置等:
Building on: linux-g++ (i386, CPU features: none detected)
Building for: linux-arm-gnueabi-g++ (arm, CPU features: none detected)
qmake vars .......... styles += mac fusion
windows DEFINES += QT_NO_MTDEV DEFINES += QT_NO_EVDEV sql-drivers = sqlite sql-plugins = qmake switches .........
Build options:
Configuration .......... accessibility alsa audio-backend clock-gettime
clock-monotonic compile_examples concurrent cross_compile dbus eventfd freetype
full-config getaddrinfo getifaddrs harfbuzz inotify ipv6ifname large-config
largefile libudev linuxfb medium-config minimal-config mremap nis no-pkg-config openssl pcre png
posix_fallocate precompile_header qpa qpa reduce_exports release rpath shared
small-config tslib zlib
Build parts ............ libs
Mode ................... release
Using C++11 ............ no
Using gold linker....... no
Using PCH .............. yes
Target compiler supports:
Neon ................. no
Qt modules and options:
Qt D-Bus ............... yes (loading dbus-1 at runtime)
Qt Concurrent .......... yes
Qt GUI ................. yes
Qt Widgets ............. yes
Large File ............. yes
QML debugging .......... yes
Use system proxies ..... no
Support enabled for:
Accessibility .......... yes
ALSA ................... yes
CUPS ................... no
Evdev .................. no
FontConfig ............. no
FreeType ............... yes (bundled copy)
Glib ................... no
GTK theme .............. no
HarfBuzz ............... yes (bundled copy)
Iconv .................. no
ICU .................... no
Image formats:
GIF .................. yes (plugin, using bundled copy)
JPEG ................. yes (plugin, using bundled copy)
PNG .................. yes (in QtGui, using bundled copy)
journald ............... no
mtdev .................. no
Networking:
getaddrinfo .......... yes
getifaddrs ........... yes
IPv6 ifname .......... yes
OpenSSL .............. yes (loading libraries at run-time)
NIS .................... yes
OpenGL / OpenVG:
EGL .................. no
OpenGL ............... no
OpenVG ............... no
PCRE ................... yes (bundled copy)
pkg-config ............. no
PulseAudio ............. no
QPA backends:
DirectFB ............. no
EGLFS ................ no
KMS .................. no
LinuxFB .............. yes
XCB .................. no
Session management ..... yes
SQL drivers:
DB2 .................. no
InterBase ............ no
MySQL ................ no
OCI .................. no
ODBC ................. no
PostgreSQL ........... no
SQLite 2 ............. no
SQLite ............... qt-qt
TDS .................. no
udev ................... yes
xkbcommon .............. no
zlib ................... yes (bundled copy)
Info: creating super cache file /home/XXX/temp/source/.qmake.super
Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into /home/XXXX/Qt541arm
Prior to reconfiguration, make sure you remove any leftovers from the previous build.
上述准确无误后,执行make -j4编译qt5.4.1开发包,这里的-j4是通知编译器使用4线程编译,这个数字根据当前运行平台的CPU核心数来设置。使用多线程编译能够极大提高编译速度。我的i3-2350计算机,编译一次qt5.4.1开发包的时间大约是40分钟左右(不过这个也和需要编译的qt5.4.1的包含项的多少有关)。
编译成功后,执行make install将qt5.4.1开发包安装到configure时-prefix指定的目录中。然后将安装目录中的lib和plugins目录拷贝到arm的nfs文件系统中的/opt/qt541arm目录下(当然,这个目录的设置看个人的兴趣爱好:) )。