新闻详情

新闻详情

首页 / 资讯中心 / 详情

Qt 5.14.2 aarch64静态交叉编译实战:从环境搭建到Orange Pi CM5部署

发布时间:2026/9/20 8:54:36来源:尧图网络
Qt 5.14.2 aarch64静态交叉编译实战:从环境搭建到Orange Pi CM5部署
1. 为什么值得折腾 aarch64 静态交叉编译如果你手上有 Orange Pi CM5、树莓派这类 aarch64 开发板又想把 Qt 程序直接丢上去跑大概率绕不开“交叉编译”这四个字。而“静态”两个字意味着你编译出来的可执行文件不依赖目标板上的 Qt 动态库拷过去就能运行省去了在板子上装一堆.so的麻烦。Qt 5.14.2 这个版本在嵌入式圈子里口碑不错模块完整、bug 相对少配合 aarch64 静态交叉编译特别适合做工业 HMI、边缘计算终端、车载中控这类需要“一次编译、到处部署”的场景。我这次折腾的目标很明确在 x86_64 的 Ubuntu 开发机上用 aarch64 交叉工具链把 Qt 5.14.2 编译成静态库然后写一个简单的 Qt 程序静态链接后直接扔到 Orange Pi CM5 上跑起来。整个过程踩了不少坑从工具链选型、configure 参数、到 serialport 模块报错、字体渲染问题几乎每个环节都卡过。这篇手册就是把这些经验完整记录下来让你少走弯路。适合谁看如果你已经会用 Qt 写桌面程序但对交叉编译只有模糊概念这篇能帮你打通从“能编译”到“能跑在板子上”的最后一公里。如果你已经做过动态交叉编译想升级到静态方案这里关于 configure 参数和依赖处理的细节也能直接抄作业。全文基于我实际操作的记录所有命令和参数都经过验证你可以按步骤复现。2. 环境准备与工具链选型2.1 开发机环境确认我用的开发机是 Ubuntu 20.04 LTSx86_64 架构内存 16GB硬盘留了 100GB 给编译。Qt 源码编译很吃磁盘和内存尤其是静态编译中间文件体积会膨胀好几倍。如果你用虚拟机建议至少给 8GB 内存和 80GB 磁盘否则编译到一半空间不足会很尴尬。先确认基础工具齐全sudo apt update sudo apt install -y build-essential git perl python3 gcc g make \ libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev \ libx11-dev libxext-dev libxrender-dev libxcb1-dev \ libxkbcommon-dev libxkbcommon-x11-dev libfontconfig1-dev \ libfreetype6-dev libpng-dev libjpeg-dev libssl-dev这些依赖里libxcb系列和libxkbcommon是 Qt 在 Linux 上跑 GUI 的基础libfontconfig和libfreetype负责字体渲染libssl给网络模块用。静态编译时这些库会被链接进最终可执行文件所以开发机上必须装好。注意不要用apt install qt5-default这种方式装 Qt那是给桌面开发用的动态库跟我们要做的静态交叉编译完全是两码事。开发机上只需要装编译依赖不需要装 Qt 本身。2.2 aarch64 交叉工具链选择aarch64 交叉工具链有好几个来源我试过三种工具链来源优点缺点适用场景Linaro GCC稳定、社区支持好版本更新慢通用嵌入式ARM 官方 GNU Toolchain版本新、优化好下载慢、配置稍复杂需要新特性发行版自带 gcc-aarch64-linux-gnu安装方便版本可能较旧快速验证我最终选了 ARM 官方 GNU Toolchain 的 10.3-2021.10 版本原因是它对 aarch64 的浮点优化做得比较好而且自带的 sysroot 比较干净不会混入开发机的库。下载后解压到/opt目录sudo tar -xf gcc-arm-10.3-2021.10-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt export PATH/opt/gcc-arm-10.3-2021.10-x86_64-aarch64-none-linux-gnu/bin:$PATH验证工具链可用aarch64-none-linux-gnu-gcc --version aarch64-none-linux-gnu-g --version如果输出显示 GCC 10.3.1说明工具链就绪。这里有个细节工具链前缀是aarch64-none-linux-gnu-不是常见的aarch64-linux-gnu-后面写 configure 参数时要注意对应。实操心得工具链路径最好写进~/.bashrc否则每次开新终端都要重新 export。另外如果你同时装了多个工具链确保PATH里只有一个生效否则 configure 时可能找到错误的编译器。2.3 目标板 sysroot 准备静态编译虽然不依赖目标板的动态库但编译时仍然需要目标板的头文件和静态库比如 libc.a、libm.a。这些文件在工具链自带的 sysroot 里就有路径通常是/opt/gcc-arm-10.3-2021.10-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc你可以用--sysroot参数指定这个路径。如果目标板上有特殊的库比如硬件加速相关的需要把对应的头文件和静态库拷到 sysroot 里。我这次只用了 Qt 核心模块和 serialport没有额外依赖所以直接用工具链自带的 sysroot 就够了。3. Qt 5.14.2 源码获取与配置3.1 源码下载与目录规划Qt 5.14.2 的源码包可以从 Qt 官方下载站获取文件名是qt-everywhere-src-5.14.2.tar.xz大小约 500MB。下载后解压到一个独立目录我习惯放在~/qt-build下mkdir -p ~/qt-build cd ~/qt-build tar -xf qt-everywhere-src-5.14.2.tar.xz cd qt-everywhere-src-5.14.2目录规划很重要。我建议把源码目录、编译目录、安装目录分开源码~/qt-build/qt-everywhere-src-5.14.2编译~/qt-build/build-aarch64-static安装~/qt-build/install-aarch64-static这样做的原因是 Qt 不支持在源码目录里直接编译in-source build必须用 shadow build。分开后如果编译失败要重新来直接删掉编译目录就行不用重新解压源码。3.2 configure 参数逐项拆解Qt 的 configure 脚本参数非常多静态交叉编译的关键参数我逐个解释../qt-everywhere-src-5.14.2/configure \ -prefix /home/user/qt-build/install-aarch64-static \ -opensource -confirm-license \ -release \ -static \ -nomake examples -nomake tests \ -no-opengl \ -no-xcb \ -no-eglfs \ -linuxfb \ -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype \ -qt-pcre \ -no-feature-sql \ -skip qtwebengine \ -skip qtdeclarative \ -xplatform linux-aarch64-gnu-g \ -sysroot /opt/gcc-arm-10.3-2021.10-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc逐项说明-prefix安装路径编译完成后make install会装到这里。-opensource -confirm-license使用开源协议自动确认许可。-release发布版编译不开调试符号体积更小。-static静态编译这是核心。-nomake examples -nomake tests不编译示例和测试节省大量时间。-no-opengl目标板没有 GPU不需要 OpenGL。-no-xcb不用 X11 后端嵌入式用 framebuffer。-linuxfb启用 Linux framebuffer 后端直接写/dev/fb0。-qt-zlib -qt-libpng -qt-libjpeg -qt-freetype使用 Qt 自带的第三方库避免依赖开发机的动态库。-qt-pcre使用 Qt 自带的正则库。-no-feature-sql不需要数据库模块减小体积。-skip qtwebengineWebEngine 编译极其耗时且依赖复杂直接跳过。-skip qtdeclarative不需要 QML跳过。-xplatform linux-aarch64-gnu-g指定目标平台配置文件。-sysroot指定目标板 sysroot。注意-no-xcb和-linuxfb要配合使用。如果你只写-no-xcb不写-linuxfbQt 可能找不到任何可用的显示后端编译出来的程序跑起来会报“could not find a suitable platform plugin”。3.3 自定义 qmake.conf 与 mkspec-xplatform linux-aarch64-gnu-g这个参数要求 Qt 源码里存在对应的 mkspec 目录。Qt 5.14.2 自带linux-aarch64-gnu-g这个 spec但默认的编译器前缀可能跟我们的工具链不一致。需要检查并修改cd ~/qt-build/qt-everywhere-src-5.14.2/qtbase/mkspecs/linux-aarch64-gnu-g cat qmake.conf如果里面的QMAKE_CC是aarch64-linux-gnu-gcc而我们的工具链是aarch64-none-linux-gnu-gcc就需要改。我直接新建了一个 spec 目录linux-aarch64-none-gnu-g复制原文件后修改cp -r linux-aarch64-gnu-g linux-aarch64-none-gnu-g cd linux-aarch64-none-gnu-g sed -i s/aarch64-linux-gnu-/aarch64-none-linux-gnu-/g qmake.conf然后 configure 时用-xplatform linux-aarch64-none-gnu-g。这样做的原因是避免污染 Qt 自带的 spec以后升级源码时不会冲突。qmake.conf 的关键内容应该是这样的QMAKE_CC aarch64-none-linux-gnu-gcc QMAKE_CXX aarch64-none-linux-gnu-g QMAKE_LINK aarch64-none-linux-gnu-g QMAKE_AR aarch64-none-linux-gnu-ar cqs QMAKE_OBJCOPY aarch64-none-linux-gnu-objcopy QMAKE_STRIP aarch64-none-linux-gnu-strip这些变量决定了 qmake 生成 Makefile 时用哪个编译器。如果这里写错编译到一半会报“command not found”。4. 编译过程与核心环节实现4.1 执行 configure 与常见报错处理在编译目录里执行 configuremkdir -p ~/qt-build/build-aarch64-static cd ~/qt-build/build-aarch64-static ../qt-everywhere-src-5.14.2/configure [上述参数]configure 过程大约 2-5 分钟会检查各种依赖。常见的报错和处理方法报错一ERROR: Feature xcb was enabled, but the pre-condition features.thread libs.xcb failed.这是因为没加-no-xcb。加上后重新 configure。报错二ERROR: Cannot find libssl如果不需要网络模块的 SSL 功能加-no-openssl。如果需要确保开发机装了libssl-dev并且 sysroot 里有对应的 aarch64 静态库。报错三Project ERROR: Unknown module(s) in QT: serialport这个报错通常出现在编译应用程序时不是 configure 阶段。原因是 Qt 的 serialport 模块默认不编译需要显式启用。在 configure 参数里加-qt-serialport或者在 qtbase 的 configure 里确保 serialport 被包含。Qt 5.14.2 的 serialport 在qtserialport子模块里configure 时默认会编译但如果用了-skip参数误跳过了就会报这个错。实操心得configure 完成后仔细看输出的 summary。里面会列出哪些模块被启用、哪些被跳过。如果发现 serialport 显示为“no”就要检查是不是被 skip 了。我第一次编译时因为加了-skip qtconnectivity结果 serialport 也被连带跳过了后来去掉这个参数才正常。4.2 make 编译与并行度设置configure 成功后执行 makemake -j$(nproc)-j$(nproc)表示用所有 CPU 核心并行编译。我的开发机 8 核编译 Qt 5.14.2 静态库大约花了 40 分钟。如果内存不足 8GB建议-j4否则可能因为内存耗尽导致编译进程被 kill。编译过程中可能遇到的错误错误一fatal error: bits/libc-header-start.h: No such file or directory这是 sysroot 路径不对或者工具链的 sysroot 里缺少头文件。检查-sysroot参数是否指向了正确的目录确保该目录下有usr/include。错误二undefined reference to pthread_create静态链接时 pthread 需要显式链接。在 qmake.conf 里加QMAKE_LFLAGS -lpthread或者在应用程序的 .pro 文件里加LIBS -lpthread。错误三编译到 qtdeclarative 时内存不足如果没加-skip qtdeclarativeQML 模块编译会消耗大量内存。加上 skip 参数即可。编译完成后执行安装make install安装目录下会生成bin/qmake、lib/libQt5Core.a等文件。验证 qmake~/qt-build/install-aarch64-static/bin/qmake -v应该输出QMake version 3.1和Using Qt version 5.14.2。4.3 编写测试程序并静态链接写一个最简单的 Qt 程序验证静态编译是否成功// main.cpp #include QCoreApplication #include QDebug #include QSerialPort int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); qDebug() Qt static cross compile test; qDebug() Serial port available: QSerialPortInfo::availablePorts().size(); return 0; }.pro 文件QT core serialport QT - gui CONFIG console CONFIG - app_bundle TARGET static_test SOURCES main.cpp用交叉编译的 qmake 生成 Makefile~/qt-build/install-aarch64-static/bin/qmake static_test.pro make编译完成后用file命令检查可执行文件file static_test输出应该是ELF 64-bit LSB executable, ARM aarch64, statically linked。如果是dynamically linked说明静态链接没生效检查 .pro 里是否漏了CONFIG static或者 qmake 是否用错了版本。把static_test拷到 Orange Pi CM5 上直接运行./static_test如果输出Qt static cross compile test和串口数量说明整个流程打通了。5. 常见问题与排查技巧实录5.1 serialport 模块报错深度排查“Unknown module(s) in QT: serialport” 这个报错在交叉编译里出现频率极高。根本原因通常是 Qt 编译时没有生成 serialport 的静态库和 qmake 配置文件。排查步骤检查安装目录下是否有lib/libQt5SerialPort.als ~/qt-build/install-aarch64-static/lib/ | grep SerialPort检查 qmake 的 mkspecs 目录下是否有 serialport 的 pri 文件ls ~/qt-build/install-aarch64-static/mkspecs/modules/ | grep serialport如果文件缺失回到 configure 阶段确认没有加-skip qtserialport并且-no-feature-serialport没有被误加。如果文件存在但 qmake 仍报错检查 .pro 里的QT serialport是否写对以及 qmake 是否指向了正确的安装目录。避坑技巧Qt 5.14.2 的 serialport 模块依赖libudev。如果目标板没有 udev编译时可能报错。可以在 configure 时加-no-feature-udev让 serialport 用内置的枚举方式。但这样在板子上可能无法自动发现串口需要手动指定设备路径。5.2 字体渲染与中文显示问题静态编译后程序在板子上跑起来如果显示中文变成方块说明字体没被正确打包。Qt 静态编译默认不包含字体文件需要手动把字体编译进资源或者放到板子的字体目录。方法一把字体文件放到板子的/usr/share/fonts下程序启动时用QFontDatabase::addApplicationFont加载。方法二用 Qt 的资源系统把字体嵌进可执行文件RESOURCES fonts.qrcfonts.qrc 内容RCC qresource prefix/fonts fileNotoSansCJK-Regular.ttc/file /qresource /RCC然后在 main 函数里加载int fontId QFontDatabase::addApplicationFont(:/fonts/NotoSansCJK-Regular.ttc); QStringList fontFamilies QFontDatabase::applicationFontFamilies(fontId); if (!fontFamilies.isEmpty()) { QFont font(fontFamilies.at(0)); app.setFont(font); }实操心得NotoSansCJK 字体文件大约 20MB嵌进可执行文件会让体积明显增大。如果板子存储紧张建议用方法一把字体单独放到板子上。另外静态编译的 Qt 默认字体引擎是 freetype确保 configure 时加了-qt-freetype。5.3 静态链接体积优化与 strip静态编译的 Qt 程序体积通常很大一个简单的 GUI 程序可能 30MB 起步。优化方法编译时加-release和-OsQMAKE_CXXFLAGS -Os QMAKE_LFLAGS -Wl,--gc-sections编译完成后用 strip 去掉符号表aarch64-none-linux-gnu-strip static_test用-no-feature-*关掉不需要的模块比如-no-feature-sql、-no-feature-network如果不用网络。我实测一个带 GUI 和 serialport 的程序strip 前 45MBstrip 后 12MB效果很明显。5.4 常见问题速查表问题现象可能原因解决方法configure 报 xcb 错误没禁用 xcb加-no-xcb编译报 pthread 未定义静态链接缺 pthread加-lpthread程序运行报找不到平台插件没启用 linuxfb加-linuxfbserialport 模块找不到模块被 skip去掉-skip qtserialport中文显示方块字体未加载嵌入字体或放到板子字体目录可执行文件体积过大未 strip用aarch64-none-linux-gnu-strip运行时报 GLIBC 版本不匹配工具链 sysroot 版本高于板子换用与板子 glibc 版本匹配的工具链6. 部署与运行验证6.1 拷贝到 Orange Pi CM5 并运行把编译好的可执行文件通过 scp 或 U 盘拷到板子上scp static_test user192.168.1.100:/home/user/在板子上运行chmod x static_test ./static_test如果程序有 GUI需要确保板子的 framebuffer 可用ls /dev/fb0如果/dev/fb0不存在可能需要配置内核的 framebuffer 驱动。Orange Pi CM5 默认的 Ubuntu 镜像通常已经启用了 framebuffer。运行 GUI 程序时指定平台插件./static_test -platform linuxfb如果报“Failed to open framebuffer device”检查/dev/fb0权限可能需要用 root 运行或者把用户加入video组。6.2 验证静态链接是否彻底用ldd检查可执行文件ldd static_test如果输出not a dynamic executable说明静态链接彻底不依赖任何动态库。如果输出一堆.so说明还有动态依赖需要检查 .pro 里是否漏了CONFIG static或者 Qt 本身编译时没加-static。注意即使 Qt 是静态编译的如果程序里用了dlopen或者某些第三方库是动态的最终可执行文件仍可能有动态依赖。用readelf -d static_test查看NEEDED条目如果为空就是纯静态。6.3 在板子上跑一个带界面的例子写一个简单的窗口程序验证 GUI 和 serialport 都能用#include QApplication #include QLabel #include QSerialPortInfo #include QVBoxLayout #include QWidget int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; QVBoxLayout *layout new QVBoxLayout(window); QLabel *label new QLabel(Qt 5.14.2 aarch64 static); layout-addWidget(label); QString ports; for (const auto info : QSerialPortInfo::availablePorts()) { ports info.portName() ; } QLabel *portLabel new QLabel(Serial ports: ports); layout-addWidget(portLabel); window.resize(400, 200); window.show(); return app.exec(); }编译后拷到板子上用-platform linuxfb运行应该能看到窗口和串口列表。如果窗口显示正常串口列表也能列出/dev/ttyS*说明整个静态交叉编译流程完全打通。7. 我踩过的坑与最后几条建议第一个坑是工具链前缀。我一开始用了发行版的gcc-aarch64-linux-gnu结果编译出来的程序在板子上跑时报GLIBC_2.29 not found因为开发机的 glibc 版本比板子高。换成 ARM 官方工具链后问题解决。所以工具链的 glibc 版本一定要跟目标板匹配最好用aarch64-none-linux-gnu-gcc -print-sysroot确认 sysroot 里的 glibc 版本。第二个坑是 configure 参数里的-no-xcb和-linuxfb必须同时出现。我试过只加-no-xcb结果 Qt 编译时找不到任何显示后端程序跑起来直接报“This application failed to start because no Qt platform plugin could be initialized”。加上-linuxfb后正常。第三个坑是 serialport 模块的 udev 依赖。Orange Pi CM5 的 Ubuntu 镜像默认有 udev所以没遇到问题。但如果你用的板子没有 udev编译 serialport 时会报错需要在 configure 时加-no-feature-udev。最后分享一个小技巧编译 Qt 静态库时可以用ccache加速。安装ccache后在 qmake.conf 里把QMAKE_CC和QMAKE_CXX前面加上ccache第二次编译时速度能快一倍以上。对于需要反复调整 configure 参数的场景这个技巧能省不少时间。这个方案后续还可以扩展比如把编译好的 Qt 静态库打包成 Docker 镜像团队里其他人直接拉镜像就能用不用每个人都折腾一遍工具链。或者写一个 CMake 工具链文件把交叉编译配置标准化配合 CLion 或 VS Code 做远程开发。这些等我下次折腾完再分享。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

