1 开发环境
目标板:FS4412
交叉编译工具链:arm-arm1176jzfssf-linux-gnueabi 4.6.4
Qt:qt-everywhere-opensource-src-5.4.2.tar.xz
Linux:Ubuntu 12.04 32位
2 Qt源码配置、编译及安装
在Linux系统下,桌面或图形界面程序本质上只是一个应用程序而已。Qt作为一个能够在Linux系统下运行的图形库,对它的移植和一般的应用程序的移植并无太多不同,所经过的步骤通常是下载源码,解压源码,配置源码,编译源码和安装等步骤。下面对这些步骤一一进行详细的说明。
Qt的新源码可以在官网上下载,这里以5.4.2的版本为例,其下载地址为//download.qt.io/official_releases/qt/5.4/5.4.2/single/qt-everywhere-opensource-src-5.4.2.tar.xz。压缩包有多种格式可选,推荐下载xz格式的压缩包,其压缩比较高。可以在网页上直接点击下载,也可以通过下面的命令下载。
$ wget -c //download.qt.io/official_releases/qt/5.4/5.4.2/single/qt-everywhere-opensource-src-5.4.2.tar.xz
源码下载完成后,使用下面的命令对源码包进行解压。
$ tar -xvf qt-everywhere-opensource-src-5.4.2.tar.xz
解压完成后,使用下面的命令进入到源码目录并查看源码配置的帮助信息。
$ cd qt-everywhere-opensource-src-5.4.2/
$ ./configure -help
Qt的配置项有很多,在帮助信息前加“*”的项为默认选项,加“+”的项为评估选项,如果评估成功,那么该功能将被包含。下面将这些配置项的含义一一列出。
-prefix <dir>:安装路径,默认的路径为/usr/local/Qt-5.4.2。
-extprefix <dir>:如果使用了-sysroot选项,那么安装路径为指定的<dir>。
-hostprefix [dir]:指定可扩展的工具库安装路径,默认当前目录。
-bindir <dir>:用户的可执行程序安装路径。
-headerdir <dir>:头文件安装路径。
-libdir <dir>:库文件安装路径。
-archdatadir <dir>:平台依赖的数据安装路径。
-plugindir <dir>:插件安装路径。
-libexecdir <dir>:可执行程序安装路径。
-importdir <dir>:QML1安装路径。
-qmldir <dir>:QML2安装路径。
-datadir <dir>:平台无关数据安装路径。
-docdir <dir>:文档安装路径。
-translationdir <dir>:翻译文件安装路径。
-sysconfdir <dir>:配置文件的搜索路径。
-examplesdir <dir>:示例程序安装路径。
-testsdir <dir>:测试程序安装路径。
-hostbindir <dir>:主机可执行程序安装路径。
-hostlibdir <dir>:主机库安装路径。
-hostdatadir <dir>:qmake使用的数据安装路径。
-release:编译和链接时关闭调试选项,默认选项。
-debug:编译和链接时打开调试选项。
-debug-and-release:生成调试和不调试的两个版本。
-force-debug-info:在非调试的版本中强制创建符号文件。
-developer-build:编译和链接时加入开发者的一些选项。
-opensource:构建Qt的开源版本。
-commercial:构建Qt的商业版本。
-confirm-license:自动确认许可证。
-no-c++11:不要开启c++11的支持。
-c++11:开启c++11的支持,评估选项。
-shared:使用共享的Qt库,默认选项。
-static:使用静态的Qt库。
-no-largefile:不支持大文件的访问。
-largefile:支持大于4G的文件访问,评估选项。
-no-accessibility:不要开启Accessibility支持,不推荐设置该选项。
-accessibility:开启Accessibility支持,评估选项。
-no-sql-<driver>:禁止SQL <driver>。
-qt-sql-<driver>:使能在Qt SQL 模块中的SQL <driver>。
-plugin-sql-<driver>:将SQL <driver>作为一个运行时的插件。
-system-sqlite:使用系统体统的sqlite。
-no-qml-debug:不要编译in-process QML调试支持。
-qml-debug:编译in-process QML调试支持,评估选项。
-platform target:构建的目标操作系统及编译器。
-no-sse2:不要用SSE2指令集编译。
-no-sse3:不要用SSE3指令集编译。
-no-ssse3:不要用SSSE3指令集编译。
-no-sse4.1:不要用SSE4.1指令集编译。
-no-sse4.2:不要用SSE4.2指令集编译。
-no-avx:不要用AVX指令集编译。
-no-avx2:不要用AVX2指令集编译。
-no-mips_dsp:不要用MIPS DSP指令集编译。
-no-mips_dspr2:不要用MIPS DSP rev2指令集编译。
-qtnamespace <name>:将所有的Qt库包裹在<name>命名空间。
-qtlibinfix <infix>:将所有的libQt*.so命名为libQt*<infix>.so。
-testcocoon:用TestCocoon代码覆盖测试工具检测Qt代码。
-gcov:用GCov代码覆盖测试工具检测Qt代码。
-D <string>:添加预处理定义。
-I <string>:添加包含路径。
-L <string>:添加库路径。
-pkg-config:使用pkg-config来检测包含路径和库路径,评估选项。
-no-pkg-config:不使用pkg-config。
-force-pkg-config:强制使用pkg-config。
-help, -h:显示帮助信息。
-qt-zlib:使用zlib库。
-system-zlib:使用系统的zlib库,评估选项。
-no-mtdev:不支持mtdev。
-mtdev:支持mtdev,评估选项。
-no-journald:不发送日志给journald,评估选项。
-journald:发送日志给journald。
-no-gif:不支持GIF。
-no-libpng:不支持PNG。
-qt-libpng:使用Qt的libpng库。
-system-libpng:使用系统的libpng库,评估选项。
-no-libjpeg:不支持JPEG。
-qt-libjpeg:使用Qt的libjpeg库。
-system-libjpeg:使用系统的libjpeg库,评估选项。
-no-freetype:不支持Freetype2。
-qt-freetype:使用Qt的libfreetype库。
-system-freetype:使用系统的libfreetype库,评估选项。
-no-harfbuzz:不支持HarfBuzz-NG。
-qt-harfbuzz:使用Qt的HarfBuzz-NG,默认选项。
-system-harfbuzz:使用系统的HarfBuzz-NG。
-no-openssl:不支持OpenSSL。
-openssl:使能OpenSSL的运行时支持,评估选项。
-openssl-linked:使能OpenSSL的支持。
-qt-pcre:使用Qt的PCRE库。
-system-pcre:使用系统的PCRE库,评估选项。
-qt-xcb:使用Qt的xcb-库。
-system-xcb:使用系统的xcb-库,评估选项。
-xkb-config-root:设置默认的XKB配置根目录。
-qt-xkbcommon:使用Qt的xkbcommon库。
-system-xkbcommon:使用系统的xkbcommon库,评估选项。
-no-xinput2:不支持XInput2。
-xinput2:支持XInput2,默认选项。
-no-xcb-xlib不支持Xcb-Xlib。
-xcb-xlib:支持Xcb-Xlib,默认选项。
-no-glib:不支持Glib:
-glib:支持Glib,评估选项。
-no-pulseaudio:不支持PulseAudio。
-pulseaudio:支持PulseAudio,评估选项。
-no-alsa:不支持ALSA。
-alsa:支持ALSA support,评估选项。
-no-gtkstyle:不支持GTK主题。
-gtkstyle:支持 GTK主题,评估选项。
-make <part>:指定添加需要编译的<part>。
-nomake <part>:指定不需要编译的<part>。
-skip <module>:指定不需要编译的整个<module>。
-no-compile-examples:仅仅安装示例的源码。
-no-gui:不编译Qt的GUI和相关的依赖。
-gui:编译Qt的GUI和相关的依赖,评估选项。
-no-widgets:不编译Qt的窗口部件和依赖。
-widgets:编译Qt的窗口部件和依赖,评估选项。
-R <string>:显式添加库路径。
-l <string>:显式添加库。
-no-rpath:不使用库的安装路径作为运行时库路径。
-rpath:使用库的安装路径作为运行时库路径,评估选项。
-continue:如果错误发生后,编译过程尽可能持续下去。
-verbose, -v:打印出详细的配置过程。
-silent:减少编译输出,以便能更好发现编译的警告和错误。
-no-optimized-qmake:不要优化qmake,默认选项。
-optimized-qmake:优化qmake。
-no-nis:不支持 NIS 。
-nis:支持NIS,默认选项。
-no-cups:不支持CUPS。
-cups:支持,默认选项。
-no-iconv:不支持iconv(3).
-iconv:支持iconv(3) ,默认选项。
-no-evdev:不支持evdev。
-evdev:支持evdev,默认选项。
-no-icu:不支持ICU库
-icu:支持ICU库,默认选项。
-no-fontconfig:不支持FontConfig。
-fontconfig:支持FontConfig,默认选项。
-no-strip:不裁剪二进制程序和库。
-strip:裁剪二进制程序和库,默认选项。
-no-pch:不使用预编译头,默认选项。
-pch:使用预编译头。
-no-dbus:不编译Qt D-Bus模块。
-dbus:编译Qt D-Bus模块,评估选项。
-dbus-linked:编译Qt D-Bus模块并链接到libdbus-1.
-reduce-relocations:通过额外的链接器优化选项减少库中的重定位。
-no-use-gold-linker:不使用GNU gold链接器。
-use-gold-linker:使用GNU gold链接器,评估选项。
-force-asserts:强制使能Q_ASSERT,即便是release版本。
-device <name>:交叉编译设备的名字。
-device-option <key=value>:添加设备特定的选项。
-no-separate-debug-info:不要把调试信息存在单独的文件中,默认选项。
-separate-debug-info:把调试信息存在单独的文件中。
-no-xcb:不支持 Xcb。
-xcb:支持 Xcb,默认选项。
-no-eglfs:不支持EGLFS。
-eglfs:支持EGLFS,默认选项。
-no-directfb:不支持DirectFB。
-directfb:支持DirectFB,默认选项。
-no-linuxfb:不支持Linux帧缓存。
-linuxfb:支持Linux帧缓存,默认选项。
-no-kms:不支持KMS。
-kms:支持KMS,默认选项。
-qpa <name>:设置默认的QPA平台。
-xplatform target:交叉编译时指定目标平台。
-sysroot <dir>:将<dir>作为目标的编译器和qmake的sysroot,并且设置pkg-config paths路径。
-no-gcc-sysroot:当使用-sysroot选项, 禁止将—sysroot传给编译器。
-no-feature-<feature>:不要编译<feature>。
-feature-<feature>:编译<feature>。 可用的特性在src/corelib/global/qfeatures.txt中查找。
-qconfig local:使用src/corelib/global/qconfig-local.h头文件。
-qreal [double|float]: 指定qreal的类型,默认是double。
-no-opengl:不支持OpenGL。
-opengl <api>:支持OpenGL。
-no-system-proxies:不使用系统的网络代理,默认选项。
-system-proxies:使用系统的网络代理。
-no-warnings-are-errors:正常处理警告。
-warnings-are-errors:将警告视为错误。
除了以上的选项而外,还有一些针对特定系统的专有选项,这些选择在Linux系统上无效,所以不再一一列举。
使用以下的命令拷贝一份qmake的配置文件,然后编辑新拷贝的配置文件。
$ cp -a qtbase/mkspecs/linux-arm-gnueabi-g++/ qtbase/mkspecs/linux-arm-g++/
$ vim qtbase/mkspecs/linux-arm-g++/qmake.conf
将配置文件中所有的arm-linux-gnueabi都替换为arm-linux。
#
# qmake configuration for building with arm-linux-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC = arm-linux-gcc
QMAKE_CXX = arm-linux-g++
QMAKE_LINK = arm-linux-g++
QMAKE_LINK_SHLIB = arm-linux-g++
# modifications to linux.conf
QMAKE_AR = arm-linux-ar cqs
QMAKE_OBJCOPY = arm-linux-objcopy
QMAKE_NM = arm-linux-nm -P
QMAKE_STRIP = arm-linux-strip
load(qt_config)
编辑一个自动配置的脚本文件(如config.sh)存放在源码顶层目录下,并添加可执行权限。脚本文件的内容如下:
#!/bin/bash
./configure -release \
-opensource \
-confirm-license \
-qt-sql-sqlite \
-no-sse2 \
-no-sse3 \
-no-ssse3 \
-no-sse4.1 \
-no-sse4.2 \
-no-avx \
-no-avx2 \
-no-mips_dsp \
-no-mips_dspr2 \
-no-pkg-config \
-qt-zlib \
-qt-libpng \
-qt-libjpeg \
-qt-freetype \
-no-openssl \
-qt-pcre \
-qt-xkbcommon \
-no-glib \
-nomake examples \
-nomake tools \
-nomake tests \
-no-cups \
-no-iconv \
-no-dbus \
-xplatform linux-arm-g++ \
-no-use-gold-linker \
-qreal float
exit
从脚本文件的内容可知,脚本主要是运行了配置命令并设置了一些配置选项,这些选项的意义可以参考前面的说明。一般来说,初次进行移植时,有些选项可能设置不正确导致配置不通过,或配置通过并编译完成后运行时出现问题。那么这就需要根据错误提示对配置进行适当的修改。编写配置脚本的其中一个目的也是为了便于修改。配置文件编写好,并添加可执行权限后,使用下面的命令对Qt源码进行配置。
$ ./config.sh
配置成功后会打印配置的汇总信息,如下所示:
Configure summary
Building on: linux-g++ (i386, CPU features: none detected)
Building for: linux-arm-g++ (arm, CPU features: none detected)
Platform notes:
- Also available for Linux: linux-kcc linux-icc linux-cxx
Build options:
Configuration .......... accessibility audio-backend c++11 clock-gettime clock-monotonic compile_examples concurrent
cross_compile evdev eventfd freetype full-config getaddrinfo getifaddrs harfbuzz inotify ipv6ifname large-config largefile linuxfb
medium-config minimal-config mremap nis no-pkg-config pcre png posix_fallocate precompile_header qpa qpa reduce_exports release
rpath shared small-config zlib
Build parts ............ libs
Mode ................... release
Using C++11 ............ yes
Using gold linker....... no
Using PCH .............. yes
Target compiler supports:
Neon ................. no
Qt modules and options:
Qt D-Bus ............... no
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 ................... no
CUPS ................... no
Evdev .................. yes
FontConfig ............. no
FreeType ............... qt
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 .............. no
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 ................... no
xkbcommon .............. no
zlib ................... yes (bundled copy)
Info: creating super cache file /home/kevin/Workspace/fs4412/others/Qt/qt-everywhere-opensource-src-5.4.2/.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 /usr/local/Qt-5.4.2
Prior to reconfiguration, make sure you remove any leftovers from
the previous build.
通过查看该汇总信息,Qt的功能模块的选择情况将会一目了然。配置完成后,没有警告和错误,就可以运行下面的命令进行编译和安装(编译的时间比较长)。
$ make
$ sudo make install
因为没有在配置中指定安装路径,所有使用的是默认的安装路径,即为/usr/local/Qt-5.4.2/。安装成功后,在该目录下将会产生如下目录:
$ ls /usr/local/Qt-5.4.2/
bin doc imports include lib mkspecs plugins qml translations
3在根文件系统中添加Qt
首先进入到根文件系统的目录,将安装好的Qt目录下的所有内容拷贝到根文件系统中,使用如下的命令:
$ cd /nfs/rootfs
$ mkdir usr/local/
$ cp -a /usr/local/Qt-5.4.2/ usr/local/
然后编辑etc目录下的profile文件,添加如下的内容:
export QTDIR=/usr/local/Qt-5.4.2
export QT_QPA_FONTDIR=$QTDIR/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:size=1024x600:tty=/dev/ttySAC2
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH$QTDIR:$QTDIR/lib
其中QT_QPA_FONTDIR环境变量用于指定字体的路径,QT_QPA_PLATFORM_PLUGIN_PATH环境变量用于指定插件的路径,QT_QPA_PLATFORM环境变量用于指定Qt的运行平台,这里是linuxfb,表示基于Linux的帧缓存,fb用于指定帧缓存设备,size用于指定显示设备以像素为单位的宽高,而tty用于指定非
GUI程序使用的tty。这个环境变量中的项目需要根据实际情况进行修改。
4 安装Qt集成开发环境
Qt集成开发环境可以在官网上进行下载,链接地址为//download.qt.io/official_releases/qt/,在网页中选择需要的版本点击下载即可。这里以Linux下的5.4.2的32位版本为例,其下载地址为//mirrors.ustc.edu.cn/qtproject/archive/qt/5.4/5.4.2/qt-opensource-linux-x86-5.4.2.run。可以在网页上直接点击进行下载,也可以通过下面的命令进行下载。
$ wget -c //mirrors.ustc.edu.cn/qtproject/archive/qt/5.4/5.4.2/qt-opensource-linux-x86-5.4.2.run
下载完成后,添加可执行权限并执行安装程序,使用下面的命令。
$ chmod u+x qt-opensource-linux-x86-5.4.2.run
$ ./qt-opensource-linux-x86-5.4.2.run
程序运行后首先弹出下面的界面,点击Next进行安装。
图1 Qt安装界面1
接下来选择安装的路径,通常使用默认路径即可。
图2 Qt安装界面2
然后选择功能组件,保持默认,即全部选择。
图3 Qt安装界面3
然后是许可证协议的确认,选择上面的那个,表示同意。
图4 Qt安装界面4
然后是确认安装,点击Install即可。
图5 Qt安装界面5
后点击Finish完成安装。
图6 Qt安装界面6
在编译Qt代码时可能出现“error: GL/gl.h: No such file or directory”的错误,需要使用下面的命令来安装相应的库。
$ sudo apt-get install libqt4-dev
5 添加ARM平台的构建环境
Qt集成开发环境安装好后,默认只有PC机上的构建环境,需要手动添加 ARM平台上的构建环境,添加的步骤如下。
在集成开发环境中选择Tools->Options子菜单。
图7 添加ARM平台构建环境步骤1
在弹出的对话框中点击Add按钮。
图8 添加ARM平台构建环境步骤2
在弹出的对话框中选择Qt移植后安装路径中的qmake工具,然后点击Open按钮。
图9 添加ARM平台构建环境步骤3
然后点击Apply按钮。
图10 添加ARM平台构建环境步骤4
接下来选择交叉编译工具,在刚才的对话框中选择Compilers选项卡,然后点击Add按钮。
图11 添加ARM平台构建环境步骤5
在弹出的对话框中选择交叉编译工具中的arm-linux-c++工具。
图12 添加ARM平台构建环境步骤6
选择好后给该编译器设置一个名字,然后点击Apply按钮。
图13 添加ARM平台构建环境步骤7
接下来添加构建套件,在刚才的对话框中选择Kits选项卡,然后点击Add按钮。
图14 添加ARM平台构建环境步骤8
然后按照下图进行设置。
图15 添加ARM平台构建环境步骤9
设置好后,点击OK按钮。
6 编写并运行Qt测试程序
经过前面的步骤后,Qt移植完成,集成开发环境设置成功。接下来编写一个测试程序,并且在开发板上进行测试。
首先要建立一个Qt的工程,在集成开发环境中选择File->New File or Project子菜单。
图16 新建Qt工程步骤1
在弹出的对话框中按照下图进行选择,然后点Choose按钮。
图17 新建Qt工程步骤2
接下来设置工程的名称和路径。
图18 新建Qt工程步骤3
接下来选择构建的套件,注意需要选择ARM的构建套件。
图19 新建Qt工程步骤4
接下来设置窗口的类和文件的名称,保持默认选项即可。
图20 新建Qt工程步骤5
后,点击Finish按钮完成工程的创建。
图21 新建Qt工程步骤6
编辑UI界面,添加一个Line Edit和一个Push Button,并将Push Button的显示的名称改为Clear,将窗口的大小改为1024x600,这样窗口可以布满整个显示屏。接下来为按钮添加槽函数,右击按钮,然后在弹出的菜单中选择go to slot子菜单即可。
图22 添加按钮槽函数步骤1
在弹出的对话框中选择clicked,然后点OK按钮。
图23 添加按钮槽函数步骤2
在自动生成的槽函数中,添加如下的代码。
void MainWindow::on_pushButton_clicked()
{
ui->lineEdit->clear();
}
代码编写完成后进行保存,然后先选择PC上的构建套件进行编译测试,点击下图中的三角形按钮即可运行。
图24 选择PC机上的构建套件
程序正常运行的话,会出现一个窗口,在文本框中可以输入字符,点击Clear按钮可以清楚文本框内的字符。
图25 在PC机上运行程序
测试成功后,在选择ARM平台的构建套件。
图26 选择ARM构建套件
然后在菜单中选择Build->Build All,即可完成交叉编译。
图27 交叉编译Qt工程
编译成功后,在项目的同级目录下会生成一个build-Test-ARM_Qt_5_4_2_GCC_32bit-Debug目录,进入到该目录,并将生成的可执行程序拷贝到根文件系统中。使用如下的命令:
$ cd build-Test-ARM_Qt_5_4_2_GCC_32bit-Debug/
$ cp Test /nfs/rootfs/root/
将开发板接上USB的鼠标和键盘,然后上电,使用NFS挂载根文件系统,登录系统后,使用下面的命令运行Qt程序:
# ./Test -plugin evdevmouse:/dev/input/event1 -plugin evdevkeyboard:/dev/input/event2
开发板上运行的程序功能将会和刚才在PC机上运行的程序功能一样。在命令行中通过evdevmouse指定了鼠标设备,通过evdevkeyboard指定了键盘设备。这些设备的路径需要根据系统的实际情况而定。