前段时间给手头的Cubietruck重新整理一套Qt开发环境,顺手把x64、x86、armhf三个版本的Qt 5.8.0全部编译安装了一遍。这个做法听起来有点折腾,但实际需求很实在:日常在x64主机上写界面、调逻辑,需要一套桌面版的Qt;要兼容老依赖或32位中间件时,又得用x86版;最终部署到Cubietruck上跑的,则是armhf版本。三个版本共用一份源码,只是configure参数和工具链不同。
这篇文章把整套流程按实际操作顺序记录下来,重点放在armhf交叉编译上,因为这是Cubietruck项目里最容易被卡住的一环,同时给出x64和x86的完整编译步骤,方便你在PC端做同版本联调。内容适合正在给A20开发板做Qt移植、或者想在同一套环境中同时维护多架构SDK的嵌入式Linux开发者参考。编译过程中常见的问题和排查方法放在最后,都是我自己踩过的坑,直接照着做能省不少时间。
1. 编译前的整体认知与方案选型
1.1 为什么要在同一套环境编译三个版本
先说说为什么要一次性编译x64、x86、armhf三个版本。Qt是以目标平台为导向的,同一个版本的Qt源码可以编译出不同架构下的库文件,但这些库文件不能互相替代。x64是PC上64位Linux系统用的,x86则是32位Linux或旧系统环境需要,armhf是目前Debian系嵌入式Linux上最常见的ARM硬浮点架构,Cubietruck这类全志A20板子跑的系统基本都属于armhf。
在实际开发流程里,x64版本解决的是"开发效率"问题:Cubietruck性能有限,直接在板上编译写界面代码非常痛苦,在x64主机上先用同一版本Qt把代码逻辑跑通,再交叉编译到armhf版本部署,这是嵌入式开发最常见的节奏。x86版本解决的是"兼容验证"问题,有些第三方32位库或者老驱动只提供x86版本,程序最终要跟这些库混编时,桌面端就得有一份x86 Qt来提前验证接口。
很多人在Cubietruck上做Qt开发时只关心armhf版本,等到代码在板上频繁编译、频繁崩溃才知道痛苦。正因为我一开始就把三个版本都准备好,后续调试Qt程序时,逻辑问题在PC端几分钟就能定位,真正放到板上跑的每次都是编译好的产物,整个迭代速度快了不止一倍。
1.2 Cubietruck平台对Qt构建的约束
Cubietruck的主控是全志A20,双核Cortex-A7,大部分版本带1GB DDR3内存,GPU是Mali400 MP2。这个配置放到今天看确实比较基础,但对于Qt 5.8.0来说完全够用,前提是编译方式要选对。
Cubietruck的板载存储通常是nand/flash,跑的系统可以是Lubuntu、Debian或者Cubian。如果直接在板子上运行Qt源码的configure和make,会遇到两个问题:一是CPU性能低,编译整个Qt 5.8.0完整版可能需要四五个小时以上;二是内存紧张,1GB内存跑编译很容易触发OOM,哪怕加了swap也不一定稳定。所以我的建议是,armhf版本必须在PC上用交叉编译工具链完成,生成armhf二进制之后拷到Cubietruck上运行。
另一个约束是系统架构。Cubietruck跑的系统虽然是ARMv7指令集,但A20的浮点单元是VFPv4和NEON,编译器必须用hard-float模式,也就是我们常说的armhf。如果编译时误用了armel软浮点,程序在板上会运行得非常慢,甚至直接报非法指令错误。这个细节会在后面的qmake.conf配置中体现。
在方案选型上,Qt 5.8.0本身支持在同一个源码树里分别构建多个平台,只需要给每个平台一个独立的build目录和独立的prefix安装路径即可。这样三个版本互不干扰,源码不重复下载,磁盘占用也最省。我这里选择的是Qt 5.8.0,因为它对armhf平台的改动相对稳定,qmake配置清晰,而且不需要像Qt 6那样引入额外的cmake依赖,对于Cubietruck这种性能有限的目标平台反而更顺手。
2. 编译环境与依赖准备
2.1 基础工具链安装
交叉编译Qt 5.8.0需要一套完整的Linux构建环境。我的主机是Ubuntu 16.04 x86_64,这套步骤在Ubuntu 18.04上同样适用,只是个别依赖包名略有出入。
先安装基础编译工具和常用依赖库:
sudo apt update sudo apt install build-essential perl python git sudo apt install libgl1-mesa-dev libfontconfig1-dev libfreetype6-dev sudo apt install libx11-dev libxkbcommon-dev libxcb1-dev sudo apt install libxcb-xinerama0-dev libxcb-icccm4-dev sudo apt install libxcb-image0-dev libxcb-keysyms1-dev sudo apt install libxcb-render-util0-dev libxcb-xkb-dev sudo apt install libglib2.0-dev libssl-dev libicu-dev sudo apt install libts-dev libudev-dev这里面的依赖各有各的用途。libxcb系列是为Qt的xcb平台插件服务的,这个插件能让Qt程序在Linux桌面环境下正常显示窗口;libfontconfig和libfreetype是字体渲染的基础,缺少它们Qt编译出来的程序即使能跑,界面上也全是方块字;libgl1-mesa-dev提供OpenGL开发头文件,虽然Cubietruck上最终用不到桌面OpenGL,但configure阶段会检测OpenGL相关功能,提前装好可以避免不必要的检测失败。
如果你是直接复制上面的命令,请注意Ubuntu 18.04里libts-dev可能叫libts-dev,Ubuntu 20.04及之后系统需要额外确认,缺失的话configure会显示tslib相关警告,但不影响非触摸屏场景使用。想要在编译时省去这些依赖检查的麻烦,也可以稍后统一加-no-feature-xxx参数,但我建议尽量把依赖装齐,这样Qt编译出来的功能模块更完整。
2.2 依赖库清单与作用
Qt 5.8.0的configure阶段会自动探测很多库,如果探测不到,它并不会立刻报错,而是自动关闭相应功能。这种方式虽然提供了兼容性,但也容易让人忽略一些实际需要的能力。比如:没有libssl,Qt的网络模块就编不出SSL支持;没有libicu,Qt的文本处理和日期模块功能会退化;没有libudev,Qt在Linux下的设备热插拔检测会失效。
下面这个表格是把关键依赖和它对应的Qt功能模块对应起来,方便你裁剪或者排查:
| 依赖库 | Qt模块 | 缺失后的影响 |
|---|---|---|
| libxcb系列 | Qt Xcb平台插件 | 程序无法以GUI方式运行 |
| libfontconfig/freetype | Qt Gui字体渲染 | 界面汉字显示异常 |
| libglib2.0 | Qt EventDispatcher | 事件循环集成能力下降 |
| libssl | Qt Network SSL | 无法使用Https链接 |
| libicu | Qt Core文本处理 | Unicode处理能力受限 |
| libts | Qt LinuxFB触摸输入 | 触摸屏不可用 |
| libudev | Qt Core设备管理 | 外部设备检测异常 |
对于Cubietruck的armhf交叉编译,还有一类特殊的依赖:目标板上运行的库版本必须跟交叉编译时sysroot里的头文件版本一致。比如板上系统是Debian 9,那sysroot最好也用Debian 9的根文件系统,否则编译出来的Qt库在板上可能因为glibc版本不匹配而无法启动。
2.3 交叉工具链与sysroot准备
armhf版本编译的核心是arm-linux-gnueabihf工具链。在Ubuntu上可以直接装:
sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf装完之后验证一下编译器版本:
arm-linux-gnueabihf-gcc --version输出正常说明基础工具链没问题。但光有编译器还不够,交叉编译Qt时,configure会去检查目标平台上的头文件和库文件。这些文件来自armhf的根文件系统,也就是sysroot。最省事的方式是用debootstrap制作一个armhf的最小Ubuntu/Debian根文件系统:
sudo apt install debootstrap sudo mkdir /opt/armhf-rootfs sudo debootstrap --arch=armhf bionic /opt/armhf-rootfs http://ports.ubuntu.com/ubuntu-ports/这里以Ubuntu 18.04的bionic为例,如果你板子跑的是Debian,可以把发行版名称和源换成对应的debian源。debootstrap执行时间取决于网速,一般几分钟到二三十分钟。
根文件系统准备好之后,进入chroot环境安装依赖:
sudo chroot /opt/armhf-rootfs apt-get update sudo chroot /opt/armhf-rootfs apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libxcb1-dev libxkbcommon-dev libglib2.0-dev libts-dev libudev-dev libssl-dev libicu-dev这些dev包会把armhf架构下的头文件和.a静态库放进sysroot的/usr目录里。最后设置两个环境变量,方便后续任何交叉编译任务使用:
export SYSROOT=/opt/armhf-rootfs export PATH=/usr/bin:$PATH3. 三个版本的完整编译流程
3.1 x64版本编译步骤
先下载Qt 5.8.0源码包。源码包有很多渠道,这里用官方archive地址,如果下载慢可以使用国内镜像站:
wget https://download.qt.io/archive/qt/5.8/5.8.0/qt-everywhere-opensource-src-5.8.0.tar.xz tar -xf qt-everywhere-opensource-src-5.8.0.tar.xz cd qt-everywhere-opensource-src-5.8.0x64版本编译最简单,因为主机就是x86_64架构,不需要交叉工具链,所有依赖库都在系统里。先创建独立目录,避免在源码目录里直接构建产生污染:
mkdir build-x64 cd build-x64 ../configure -prefix /opt/Qt5.8.0-x64 \ -opensource -confirm-license \ -release -shared \ -xcb -qt-xcb \ -nomake tests -nomake examples参数说明一下:-prefix指定安装路径,这样后续make install会把所有文件安装到独立目录,不会污染系统;-opensource和-confirm-license组合用于跳过交互确认;-release表示编译发布版本,去掉调试符号,体积和运行速度都有优势;-shared表示动态链接;-xcb启用xcb平台插件,配合-qt-xcb让Qt使用自带的libxcb,避免跟系统xcb版本冲突;-nomake tests和-nomake examples是为了减少编译时间。
然后开始编译:
make -j$(nproc) 2>&1 | tee build.log sudo make install如果机器内存足够,-j参数可以用逻辑核心数。编译时间取决于CPU性能,一般半小时到一小时。
编译完成后验证:
/opt/Qt5.8.0-x64/bin/qmake --version能正常输出版本信息,x64版本就成功了。后续写Qt程序时,用这个qmake来生成Makefile即可。
3.2 x86版本编译步骤
x86版本的目标是32位Intel架构。这一步容易让人犯迷糊的地方在于,我是在64位主机上编译32位版本的Qt。如果你手头正好是32位系统的老机器,那可以直接照搬x64的步骤,把-prefix改成x86路径即可。但绝大多数人手上都是64位系统,所以要处理多架构编译的问题。
首先是安装32位编译支持:
sudo apt install gcc-multilib g++-multilibgcc-multilib让64位系统的gcc具备编译-m32程序的能力,也就是能生成32位代码。光有编译器还不够,32位程序需要32位版本的C运行库和依赖库,所以还得启用dpkg的多架构支持并安装32位基础库:
sudo dpkg --add-architecture i386 sudo apt update sudo apt install libc6-dev:i386 libx11-dev:i386 libxcb1-dev:i386 libfontconfig1-dev:i386 libfreetype6-dev:i386 libssl-dev:i386 libglib2.0-dev:i386这里有很多依赖包,如果configure阶段提示缺少某个库,就再用apt-get install 包名:i386补上。安装32位库时要注意,部分:i386包依赖的多媒体库比较大,如果只是做基础Qt应用,可以只装核心库,configure不会全部强制要求。
configure时指定32位平台:
mkdir build-x86 cd build-x86 linux32 ../configure -prefix /opt/Qt5.8.0-x86 \ -opensource -confirm-license \ -release -shared \ -platform linux-g++-32 \ -xcb -qt-xcb \ -nomake tests -nomake exampleslinux32命令的作用是把当前环境伪装成32位系统,有些configure脚本会自动检测host系统位数,不加这个可能检测出64位导致配置错误。核心参数是-platform linux-g++-32,这个mkspec明确告诉构建系统用-m32编译标志。
编译安装跟x64一样:
make -j$(nproc) 2>&1 | tee build.log sudo make install这里有一个非常常见的坑:没有安装32位依赖时,configure会报“Basic XLib functionality test failed”。很多人以为是xcb没装好,其实通常是x11相关库缺失。比较好的排查方式是看config.log,搜索test failed附近的错误信息,几乎都会明确指出是哪个头文件或库找不到,直接用apt装对应的:i386版本即可。
3.3 armhf版本交叉编译步骤
armhf版本是整个流程里最核心也最容易出问题的一步。先准备armhf专用的mkspec。Qt 5.8.0源码里默认有linux-arm-gnueabi-g++配置,但针对armhf需要微调浮点参数。我习惯复制一份然后定制:
cp -r qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/linux-arm-gnueabihf-g++ cd qtbase/mkspecs/linux-arm-gnueabihf-g++然后编辑qmake.conf,改成下面这样:
# # qmake configuration for building with arm-linux-gnueabihf-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) 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_CFLAGS += -marm -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard QMAKE_CXXFLAGS += -marm -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard QMAKE_INCDIR += $$[QT_SYSROOT]/usr/include/arm-linux-gnueabihf QMAKE_LIBDIR += $$[QT_SYSROOT]/usr/lib/arm-linux-gnueabihf load(qt_config)这些编译参数是针对Cubietruck的A20芯片特别选择的。-march=armv7-a告诉编译器按ARMv7指令集生成代码;-mfpu=neon-vfpv4启用NEON和VFPv4浮点单元,A20是Cortex-A7,支持这个指令集,向量运算和浮点性能会明显提升;-mfloat-abi=hard则确保使用硬件浮点ABI,也就是armhf的意义所在。
sysroot环境变量在这里很关键,configure时通过-sysroot参数指定,它的作用是让编译器在交叉编译时优先查找sysroot下的头文件和库,而不是主机系统的x86_64版本。
创建armhf的build目录并执行configure:
cd qt-everywhere-opensource-src-5.8.0 mkdir build-armhf cd build-armhf export SYSROOT=/opt/armhf-rootfs export PKG_CONFIG_PATH=$SYSROOT/usr/lib/arm-linux-gnueabihf/pkgconfig export PKG_CONFIG_SYSROOT_DIR=$SYSROOT ../configure -prefix /opt/Qt5.8.0-armhf \ -opensource -confirm-license \ -release -shared \ -xplatform linux-arm-gnueabihf-g++ \ -sysroot $SYSROOT \ -no-xcb -linuxfb -tslib \ -no-eglfs \ -nomake tests -nomake examples这里的-xplatform和x64版本里的-platform不同,-platform用于本机编译,-xplatform用于交叉编译。sysroot指向我们的armhf根文件系统。没有用-xcb,因为Cubietruck不是跑完整桌面系统,不需要xcb插件,真正依赖的是linuxfb平台插件,它直接把Qt窗口输出到framebuffer设备/dev/fb0。-tslib则启用触摸屏支持,Cubietruck如果接的是电阻屏或者带tslib驱动的触摸屏,这个选项必不可少。
有个容易被忽略的点:如果sysroot里的pkgconfig路径不在PKG_CONFIG_PATH里,configure可能在探测fontconfig等库时失败。所以开头设置的两个环境变量一定要先export,否则后续会报各种检测不到库的诡异错误。
编译:
make -j$(nproc) 2>&1 | tee build.log sudo make install交叉编译比x64版本编译耗时更长,一般在1到2小时之间。编译期间可以留意日志里是否有error中断,如果有特定模块编译失败,比如qtmultimedia库缺ALSA依赖,可以单独进入对应模块目录重新make。
编译完成之后,把安装目录打包拷到板子上:
cd /opt sudo tar -czf qt5.8.0-armhf.tar.gz Qt5.8.0-armhf scp qt5.8.0-armhf.tar.gz cubie@<板子IP>:/home/cubie/在Cubietruck上解压到目标目录:
sudo tar -xzf qt5.8.0-armhf.tar.gz -C /opt/3.4 关于Qt模块裁剪
交叉编译完完整版Qt之后,建议检查一下实际安装体积。完整版Qt 5.8.0 armhf大概有几百MB,如果Cubietruck的存储空间比较小,可以通过configure阶段禁用不需要的模块来节省空间。比如明确不用Qt Multimedia和Qt WebEngine的话,可以加:
-skip qtwebengine -skip qtmultimedia -skip qtwayland-skip参数在Qt 5.8里是支持的,每指定一个模块就跳过对应目录的构建。对于纯界面业务,通常保留qtbase、qtdeclarative、qtquickcontrols即可。裁剪模块时要注意依赖关系,跳过qtwebengine对编译时间影响最大,因为那个模块编译量非常大,跳过之后整个构建时间能缩短一半以上。我当时第一次编译没裁剪,等了相当久才完成,后来重编时果断跳过webengine,体验完全不同。
4. 常见问题与排查技巧实录
4.1 configure阶段问题
Configure阶段是报错最密集的地方,排查思路其实很统一:无论报什么错,第一件事是查看config.log,搜索最后的error关键字,看错误上下文。下面几个是我遇到的典型情况。
第一个问题:报“Basic XLib functionality test failed!”。这个错误在x64和x86编译时经常出现。原因基本就是找不到libX11头文件或者xcb相关库。解决办法是检查libx11-dev和libxcb1-dev是否安装完整,如果是在64位主机上编x86版,则要安装:i386版本。如果确定依赖没问题但还报错,可以打开config.log看具体是哪个test executable编译失败,错误信息里会直接显示缺少哪个头文件或函数。
第二个问题:报“Could not find qmake spec 'linux-arm-gnueabihf-g++'”,这是mkspec没放对位置。确认一下是否在qtbase/mkspecs目录下创建了对应的文件夹,而且名称要和-xplatform参数完全一致,包括大小写。
第三个问题:configure时提示“The QT_ARCH is not supported by the toolchain”或者类似的架构不匹配错误。这种情况通常是sysroot路径没设置好,或者工具链前缀不对。在armhf配置里,务必确认arm-linux-gnueabihf-gcc命令能正常执行,并且qmake.conf里的QMAKE_CC和QMAKE_CXX指向正确的编译器。
4.2 make阶段问题
Make阶段最常见的是内存不足导致的编译器崩溃。症状是编译某个大文件时突然报“internal compiler error: Killed”,这是因为gcc进程被系统OOM杀掉。解决办法有几种:一是降低-j并发数,比如从-j8降到-j4甚至-j2;二是临时增加swap分区,尤其对于内存较少的构建机;三是拆分编译,先单独编译qtbase,再编译其他模块,这样可以把峰值内存摊开。
另一个make阶段的经典问题是“c++: fatal error: Killed signal terminated program cc1plus”,本质上还是内存不足。如果你用交叉编译,同时主机的内存又比较小,这样的情况很容易反复出现。我建议在make之前先执行:
free -h swapon --show如果swap没有开启或者只有几百MB,就先加一个swap文件:
sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile加上4GB swap之后,编译稳定性会好很多。
还有一种情况是make过程中某个子模块链接失败,报一堆未定义的引用。这种基本都是交叉编译时依赖库顺序或者库路径不对。排查方法是找到报错的链接命令,手动复制到终端执行,然后在末尾加上-ldl之类的库参数,确认能否链接通过。如果是因为sysroot目录下的库符号不兼容,最好重新debootstrap一个和板子系统版本一致的根文件系统,别指望直接在原sdk上打补丁。
4.3 板子运行阶段问题
编译好的Qt库拷到Cubietruck后,运行程序可能遇到的问题比编译期要多得多。第一个高发问题是“error while loading shared libraries: libQt5Core.so.5: cannot open shared object file”。原因很简单,动态库路径没设置。解决方法是把Qt库路径加入LD_LIBRARY_PATH,或者把路径写入/etc/ld.so.conf.d/qt5.conf然后ldconfig。
第二个高发问题是程序启动时报“Could not load the Qt platform plugin "linuxfb"”。这个问题的根源是Qt运行时找不到plugins/platforms目录下的libqlinuxfb.so。Qt通过编译时的QLibraryInfo来确定插件路径,如果整个安装目录是从PC搬到板子的,路径不对就会出问题。解决方法是使用设置环境变量QT_QPA_PLATFORM_PLUGIN_PATH,或者在程序里用QApplication::addLibraryPath显式指定。最稳妥的做法是进入Qt安装目录检查目录结构:
ls /opt/Qt5.8.0-armhf/plugins/platforms/里面有libqlinuxfb.so就说明插件编译进去了,接下来把环境变量设置好即可。
第三个问题是触摸屏没反应。Qt 5.8的linuxfb插件默认会读取libinput或者tslib库。如果sysroot里装了tslib,configure时也开了-tslib,那运行前还要设置对应的触摸屏设备参数。常见做法:
export QT_QPA_PLATFORM=linuxfb:/dev/fb0 export TSLIB_TSDEVICE=/dev/input/event0 export TSLIB_CALIBFILE=/etc/pointercal export QT_QPA_FB_TSLIB=1具体event编号要根据板子的实际设备节点确定,有时候是event1,有时候是event2,在板上执行一下:
cat /proc/bus/input/devices就能看到触摸屏对应的设备节点。
字体问题也得提醒一下。Qt在armhf板子上默认找不到中文字体,界面里的中文会显示成方块。解决方法是把PC上的中文字体拷贝到板子Qt目录下:
scp /usr/share/fonts/truetype/wqy/wqy-microhei.ttc cubie@<板子IP>:/opt/Qt5.8.0-armhf/lib/fonts/然后设置QT_QPA_FONTDIR指向这个目录。如果你的Qt程序完全不涉及中文,这一步可以跳过,但绝大多数GUI项目都躲不开汉字显示。
4.4 问题排查速查表
| 问题现象 | 直接原因 | 排查/解决办法 |
|---|---|---|
| configure报Basic XLib test failed | 缺少xcb/x11开发包 | 安装libx11-dev和libxcb1-dev,x86版需要安装:i386包 |
| qmake spec not found | mkspec目录不存在 | 检查qtbase/mkspecs下是否创建了对应配置目录 |
| make时gcc被Killed | 内存不足 | 降低-j并发数,增加swap空间 |
| 链接阶段大量未定义引用 | sysroot库路径或顺序不对 | 查看具体链接命令,核查sysroot下依赖库 |
| 板子上报libQt5Core.so找不到 | 动态库路径未配置 | export LD_LIBRARY_PATH=/opt/Qt5.8.0-armhf/lib |
| 找不到linuxfb平台插件 | plugins目录未拷贝或路径不对 | 设置QT_QPA_PLATFORM_PLUGIN_PATH |
| 触摸屏无响应 | tslib设备参数未配置 | 设置TSLIB_TSDEVICE和QT_QPA_FB_TSLIB |
| 界面中文显示方块 | 缺少字体 | 拷贝中文字体到Qt fonts目录,设置QT_QPA_FONTDIR |
5. 部署到Cubietruck后的运行环境配置
Qt装到板子上只是第一步,实际运行程序时还需要配全环境变量。Cubietruck的系统环境相对精简,很多默认路径跟PC不同,我在板子上反复试过几套配置,最终稳定生效的是这一个:
export QTDIR=/opt/Qt5.8.0-armhf export PATH=$QTDIR/bin:$PATH export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH export QT_QPA_PLATFORM=linuxfb:/dev/fb0 export QT_QPA_FONTDIR=$QTDIR/lib/fonts export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins/platforms把这些写进板子上用户的~/.bashrc,避免每次开终端都手工设置。然后写一个最简单的Qt测试程序,编译后放到板子上验证整条链路:
#include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label("Cubietruck Qt OK"); label.resize(320, 240); label.show(); return app.exec(); }编译时用armhf的qmake:
/opt/Qt5.8.0-x64/bin/qmake # 这是PC端x64版本,用来生成Makefile make # 这里需要确保交叉工具链已被调用严格来说,PC上直接用x64 qmake编译出来的产物不能给armhf板子用。正确操作是使用交叉编译好的qmake:
/opt/Qt5.8.0-armhf/bin/qmake或者在PC上直接用armhf SDK里的qmake交叉编译:
/opt/Qt5.8.0-armhf/bin/qmake test.pro make再把生成的test二进制拷贝到板子上运行。如果能在Cubietruck的屏幕上看到“Cubietruck Qt OK”标签,说明整个工具链已经跑通了。
关于linuxfb和eglfs的选择,我个人的体会是:Cubietruck虽然支持Mali400 GPU,但GPU驱动在Linux板端往往没有桌面级那么稳定,如果只是做普通界面应用,linuxfb的软件渲染反而更省心,兼容性也更好。如果要做动画较多的QML应用,再考虑折腾eglfs,不过驱动和qmake参数都得重新调,不是一蹴而就的事。
最后再分享一个小技巧。交叉编译Qt时,建议把config.log和build.log都保留下来。下次升级Qt版本或者换板子时,很多问题可以在旧日志里直接找到对应答案,比自己重新排查一遍快得多。编译这套三个版本的Qt流程,我最大的感受是:真正容易翻车的地方从来不是configure那些参数,而是qmake.conf里的编译器前缀、sysroot路径、浮点参数这些细节。只要这些基础设定不出错,整个构建流程其实可以一路顺畅跑完。