携程酒店评论情感分析全流程实践 2026/9/20 9:51:45

携程酒店评论情感分析全流程实践

简介:本资源是一套面向Python初学者与数据分析课程设计者的完整实战项目,聚焦携程酒店评论数据的采集、清洗、情感分析与可视化全流程。适用于期末大作业、课程设计及数据分析入门实践,代码含详细注释,部署简单,新手可…

阅读更多 →
基于LSTM的比特币与黄金双资产综合决策模型 2026/9/20 9:51:45

基于LSTM的比特币与黄金双资产综合决策模型

简介:一套基于LSTM预测比特币和黄金价格走势的综合决策模型项目,源码、数据与项目说明齐备。项目出自大三课程作业,经导师指导评审获得99分,代码完整可运行,面对计算机相关专业毕设、课程设计和期末大作业场景均适用&a…

阅读更多 →
Atlas 300V 24G实战:从零部署YOLO目标检测全指南 2026/9/20 9:51:45

Atlas 300V 24G实战:从零部署YOLO目标检测全指南

1. Atlas 300V 24G到底是什么,为什么要拿它跑YOLO1.1 一张卡的本质:它不是GPU,但也不是“孬货”先回答很多人在搜的问题:atlas 300v 24g 是运算加速卡吗?是,而且是一张专门为AI推理设计的运算加速卡。它核心…

