1. 为什么需要搭建ARM交叉编译环境如果你正在开发一个运行在ARM架构嵌入式设备比如树莓派、RK3588开发板、或者各种工控机上的Qt图形界面程序那你肯定遇到过这样的场景在性能强大的x86电脑上写代码、调试感觉行云流水但每次想测试一下都得把代码拷贝到开发板上用板子那有限的CPU和内存去编译等个十几二十分钟是家常便饭效率低得让人抓狂。这时候交叉编译就是你的救星。简单来说它就像请了一个“翻译官”。你的电脑x86架构本身只会说“x86语言”而你的开发板ARM架构只懂“ARM语言”。交叉编译工具链就是这个翻译官它运行在你的x86电脑上却能理解ARM的指令集把你写的C/Qt代码直接“翻译”成ARM设备能执行的程序。这样一来所有繁重的编译工作都在高性能的开发机上完成生成的可执行文件直接丢到板子上就能跑开发效率瞬间提升好几个数量级。我刚开始接触嵌入式Qt开发时也傻乎乎地在板子上编译一个简单的Demo都要等好久。后来搭建好交叉编译环境后那种“秒编译、秒运行”的畅快感至今难忘。今天我就把自己在Linux平台下为Qt 5.14.2搭建ARM交叉编译环境并配置Qt Creator的完整过程、踩过的坑以及解决方案毫无保留地分享给你。整个过程我会尽量讲得细致确保即便是第一次接触的朋友也能跟着一步步做下来。2. 准备工作理清思路与获取资源工欲善其事必先利其器。在开始动手之前我们得先把需要的“食材”准备好并理解整个“烹饪”流程。整个搭建过程可以概括为三个核心步骤获取工具链、编译Qt库、配置Qt Creator。听起来简单但每一步都有不少细节。首先你需要一个Linux开发环境我使用的是Ubuntu 20.04 LTS其他如Ubuntu 18.04/22.04、Debian等主流发行版也大同小异。确保你的系统有足够的磁盘空间建议预留20GB以上因为编译Qt源码会占用不少空间。接下来是资源清单Qt安装包与源码我们需要两份东西。一是用于在开发机上运行Qt Creator的Qt安装程序比如qt-opensource-linux-x64-5.14.2.run它提供了IDE和本地编译工具。二是对应版本的Qt源码包qt-everywhere-src-5.14.2.tar.xz这是用来为ARM平台交叉编译出Qt运行库的原材料。ARM交叉编译工具链这是核心中的核心决定了最终生成程序能否在你的板子上运行。常见的提供商有ARM官方Arm GNU Toolchain、Linaro等。选择时一个关键原则是工具链的C库glibc版本不能高于你目标板系统上的版本。比如你的板子系统是Ubuntu 18.04glibc 2.27那么你最好选择glibc版本等于或低于2.27的工具链否则编译出的程序在板子上可能会因为找不到高版本的库符号而无法运行。你可以通过在板子上执行ldd --version来查看其glibc版本。为了方便大家这里提供一个清晰的资源下载对照表资源类型推荐来源关键选择依据本文示例Qt安装包 (x86_64)Qt官方存档目录选择对应版本的.run安装文件qt-opensource-linux-x64-5.14.2.runQt源码包Qt官方存档目录选择single目录下的tar.xz完整源码qt-everywhere-src-5.14.2.tar.xzARM交叉工具链ARM Developer或Linaro Releases匹配目标板架构aarch64/arm和glibc版本gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu.tar.xz准备好这些我们就可以进入实战环节了。3. 第一步安装Qt与交叉编译工具链3.1 安装桌面版Qt Creator首先我们把Qt开发环境装好。找到下载好的qt-opensource-linux-x64-5.14.2.run文件给它加上执行权限然后运行。# 进入下载目录 cd ~/Downloads # 添加执行权限 chmod x qt-opensource-linux-x64-5.14.2.run # 执行安装可能需要sudo权限 sudo ./qt-opensource-linux-x64-5.14.2.run安装过程是图形化的跟着向导走就行。安装时需要一个Qt账户如果没有可以去官网免费注册一个。在选择安装组件时至少确保勾选了Qt 5.14.2下的Desktop gcc 64-bit套件这是用于本地编译和运行Qt Creator的。其他如Android、源码等组件可以按需选择。安装路径我通常就用默认的/opt/Qt5.14.2这样比较清晰。安装完成后你可以通过/opt/Qt5.14.2/Tools/QtCreator/bin/qtcreator来启动Qt Creator。建议创建一个桌面快捷方式方便以后使用。3.2 部署ARM交叉编译工具链接下来处理交叉编译工具链。假设你下载的是Linaro的6.5.0版本文件是gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu.tar.xz。我习惯把这类工具链集中放在/opt目录下管理。# 创建工具链目录并解压 sudo mkdir -p /opt/toolchains sudo tar -xJf gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu.tar.xz -C /opt/toolchains/解压后工具链的完整路径就是/opt/toolchains/gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu。为了能在终端里直接使用这个工具链的命令比如aarch64-linux-gnu-gcc我们需要把它添加到系统的PATH环境变量中。这里要注意你的系统默认shell是什么。如果是bash就编辑~/.bashrc如果是zsh像我用的是Oh My Zsh就编辑~/.zshrc。# 使用你喜欢的编辑器比如nano或vim nano ~/.zshrc # 或者 nano ~/.bashrc在文件末尾添加以下行export PATH/opt/toolchains/gcc-linaro-6.5.0-2018.12-x86_64_aarch64-linux-gnu/bin:$PATH保存退出后执行source ~/.zshrc或source ~/.bashrc让配置立即生效。现在打开一个新终端输入aarch64-linux-gnu-gcc --version并回车如果能看到类似gcc version 6.5.0的输出恭喜你工具链已经就绪了。4. 第二步交叉编译Qt 5.14.2源码这是整个过程中最具挑战性但也最关键的一步。我们需要用刚刚配置好的ARM工具链把Qt庞大的源代码编译成ARM平台专用的库。4.1 解压与配置源码首先把下载的Qt源码包解压到一个合适的位置比如你的家目录下。tar -xJf qt-everywhere-src-5.14.2.tar.xz -C ~/ cd ~/qt-everywhere-src-5.14.2在编译之前强烈建议先安装一些编译所需的依赖库这能避免后续很多奇怪的错误。# 安装基础编译工具和库 sudo apt update sudo apt install build-essential libgl1-mesa-dev libxkbcommon-dev libnss3-dev libdbus-1-dev # 如果后续需要用到X11相关功能比如在板子上运行桌面程序还需要安装 sudo apt install ^libxcb.*-dev libx11-xcb-dev libxrender-dev libxi-dev现在进入正题执行configure脚本进行配置。这个命令参数很多我逐条解释一下./configure -release \ -static \ -opensource -confirm-license \ -prefix /opt/Qt5.14.2-arm \ -nomake tests -nomake examples \ -no-opengl \ -skip qtvirtualkeyboard \ -skip qtwebengine \ -platform linux-g \ -xplatform linux-aarch64-gnu-g-release编译发布版本体积小速度快。调试阶段可以用-debug但体积会大很多。-static编译成静态库。这是嵌入式开发中常见的选择最终生成的可执行文件会包含所有Qt库代码体积大但部署简单不依赖目标板上的Qt动态库。如果选择动态库-shared则需要在板子上也部署对应的.so文件。-opensource -confirm-license确认使用开源协议。-prefix /opt/Qt5.14.2-arm指定编译产出的安装路径。编译安装后所有的头文件、库文件都会放在这里。-nomake tests -nomake examples不编译测试和示例程序可以显著缩短编译时间。-no-opengl如果你的板子没有GPU或者不需要OpenGL加上这个可以避免相关依赖错误。-skip qtvirtualkeyboard -skip qtwebengine跳过虚拟键盘和WebEngine模块。这两个模块依赖复杂编译容易出错除非你的项目确实需要否则建议先跳过让首次编译成功率更高。-platform linux-g指定宿主机你的电脑的编译器配置。对于大多数Linux桌面就是linux-g。-xplatform linux-aarch64-gnu-g指定目标机ARM板的编译器配置。这是最关键的一步它告诉Qt构建系统使用我们为ARM准备的工具链。linux-aarch64-gnu-g对应一个特定的配置目录。4.2 处理平台配置与常见编译错误当你执行上面的configure命令后可能会遇到第一个拦路虎提示找不到linux-aarch64-gnu-g这个平台配置。这是因为Qt源码里默认没有这个配置。我们需要手动创建它。进入Qt源码的qtbase/mkspecs目录找一个最接近的配置来复制修改比如linux-arm-gnueabi-g。cd ~/qt-everywhere-src-5.14.2/qtbase/mkspecs cp -r linux-arm-gnueabi-g linux-aarch64-gnu-g cd linux-aarch64-gnu-g然后编辑这个新目录下的qmake.conf文件nano qmake.conf你需要修改关键的两行指向你的交叉编译工具链# 修改前可能是 #QMAKE_CC arm-linux-gnueabi-gcc #QMAKE_CXX arm-linux-gnueabi-g # 修改为使用你的工具链路径和前缀 QMAKE_CC aarch64-linux-gnu-gcc QMAKE_CXX aarch64-linux-gnu-g # 同样修改链接器和归档工具 QMAKE_LINK aarch64-linux-gnu-g QMAKE_LINK_SHLIB aarch64-linux-gnu-g QMAKE_AR aarch64-linux-gnu-ar cqs QMAKE_OBJCOPY aarch64-linux-gnu-objcopy QMAKE_NM aarch64-linux-gnu-nm -P QMAKE_STRIP aarch64-linux-gnu-strip # 修改目标平台标志 QMAKE_CFLAGS -marcharmv8-a QMAKE_CXXFLAGS -marcharmv8-a保存退出后回到源码根目录再次运行./configure ...命令。这次应该能顺利生成Makefile了。接下来就是漫长的编译过程使用make -j$(nproc)命令可以调用你电脑的所有核心来加速编译。比如8核电脑就用make -j8。这个过程可能会持续一两个小时取决于你的电脑性能。编译过程中很可能会遇到错误。我遇到过最常见的一个是“limits头文件找不到”。错误信息通常指向某个.cpp文件里缺少#include limits。解决方法很简单就是找到报错的文件在开头加上这行include。另一个常见错误是“Project ERROR: Unknown module(s) in QT: openglextensions”这通常是由qtquick3d模块引起的。如果你不需要3D功能回到配置步骤在configure命令里加上-skip qtquick3d重新配置并编译即可。4.3 安装编译成果当make命令最终成功完成屏幕上没有红色错误提示时就可以进行安装了sudo make install这会把编译好的所有ARM架构的Qt库、头文件、工具如qmake安装到之前-prefix指定的目录本例中是/opt/Qt5.14.2-arm下。至此专属于你目标板的Qt SDK就准备好了。5. 第三步在Qt Creator中配置交叉编译套件现在我们有了ARM的Qt库和工具链最后一步就是让Qt Creator认识它们并能够用它们来编译我们的项目。5.1 配置交叉编译工具链打开Qt Creator进入工具(Tools)-选项(Options)-Kits选项卡。首先我们需要在编译器(Compilers)页面添加我们的交叉编译器。点击添加(Add)-GCC-C。名称可以起一个易懂的比如“GCC 6.5.0 ARM aarch64”。在编译器路径(Compiler path)一栏点击浏览找到你的交叉编译工具链中的g。它的路径通常是/opt/toolchains/gcc-linaro-.../bin/aarch64-linux-gnu-g。用同样的方法再添加一个C编译器路径指向同目录下的aarch64-linux-gnu-gcc。5.2 配置Qt版本接下来切换到Qt版本(Qt Versions)页面。点击添加(Add)然后浏览到我们刚才编译安装的ARM版Qt目录下找到bin/qmake文件。它的完整路径是/opt/Qt5.14.2-arm/bin/qmake。选中它Qt Creator会自动检测出版本信息你给它起个名字比如“Qt 5.14.2 ARM Static”。5.3 组装成完整的构建套件最后来到构建套件(Kit)页面点击添加(Add)创建一个新套件。设备类型(Device type)选择“通用Linux设备”或“裸机设备”取决于你的板子。设备(Device)如果你配置了远程设备通过SSH连接板子可以在这里选择。初期测试可以先不选。编译器(C Compiler)选择你刚才添加的ARM C编译器。编译器(C Compiler)选择你刚才添加的ARM C编译器。调试器(Debugger)如果需要交叉调试需要额外配置gdb这里可以先选“系统GDB at ...”但注意它可能不适用ARM架构。交叉调试是另一个话题我们暂且跳过。Qt版本(Qt mkspec)这是最关键的一步点击下拉框选择我们刚才添加的“Qt 5.14.2 ARM Static”。Qt mkspec手动填入我们之前创建的配置目录名linux-aarch64-gnu-g。这告诉Qt Creator在构建时使用正确的平台配置。给这个套件起个名字比如“ARM aarch64 Qt5.14 Static”。配置完成后点击“Apply”保存。现在当你新建一个Qt项目或者在打开现有项目的构建设置时就可以在“Kit Selection”页面看到这个新添加的ARM套件了。选择它然后点击构建Qt Creator就会调用交叉编译工具链和ARM版的Qt库为你的目标板生成可执行文件。6. 验证与排错让你的程序在板子上跑起来配置好一切激动地点击构建生成了一个ARM可执行文件比如myapp。通过SCP或者U盘把它拷贝到你的开发板上。在板子的终端里先给它执行权限chmod x myapp然后尝试运行./myapp。你可能会遇到一些运行时错误别慌这很正常。最常见的是找不到动态库。如果你编译的是动态链接版本需要确保板子上有对应的Qt库或者把你编译的整个/opt/Qt5.14.2-arm/lib目录拷贝到板子的某个路径比如/usr/local/qt5.14并通过设置环境变量LD_LIBRARY_PATH来告诉系统去哪找export LD_LIBRARY_PATH/usr/local/qt5.14/lib:$LD_LIBRARY_PATH ./myapp另一个常见错误是关于图形显示后端的比如提示“Could not find the Qt platform plugin ‘xcb’”。这说明你的程序在板子上找不到合适的显示驱动。对于嵌入式设备通常使用eglfs或linuxfb后端。你可以通过设置环境变量来指定# 对于使用GPU的板子尝试eglfs export QT_QPA_PLATFORMeglfs # 或者使用最简单的framebuffer export QT_QPA_PLATFORMlinuxfb ./myapp如果程序还是崩溃可以使用ldd命令检查可执行文件的依赖是否都满足ldd myapp。看看有没有显示“not found”的库。在整个搭建和验证过程中耐心和仔细查看错误信息是最重要的。每次错误都是你更理解这套系统如何工作的机会。我当初也是经历了无数次“编译-报错-搜索-解决”的循环才最终让第一个“Hello ARM”窗口在板子上亮起来。当你看到自己开发的Qt应用在资源受限的嵌入式设备上流畅运行时那种成就感绝对值得之前的付出。希望这篇详细的指南能帮你少走弯路顺利搭起属于你自己的嵌入式Qt开发桥梁。