在Zynq平台上运行QT其实与PC无异,都需要相应的执行环境,只不过PC上的QT Lib可以使用QT SDK自动安装配置,而Zynq平台上的QT Lib则需要手动安装。另外,我们自己编写的代码只需要使用Xilinx交叉编译器进行一次编译就能在ZedBoard上执行,而QT代码则需要先由QMake进行配置,之后再用交叉编译器编译。因此,想让QT开发的应用程序在ZedBoard上运行,首先就要编译一个适合Zynq平台的QT库。
其实操作方法已经在Xilinx Wiki中介绍了,但跟着Xilinx的介绍走一通可能都不知道自己在干什么(兔子一开始就是这样)。这里我就给大家一步骤讲解一下。原始资料请见Wiki:
http://wiki.xilinx.com/zynq-base-trd-qt
Xilinx已经提供了一个QT Lib源码包和相关的配置文件,不过是4.7版的:
http://download.xilinx.com/kits/qt_build_src.tar
兔子使用的4.8.3版本可以在QT官网上下载:
http://releases.qt-project.org/qt4/source/qt-everywhere-opensource-src-4.8.3.tar.gz
之前我们已经配置好了交叉编译环境使用的环境变量PATH和CROSS_COMPILE,而为了简便操作,还可以再设置几个环境变量。
export ZYNQ_QT_BUILD=/path/to/qt/build
export ZYNQ_QT_INSTALL=/path/to/qt/install
export PATH=$ZYNQ_QT_INSTALL/bin:$PATH
ZYNQ_QT_BUILD指向QT源码解压后的目录,ZYNQ_QT_INSTALL则指向QT Lib的安装目录,以后要编译QT工程,都需要用到安装目录中的程序,因此在PATH中添加了一条指向QMake等程序所在的路径。按需要替换等号后面的路径,比如兔子的安装路径是/arm/qt/qt-lib/。
之后将qt-everywhere-opensource-src-4.8.3.tar.gz解压到ZYNQ_QT_BUILD指向的目录中,把qt_build_src.tar里的qmake.conf配置文件复制到qt-everywhere-opensource-src-4.8.3/mkspecs/qws/linux-arm-gnueabi-g++目录下,这个文件用来告知QMake应该用哪个编译器来编译QT工程。然后对QT进行配置:
./configure
-xplatform qws/linux-arm-gnueabi-g++ \
-little-endian \
-opensource \
-host-little-endian \
-confirm-license \
-nomake demos \
-nomake examples \
虽然QT Lib是在本地进行交叉编译的,这些配置选项则根据目标平台而定,其中-embedded arm一项表示目标设备为ARM核心设备,-prefix $ZYNQ_QT_INSTALL则将QT Lib安装到指定的目录里。
兔子在看到这个选项后当即想到能不能在Xilinx其他系列的FPGA上移植QT。很不幸的是,目前QT似乎并不支持MicroBlaze或NIOS II这样的软核,虽然也有资料显示可以实现,但应该需要不小的工作量。还有待进一步研究啊。
配置完成后进行编译:
make
编译好了就可以进行安装(安装需要在root权限下进行):
make install
之后将Xilinx交叉编译器中的基础C++库复制到QT的安装目录下:
cp -P /path/to/cross/compiler/arm-xilinx-linux-gnueabi/libc/usr/lib/libstdc++.so* $ZYNQ_QT_INSTALL/lib
这样就位Zynq平台手动安装了一个QT Lib。
二、为ZedBoard制作预编译QT库镜像
安装好QT Lib后,已经可以直接编译QT工程了,但是想要在ZedBoard上运行还需要将所需的库文件拷贝到ZedBoard上,那么为什么要把它做成镜像文件呢?
兔子的理由是这样的:以Digilent出厂默认的Demo系统为例,该系统的rootfs是通过在内存中虚拟出一个8M-Byte大小的空间并加载固定的镜像文件来实现的,这个rootfs十分小巧,但缺点是空间不足。数十兆的QT支持库无法装入这个小镜像里,即使可以也会占用大量内存。因此只要将其做成镜像的形式,就可以保存在SD卡中,通过mount指令装载,节省了内存资源。
Xilinx已经提供了制作镜像的方法(安装需要在root权限下进行):
cd $ZYNQ_QT_BUILD
dd if=/dev/zero of=qt_lib.img bs=1M count=80
mkfs.ext2 -F qt_lib.img
chmod go+w qt_lib.img
mount qt_lib.img -o loop /mnt
cp -rf $ZYNQ_QT_INSTALL/* /mnt
chmod go-w qt_lib.img
umount /mnt
这个qt_lib.img就是我们需要的QT运行库了。
三、编译QT工程
在上一篇博客中,我们已经建立好了一个QT工程,名为HelloQT。在交叉编译之前,建议复制一份工程文件夹,以防交叉编译后,QT Creator无法再运行该工程。
这里我们将复制得到的文件夹命名为zed_complie,保证ZYNQ_QT_INSTALL和PATH变量已经配置正确(可以按之前讲的方法把两个export命令加入到开机自动运行中),在这个文件夹下,依次执行下列指令:
qmake –project
qmake
make
完成后会生成一个与文件夹同名的可执行文件,在这里就叫zed_complie。和拷贝到SD卡中,在ZedBoard里装载qt_lib.img。要注意的是,这个镜像最好装载到与本地安装目录相同的路径下,即ZYNQ_QT_INSTALL指向的目录,兔子就把这个镜像装载到/arm/qt/qt-lib/文件夹下(mmcblk0p2是SD卡的分区)。
mount /dev/mmcblk0p2 /mnt/
mount /mnt/qt_lib.img /arm/qt/qt-lib/
这样一来,就可以运行QT程序了。-qws指令用来建立一个运行QT软件必须的QWS Server,这是由QT的运行机制决定的,软件会从/arm/qt/qt-lib/文件夹里调用QT运行库。
/sdcard/zed_compile –qws
再根据兔子之前讲的修改rootfs镜像的方法,便能够实现ZedBoard上电自动加载QT库并运行我们自己开发的应用软件。
深入思考:
1.能否通过修改环境变量来改变调用QT运行库的位置?
2.如何为Linaro系统编译QT库,并在Linaro系统下运行QT软件?
这两个问题就留给大家思考吧,希望研究出结果的朋友不吝分享啊。
最后发一个ZedBoard上的运行效果图:
——转自网友 懒兔子