阅读更多 →
Atlas 300V 24G部署YOLO实战:从模型转换到多路视频推理 2026/9/20 9:51:45

Atlas 300V 24G部署YOLO实战:从模型转换到多路视频推理

1. 从“atlas”这个关键词说起:它到底指什么第一次看到“atlas”这个词,很多人脑子里蹦出来的可能是地图册,或者希腊神话里扛着地球的泰坦神。但在技术圈子里,尤其是最近这段时间,“atlas”几乎只有一个指向——华为昇…

阅读更多 →
Roc 字符串插值中的多行格式化:从快照测试透视编译流水线(templating 触发而非多行字符串字面量) 2026/9/20 9:51:45

Roc 字符串插值中的多行格式化:从快照测试透视编译流水线(templating 触发而非多行字符串字面量)

【免费下载链接】roc A fast, friendly, functional language. 项目地址: https://gitcode.com/GitHub_Trending/ro/roc 点击查看 免费下载 本文以 Roc 编译器的快照测试文件 string_multiline_formatting_(due_to_templating_not_multiline_string_literal)_1.md …

阅读更多 →
C++低延迟量化交易系统全链路设计解析 2026/9/20 9:48:45

C++低延迟量化交易系统全链路设计解析

简介:这是一套面向量化交易开发者与C高性能系统实践者的开源项目,聚焦于低延迟交易场景下的策略执行优化。针对Java版NFD2.0在行情响应与订单抢跑中遇到的性能瓶颈,作者重构为C实现的NFD3.0量化交易系统,显著提升核心路径处理速度…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