ARM64麒麟V10上编译Qt 5.12.10:从configure到避坑指南

发布时间:2026/10/15 21:16:59
ARM64麒麟V10上编译Qt 5.12.10:从configure到避坑指南
简介面向ARM64架构的麒麟桌面操作系统Kylin-Desktop-V10-GFB-Release-020-ARM64提供一份已编译完成的Qt 5.12.10运行库及配套开发头文件包适用于昭阳N4720Z等联想设备可直接用于QT Creator构建套件配置。压缩包为gzip格式共收录2000个头文件.h涵盖QOpenGL、QLocale、QUrl等Qt核心与扩展模块整包约84.62MB解压后即可在/opt/qt5.12.10等目录下引用。该版本为作者亲测可用的Lenovo定制版免去源码编译及依赖配置的繁琐环节已有1070人学习下载。读者可快速获得一套适配国产化ARM平台的Qt环境同时通过头文件了解Qt内部接口结构适合在麒麟系统上从事Linux应用开发、国产化迁移或嵌入式界面调试的工程师。1. 在 ARM64 机器上重编 Qt 5.12.10先回答自己三个问题拿到 Kylin-Desktop-V10-GFB-Release-020 这个 ARM64 镜像时我先做的事不是写业务代码而是把系统自带的 Qt 环境整个摸了一遍。很多整机出厂镜像里的 Qt 是按预装应用定制的不会考虑你后续工程要什么版本可能不是 5.12.10编译选项可能不开 xcb甚至qmake都只暴露在某个隐藏目录里。客户端程序一启动就报 xcb 插件异常与其绕路去找不知道有没有的安装包不如直接在设备上把 Qt 5.12.10 编译完成做成一个干净的定制版本基线。这里要给的不只是一个 configure 命令而是一条能照着跑完的路径本机编译、依赖准备、关键参数取舍、问题排查。目标很简单两小时内让/opt/Qt5.12.10/bin/qmake -v明确输出 5.12.10并且用它构建的图形程序能正常弹出窗口。适合刚拿到 ARM64 麒麟 V10 设备、需要在上面做 Qt 开发的工程师对交叉编译有经验但想快速出基线的人可以直接跳到第 3 章抄参数再回头来看环境。2. 编译前的环境准备目标机检查、依赖安装与源码落位2.1 先分清本机编译和交叉编译两种路线怎么选我一般会先问一个问题编译机和目标机是不是同一台。如果你手里就是那台麒麟 V10 ARM64 整机本机编译永远是最稳的路线。头文件直接从/usr/include找链接器直接链接目标系统的 glibc不用维护 sysroot也不用担心编译出来的 Qt 在一个兼容性差的库环境下跑不起来。在设备上先把家底查清楚执行下面几条命令uname -m cat /etc/os-release gcc --version | head -n1 perl -v | head -n2 free -h df -h /opt输出里uname -m应该是aarch64gcc至少能看到 9 或者更高版本perl必须存在因为 Qt 5.12 的 configure 脚本依赖 perl。free -h主要看内存是不是 8G 以上后面make -j的并行度要按它来定。df -h /opt是确认编译过程有 30G 以上的空间整个 Qt 全模块编下来中间产物比你想的大得多。有些团队会选择交叉编译在 x86 CI 集群上配置 aarch64 交叉工具链再挂一个 sysroot好处是编译速度快、不占设备资源。但代价是你需要手动维护 sysroot把目标机上的头文件和库按目录复制出来还要处理-sysroot参数。对我这种只需要一版 Qt 基线的情况本机编译的失败成本更低排查起来也更直观。所以后面所有步骤都以本机编译为前提如果你确实要走交叉编译configure 参数差别不大但依赖检查这一节就不能照抄了。2.2 目标机一套 apt 命令装齐的依赖清单麒麟 V10 桌面版通常是 apt 系跟 Debian/Ubuntu 的包管理习惯一致。有些精简镜像连build-essential都没装不要直接跳到 configure先补齐编译链。下面是我在这类镜像上装依赖时用的命令sudo apt update sudo apt install -y build-essential perl python \ libgl1-mesa-dev libx11-dev libxext-dev \ libxcb1-dev libxcb-util-dev libxcb-xinerama0-dev \ libxcb-icccm4-dev libxcb-keysyms1-dev libxcb-image0-dev \ libxcb-randr0-dev libxcb-shape0-dev libxcb-glx0-dev \ libxcb-xfixes0-dev libxcb-sync-dev libxcb-xkb-dev \ libxcb-cursor-dev libxkbcommon-x11-dev libgtk-3-devbuild-essential提供 gcc、g、make是最底层的编译工具链perl和python是 Qt configure 与构建脚本的解释器依赖少任何一个都可能在中途爆出奇怪错误。libgl1-mesa-dev提供 OpenGL 头文件Qt GUI 模块编译时可能用得到如果后面打算用-no-opengl这一项可以省但装了没有坏处。libxcb 系列是 xcb 平台插件编译期的开发包其中libxcb-util-dev、libxcb-image0-dev这种经常被漏掉。漏掉之后 configure 阶段看不出问题等到编译qtbase的 xcb plugin 时才会报头文件缺失那时候再回头补包很浪费时间。libgtk-3-dev对应-gtk平台主题如果你想让 Qt 应用的菜单和对话框跟随麒麟桌面风格这个包必须装。若你遇到的是 yum 系的 V10 服务器版本把apt install换成yum install包名基本能对上个别找不到的用yum search libxcb反查。2.3 源码版本选择与解压落位源码不需要特别渠道Qt 官方归档目录里有qt-everywhere-src-5.12.10的打包文件认准版本号和 opensource 字样就可以。下载完成后解压到/opt/src组织方式建议固定下来方便以后查日志、复现构建sudo mkdir -p /opt/src cd /opt/src sudo tar xf qt-everywhere-src-5.12.10.tar.xz cd qt-everywhere-src-5.12.10 ls qtbase/mkspecs/ | grep aarch64最后一条命令是为了确认 Qt 5.12.10 自带的 mkspec 里有linux-aarch64-gnu-g这个目录。看到它后面 configure 的-platform参数才有对应项。如果因为某种原因你这个源码包里缺少 aarch64 的 mkspec不要硬编补齐源码再来否则 configure 第一阶段就会失败。解压之后我还有一个习惯把源码目录的属主改成当前用户而不是用 root 去 configure。Qt 编译过程中会写一些临时文件到源码目录里用普通用户跑能避免后期忘了文件权限。执行sudo chown -R $USER:$USER /opt/src/qt-everywhere-src-5.12.10即可。这个细节不影响编译结果但能减少后续清理或补编时的权限报错。3. configure 配置ARM64 的 mkspec、xcb 与 OpenGL 怎么一次定对3.1 一份够用的 configure 命令与参数拆解configure 是整条链路里最值得抠的一步参数定了后面几乎没有回头路。我在 ARM64 麒麟 V10 上编 Qt 5.12.10 时用的是一套组合拳先贴出来再逐个解释cd /opt/src/qt-everywhere-src-5.12.10 ./configure \ -prefix /opt/Qt5.12.10 \ -opensource -confirm-license \ -release \ -platform linux-aarch64-gnu-g \ -xcb \ -gtk \ -opengl es2 \ -no-use-gold-linker \ -skip qtwebengine \ -skip qt3d \ -nomake examples -nomake tests-prefix /opt/Qt5.12.10决定最终安装路径后续 qmake、头文件、插件都会装到这里建议改名的项目统一用这个前缀。-opensource -confirm-license表示使用开源协议并直接确认许可避免 configure 停在交互界面。-release只构建 release 版本调试符号不生成体积和性能都更友好。-platform linux-aarch64-gnu-g是最关键的一项它告诉 Qt 构建系统使用 aarch64 的 mkspec。ARM64 机器上绝不能用linux-g那是 x86 平台的默认项用了之后 configure 能过但编译出的 Qt 库运行时行为无法保证。-xcb打开 X11 下的 xcb 平台插件这是麒麟 V10 桌面上 Qt 图形程序最常走的路径。-gtk启用 GTK 平台主题让 Qt 控件在系统主题下看起来不那么突兀。-opengl es2选 OpenGL ES 2.0这是 ARM 设备上 GPU 驱动最常见的实现。很多整机用的 Mali、Adreno 系列 GPU 对 desktop OpenGL 支持一般但 ES 2.0 几乎不会缺驱动。设备完全没 GPU 时后面我可以改成-no-opengl。-no-use-gold-linker是为了躲开老编译器配 gold 链接器的各种奇怪问题有些 ARM 设备上 gold 链接直接卡死纯属玄学关掉最省心。最后两个-skip qtwebengine -skip qt3d是为了剪掉重模块qtwebengine 内部等于一个 Chromium会吃掉大量时间和内存。3.2 三个关键开关的取舍表xcb / opengl / skip不同场景下同一组参数要微调这里给一张我常用的取舍表照着改即可。表格里的改动会直接影响运行效果不要随意组合参数默认取值什么情况要改改了会有什么后果-opengl es2保持 es2无 GPU 或只要软渲染改成-no-openglGUI 走软件渲染性能明显下降-gtk启用不关心系统主题一致性去掉后少一个平台主题插件程序外观由 Qt 样式决定-skip qtwebengine跳过应用依赖 WebEngine 展示网页不跳过的话编译时长成倍增加内存峰值显著变大-skip qt3d跳过应用确实用到 Qt 3D 模块不跳过时增加 OpenGL ES 相关编译复杂度-nomake examples -nomake tests保留调试期想用官方示例验证去掉会让构建产物变大但方便验证模块功能如果你做的是纯控制台程序一个QCoreApplication就能跑那-xcb -gtk -opengl es2都可以去掉只要 QtCore 和 QtNetwork 等模块configure 会快很多。反过来如果你的应用依赖 Qt Charts、Qt Data Visualization 这类模块不要盲目 skip去查一下模块列表再做决定。3.3 configure 结果怎么看xcb 显示 no 怎么办configure 跑完后控制台会输出一个摘要列出Xcb: yes/no、OpenGL: es2这类信息。我每次都会先把输出存成日志防止关键行被终端滚动冲掉./configure ... 21 | tee config.log grep -n -i xcb config.log | head -n 30grep xcb是重点。如果看到xcb ......... no说明前面依赖没装齐后面就算 make 成功编出来的 Qt 也没有 xcb 平台插件。此时回到第 2.2 节把 libxcb 系列补上然后执行make distclean清掉 configure 缓存再重新 configure。直接重跑 configure 有时不会重新检测已失败的项这个坑我在早期踩过现在一律先 clean 再 config。另外configure 阶段报错信息大多直接打印在终端末尾。最常见的提示是缺少某个开发包纠错方法就是看它提示的.h头文件反查它属于哪个包。举例来说如果提示X11/Xinput2.h那就是libxi-dev没装。这类小依赖比较琐碎但没有捷径一个一个补齐比用-skip绕开更实际。4. 编译与安装并行度、输出目录、环境变量一次收尾4.1 make 并行度与内存边界别让 OOM 杀进程configure 通过之后直接进入漫长的 make 阶段。这里最需要控制的是并行度而不是时间。make -j$(nproc)看起来是自动适配核数但 ARM 整机经常是 8 核 8G 内存的组合全核并行后内存瞬间见底编译进程会被内核杀掉报出很吓人的Killed状态。我在编译前会先看两个数核数和内存nproc free -h make -j4 21 | tee build.log内存 8G 左右用-j416G 以上可以用-j6超过 16G 且核数很多才建议-j8。不要把-j拉满。Qt 编译过程中每一个编译单元都对应一个 g 进程每个进程吃几百 MB 内存是常态。并行度设置过度导致 OOM 时浪费的不只是时间还有排查问题的精力。make 阶段日志会非常长用tee同时输出到终端和build.log。如果中途失败先看build.log尾部定位第一个Error出现的位置而不是从中间乱找。make 本身支持断点续编修复依赖问题后重新执行同样的 make 命令会跳过已编译完的目标不用从零再来。4.2 make install 之后的目录验证编译完成后再执行安装所有 build 产物会落到 configure 指定的前缀目录。因为没有往系统/usr/lib里塞任何东西所以对系统自带 Qt 环境是零侵入这也是我坚持用/opt/Qt5.12.10的原因之一sudo make install du -sh /opt/Qt5.12.10 ls -l /opt/Qt5.12.10/bin/qmake ls /opt/Qt5.12.10/lib/cmake | head -n 20make install需要 root 权限因为-prefix是/opt下的目录。装完之后第一眼看du -sh整个 Qt 5.12.10 安装目录通常在 500M 到 1G 之间具体取决于你保留了哪些模块。lib/cmake目录很关键它是 CMake 工程里find_package(Qt5)的搜索位置之一如果这里缺失后面用 CMake 构建第三方库时会找不到 Qt。业界常用做法是同时检查bin/qmake的版本输出。执行/opt/Qt5.12.10/bin/qmake -v如果看到Using Qt version 5.12.10 in /opt/Qt5.12.10/lib这样的字符串就说明安装路径里的 qmake 和库目录对上了。我见过有人只在 PATH 里改了 qmake但库还是指向系统旧版本运行时版本错乱这种问题最隐蔽。4.3 环境变量配置项目构建期与运行期各一套环境变量要分两个场景配置。构建期只需要PATH指向新 qmake让工程用对编译工具运行期需要LD_LIBRARY_PATH和QT_PLUGIN_PATH让程序加载对版本的库和插件。我一般会加一个/etc/profile.d/qt512.sh内容如下export QTDIR/opt/Qt5.12.10 export PATH$QTDIR/bin:$PATH export LD_LIBRARY_PATH$QTDIR/lib:$LD_LIBRARY_PATH export QT_PLUGIN_PATH$QTDIR/plugins写完之后source /etc/profile.d/qt512.sh或重新登录生效。注意不要把QT_PLUGIN_PATH误写成编译期变量它只在运行期生效。如果程序自己用QCoreApplication::addLibraryPath指定了插件路径那么以程序内为准外部变量只是兜底。这条路径设计成只对当前登录用户生效也可以关键点是不要污染系统自带的 Qt。有些整机出厂镜像里已经装了另一个 Qt 版本你把新 Qt 的库目录加进LD_LIBRARY_PATH后系统自带的一些 Qt 小程序可能会受影响。遇到这种情况我会把/etc/profile.d/qt512.sh里的变量拆到项目自己的构建脚本里让它们只在需要时存在。5. 避坑ARM64 麒麟 V10 上 Qt 5.12.10 编译的常见问题排查5.1 configure 阶段直接报 not supported现象很明显configure 刚开始运行就弹出ERROR: The specified system/compiler is not supported或Unknown platform。很多人在这一步以为源码问题其实多半是-platform参数写错了。有些教程习惯性写了linux-g那对应的是 x86 架构在 ARM64 上当然不被支持。原因有两个层面第一是 mkspec 名不正确第二是 gcc 版本太低。Qt 5.12.10 要求 gcc 至少 5.0 以上但旧一点的 V10 镜像如果长期没更新编译器可能停留在 4.8 时代。处理办法是先把编译器版本确认清楚再指定正确的 mkspecgcc --version | head -n1 ls /opt/src/qt-everywhere-src-5.12.10/qtbase/mkspecs/如果 gcc 版本过低先升级build-essential到当前系统可用的最新版本如果 gcc 版本没问题就把 configure 参数改成-platform linux-aarch64-gnu-g再试。还有一种少见情况是源码包被裁剪过qtbase/mkspecs下根本没有 aarch64 对应目录那就只能重新获取完整源码包不要自己手写 mkspec。5.2 编译中报 GL/gl.h、X11 头文件缺失编译进入qtbase的 GUI 模块时经常冒出fatal error: GL/gl.h: No such file or directory或者X11/Xlib.h找不到。这个错不在 Qt 本身而是系统缺少开发头文件。没有这些头文件Qt 只能靠猜来配置图形栈猜不中就报错。先做一件事确认 configure 时的 OpenGL 选项是什么。如果设备没有 GPU直接用-no-opengl反而省事如果设备有 GPU 需要跑图形界面那就老老实实补依赖sudo apt install -y libgl1-mesa-dev libx11-dev libxext-dev make distclean ./configure ... -opengl es2 ...补充依赖后必须make distclean再重新 configure。我见过有人直接重跑配置结果旧缓存里仍然记录着缺少头文件白折腾一轮。还有一种情况是头文件存在但路径不被默认搜索比如安装在/usr/include/glib-2.0这种非标准路径此时可以在环境变量CPATH或CFLAGS里补路径但非常少见。5.3 最后编译 xcb 插件时报 xcb 头文件缺失这种情况和 5.2 类似但专属于 xcb 系列。configure 摘要里可能显示xcb: yes真到编译 xcb 插件的时候却报xcb/xcb.h: No such file or directory或者找不到QtXcbQpa相关的内部头文件。原因是 5.2 那种全局头文件错误会让 configure 直接失败但 xcb 系列依赖缺失时 configure 可能打桩成部分支持编译才爆出来。我的排查顺序是先确认 xcb 依赖能不能被 pkg-config 找到pkg-config --exists xcb echo xcb-ok pkg-config --modversion xcb如果第二条没有输出说明libxcb1-dev没装回到 2.2 的安装清单补齐。重点检查libxcb-util-dev、libxcb-image0-dev、libxcb-xinerama0-dev这几个容易漏的包。装完之后依然建议make distclean否则旧 configure 缓存里 xcb 相关检测结果还是错的。清洗后重新 configure摘要里看到xcb: yes再继续 make。5.4 collect2: fatal error: ld terminated with signal 9这个错误出现时编译前端已经成功是链接阶段内存不足被系统杀掉。信号 9 是 SIGKILL多半是 Linux OOM killer 动手了。典型的场景是make -j8同时链接多个大模块内存峰值冲满进程瞬间消失。终端最后几行往往是collect2: fatal error: ld terminated with signal 9 [Killed]。不要急着改代码或换编译器先看当前内存和系统日志free -h dmesg | tail -n 20 make -j2 21 | tee build.logdmesg里能看到被杀的 g 或 ld 进程记录。处理办法就是降并行度make -j2是最稳的兜底。如果机器内存确实小还可以临时加上 swap 再编译但 swap 对速度影响很大只适合救急。编译完成之后建议把-j参数记进构建脚本避免后面增量编译时再触发同样的问题。5.5 运行程序提示找不到 xcb 平台插件编译安装都顺利结束但用新 qmake 构建出来的程序一运行报could not load the Qt platform plugin xcb。常见场景是在设备上通过 SSH 远程跑 GUI 程序或者构建机器和目标运行机不是同一套环境。这里有三个常见原因。第一个原因很简单运行时 Qt 找不到 plugins 目录因为LD_LIBRARY_PATH配了但QT_PLUGIN_PATH没配。第二个原因是 xcb 插件依赖的某些系统运行库缺失比编译期更隐蔽。第三个原因是程序通过-platform offscreen或错误的环境变量绕过了 xcb结果窗口根本起不来。排查时用调试模式运行一下信息会直接打印到终端export QT_DEBUG_PLUGINS1 ./your_appQT_DEBUG_PLUGINS1会打印每个插件加载尝试和失败原因经常能看到Cannot load library后面跟着一个具体缺失的.so文件。比如缺libxcb-xinerama0即使编译期有头文件运行期也必须有对应的运行库。解决办法是sudo apt install -y libxcb-xinerama0这种补装对应库补完之后程序一般就能起来了。不要把QT_QPA_PLATFORMoffscreen当作解决方案那只是让程序不崩溃窗口出不来问题会被掩盖。6. 用一个小 Demo 验证自编 Qt并把它固化成基线6.1 可复现的 demo 工程与构建命令环境全部落地后最后一步是验证我会专门建一个最小工程确认这一版 Qt 真的能加载 xcb 平台插件。项目只需要两个文件。先是hello.pro内容如下QT core gui greaterThan(QT_MAJOR_VERSION, 4): QT widgets TARGET hello TEMPLATE app SOURCES main.cpp然后是main.cpp#include QApplication #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label(Kylin-Desktop ARM64 Qt 5.12.10); label.resize(360, 180); label.show(); return app.exec(); }用自编 Qt 构建并运行export PATH/opt/Qt5.12.10/bin:$PATH qmake hello.pro make -j4 ./hello如果屏幕上出现一个标签窗口说明 Qt 内核、xcb 插件、GUI 模块全链路都正常。这是在本地桌面环境下的验证如果当前是 SSH 无桌面会话可以改用QT_QPA_PLATFORMwayland或放到桌面会话里跑但验证本质一样。看到窗口之后我习惯把这个 demo 工程留在/opt/Qt5.12.10/check-demo目录里作为后续环境变更后的第一道回归测试。验证通过后建议把 configure 命令完整存成脚本放在源码目录里命名成build-qt512-aarch64.sh。不要靠记忆不要只写注释把参数原样固化下来。我自己的习惯是连同/opt/Qt5.12.10一起打一个 tar 包特别在不同设备上重复部署时会节省大量时间。打完包后用一个干净的同一个 GFB-Release-020 镜像设备解压验证一次确认它能在不编译的情况下直接用于 qmake 构建。这就是我理解的“编译完成”的终点不是 make 打完收工而是任何一台同样的 ARM64 麒麟 V10 设备拿着这套记录和产物都能复现同一个 Qt 5.12.10 环境。我在这个版本上翻过一次车编完 Qt 后没记录 configure 参数过了两周去补编一个模块发现缺-xcb整个链接阶段的表现完全不一样。从那之后configure 命令、依赖清单、并行度选择都会同步写进构建脚本这也算一次踩坑换来的习惯。这一套组合拳打下来系统里的 Qt 才真正变成可以长期依赖的东西希望帮到你。本文还有配套的精品资源点击获取