简介:Qt5.5.1 ARM交叉编译链是一套面向ARM嵌入式场景的预编译Qt环境,主要服务在x86/PC上开发、部署到ARM设备(如嵌入式板卡、工业终端)的开发者,尤其适合嵌入式产品原型开发、工业控制类应用的快速迭代,也能用于教学评估与量产前期的方案验证。包内集成ARM GCC交叉编译器、qmake构建系统、Qt核心模块库及对应头文件,覆盖GUI、网络、SQL、XML等模块,省去在目标板上从源码编译Qt的复杂过程。压缩包约50.65MB(gz格式),以预编译库、头文件、配置脚本等文件为主,便于在Linux开发主机上直接解压使用。已有338人学习。借助该工具链,开发者可在本机配置QTDIR、QMAKE等环境变量,通过qmake -spec linux-arm-gnueabi-g++指定目标架构,围绕ARM版本与ABI做好适配取舍,再结合真机调试与性能优化,即可建立一套完整的ARM端Qt应用开发与部署流程,显著降低多设备适配成本。
1. 这套Qt5.5.1 ARM已编译交叉编译链,解决的不只是编译速度问题
很多人拿到这个Qt5.5.1 ARM交叉编译链,第一反应是“省了我在x86上编译Qt那一个多小时”。但实际上,它最大的价值在于把开发环境与目标硬件解耦:你在PC上写完C++代码,用预编译好的ARM工具链现场生成二进制,再丢到ARM板子上跑。对于嵌入式Linux、工控触摸屏和物联网网关这类项目,这意味着团队里不需要每个人都配一台ARM开发板,也不需要有人在板子上敲make等半天。适合的人群很明确:做Qt嵌入式应用开发、维护老旧Qt5.5工程、或者刚从QWidget迁到QML而又不想升级整套工具链的工程师。这套链里包含了为ARM准备的GCC编译器、qmake构建系统、Qt5.5.1的预编译库和头文件,下面我按实际动手的顺序讲清楚怎么用,以及最容易翻车的地方。
2. 先看懂工具链的组成,才不会在ABI上翻车
2.1 解包后的目录结构与关键文件
拿到压缩包后,第一件事不是急着设环境变量,而是先看目录结构。这套链一般会解压出类似arm-qt5.5.1的根目录,里面至少包含bin、lib、include、mkspecs等几个关键文件夹。
tar -xzf qt5.5.1-arm.tar.gz cd qt5.5.1-arm ls -la ls mkspecs | grep armbin目录下应该能看到交叉编译器(类似arm-linux-gnueabi-g++或者arm-none-linux-gnueabi-gcc)以及Qt自己的工具(qmake、moc、rcc、uic)。lib目录存放的则是已经针对ARM编译好的Qt库文件(.so和.a)。mkspecs里的linux-arm-gnueabi-g++这类目录,是qmake用来确定编译规则的关键。
这条检查逻辑说明:先确认工具链确实存在,再确认qmake的spec目录和目录里的qmake版本一致。如果里面没有对应的mkspecs目录,那后面手动指定-spec参数时qmake会直接报错,这是最容易在第一步就卡住的地方。
2.2 ARMv7与ARMv8、硬浮点与软浮点的边界
交叉编译链里的“ARM”是个泛称。实际板子可能是ARMv7(比如Cortex-A7、A9),也可能是ARMv8(比如Cortex-A53、A72),甚至还有老旧的ARM11。最重要的一条边界是浮点运算规则:硬浮点(hard-float)用FPU寄存器传参,软浮点(softfp)用通用寄存器传参。两者编译出来的库不能混用,否则链接阶段会出现一堆“undefined reference”或者运行时直接Segmentation Fault。
我一般用readelf -A来检查一个现成的Qt库或者可执行文件的属性:
readelf -A lib/ libQt5Core.so.5 | grep Tag_ABI_VFP_args如果输出里有Tag_ABI_VFP_args: VFP registers,说明这个库是硬浮点编译的;如果没有任何输出,那大概率是软浮点。随后在qmake配置时,要保证编译器的-mfloat-abi参数和这个结果一致。很多新手拿到“arm交叉编译链”直接编,编完拷到板子上跑不起来,十有八九就是这里出了问题,而不是代码本身有bug。
2.3 环境变量怎么设才不出乱子
正确设置环境变量是这套链能否工作的前提。我建议不是把变量临时写在命令行里,而是写成一个setenv.sh脚本,每次开新终端都source一次,避免污染全局配置。
export PATH=/opt/qt5.5.1-arm/bin:$PATH export QTDIR=/opt/qt5.5.1-arm export QMAKE=/opt/qt5.5.1-arm/bin/qmake export LD_LIBRARY_PATH=/opt/qt5.5.1-arm/lib:$LD_LIBRARY_PATH export CROSS_COMPILE=arm-linux-gnueabi-关于变量含义:PATH让系统在路径下自动找到qmake和交叉编译器;QTDIR指向Qt的根目录,qmake和后续构建脚本依赖它来定位库和头文件;QMAKE显示指定qmake路径,防止系统里存在多个Qt版本时找错;LD_LIBRARY_PATH主要给目标板运行时用,但主机上做某些工具运行时也会用到;CROSS_COMPILE是交叉编译器的前缀,很多Makefile脚本依赖这个变量。
注意:不要把这些环境变量写进/etc/profile,除非这台机器就是专门做交叉编译的构建机。因为一旦PATH里带了ARM工具链,再编译主机上的原生Qt程序时,很可能意外走到arm编译器上,导致一堆“cannot find -lGL”的怪问题。
3. 基于qmake的交叉编译构建流程:从.pro到可执行文件
3.1 先确认mkspecs里有没有你要的spec
qmake的-spec参数决定了用什么样的编译规则。Qt5.5.1自带的ARM spec通常是linux-arm-gnueabi-g++,但在某些定制工具链里可能叫linux-arm-gnueabihf-g++,后缀代表硬浮点。使用前先查一遍真实目录:
ls $QTDIR/mkspecs/ | grep linux-arm正常能看到类似linux-arm-gnueabi-g++的输出。如果没看到,说明发布者在打包时把spec目录裁掉了,这时候需要手动把工具链路径写进qmake的配置里,实操起来比较麻烦,不如换个完整包。
3.2 一步步编译一个带GUI依赖的小工程
为了验证工具链是否可用,我通常先建一个最小Qt Widgets工程,不用任何第三方库,跑通了再进真实项目。先写工程文件:
# test.pro QT += core gui widgets TARGET = hellopanel TEMPLATE = app SOURCES += main.cpp再写一个最简单的窗口main.cpp,创建QApplication和QLabel。编译前先建一个独立的构建目录,避免把中间产物混进源码目录:
mkdir build-arm && cd build-arm $QTDIR/bin/qmake -spec linux-arm-gnueabi-g++ ../test.pro make -j$(nproc)执行完,目录下会生成hellopanel这个可执行文件。这里的-spec linux-arm-gnueabi-g++就是告诉qmake,要按交叉编译规则来生成Makefile,编译器、头文件路径、库路径全部改成工具链对应的值。make -j$(nproc)用多核并行编译,缩短验证时间。
3.3 常见构建失败与参数修正
下面是几个我反复遇到的报错和对应处理方式:
| 报错特征 | 常见原因 | 处理方式 |
|---|---|---|
Cannot find -lGL或cannot find -lGLESv2 | Qt的GUI模块依赖OpenGL ES库,工具链里缺少对应符号 | 在.pro里加QT -= opengl或指定LIBS += -lGLESv2,如果仍报错则检查lib目录下是否有libGLESv2.so |
qmake: not found | PATH里没有包含qmake所在目录 | source setenv.sh后重新执行which qmake |
mkspecs not found | qmake找不到spec目录 | 确认QTDIR指向工具链根目录,且mkspecs目录存在 |
编译时用了宿主机的.h文件 | INCLUDEPATH里带了原生Qt路径 | 删除.pro里的额外INCLUDEPATH,只依赖qmake自动添加的路径 |
undefined reference to std::__throw_bad_function_call() | 编译器版本和libstdc++版本不匹配 | 确认工具链里的g++版本和lib目录的libstdc++一致 |
qmake还有一个容易被忽视的变量叫QMAKE_CXXFLAGS,如果在.pro文件里手动追加了针
本文还有配套的精品资源,点击获取