
简介面向麒麟桌面系统Kylin-Desktop-V10-GFB-Release-020-ARM64和联想昭阳N4720Z平台资源给出已编译完成的Qt 5.12.10 ARM64版本适合在国产化Linux环境中进行Qt应用开发、软件移植或交叉验证的工程师参考。包体约84.62MB包含2000个h头文件覆盖Qt Core、Gui、Widgets、OpenGL等常用模块的头定义可辅助代码阅读、API查找与编译配置检查压缩包同时保留qmake与构建套件需要的文件省去在Kylin ARM64上从源码编译Qt的耗时工作。作者已在指定机型与系统上亲测可用说明读者能直接借助这套环境搭建应用降低国产硬件上Qt开发的上手门槛。已有1070人学习/下载对于需要解决Qt5在Kylin、Linux ARM64环境下qmake路径配置、构建套件选择或头文件缺失等问题的人群是一份具有实践参考价值的基础资料。1. 拿到ARM64桌面Linux的Qt预编译包先别急着源码编译这份资源能省你半天在某国产桌面系统V10ARM64架构上做Qt应用开发第一道坎往往不是业务代码而是基础环境源码编译Qt 5.12.10configure脚本在ARM64上报一堆依赖缺失make过程动辄两三个小时失败一次就基本要从头再来。最近拿到一份已经编译好的Qt 5.12.10预编译包它针对某厂商的ARM64整机做过优化解压后配置环境变量就能直接用。这篇文章我拆解了部署、验证和排错的全过程适合刚接触ARM64环境、不想折腾编译链的开发者参考。2. 为什么说别源码编译ARM64 桌面Linux的Qt 5.12.10有七道坎2.1 依赖链从xcb到OpenGL缺一个就中断源码编译Qt最烦人的阶段是configure。Qt的GUI模块在Linux下依赖xcb协议栈而xcb又依赖xcb-xinerama、xcb-cursor等一系列子库。在x86桌面发行版里这些依赖多半是默认装好的但很多精简的ARM64桌面系统把开发头文件全部省略。configure执行到Basic XLib functionality test时一旦检测不到X11/Xlib.h或者xcb/xcb.h直接报错退出。解决方式是configure加-qt-xcb让Qt自带xcb库但这样对编译器的静态链接能力要求更高后期链接阶段更容易出问题。更隐蔽的是OpenGL。Qt5的Widgets模块在运行时需要通过GL动态库创建渲染上下文。编译期间如果找不到GL/gl.hconfigure会默认放弃OpenGL支持表面上能过但生成的Qt库缺少关键的QOpenGLContext功能后面任何依赖OpenGL的窗口都会段错误。这种错误不到运行期根本发现不了排查起来非常消耗时间。2.2 本地编译还是交叉编译sysroot坑都不一样很多人拿到ARM64设备第一反应是从x86的PC上交叉编译。交叉编译Qt必须指定--sysroot指向目标系统的根目录。我朋友曾经在sysroot里缺了/usr/lib/aarch64-linux-gnu/crtbeginS.o链接阶段反复报错找了一下午才发现是sysroot里的gcc版本和目标机器不一致导致的。即使在ARM64本机本地编译也会遇到多gcc版本共存的问题。Qt的configure会探测/usr/bin/gcc的默认路径如果环境里同时装了gcc-10和gcc-9而系统的libstdc头文件跟随gcc-9configure可能生成错误的qconfig.h。我一般做法是临时把其他gcc移出PATH只用系统默认gcc并且不手动指定--sysroot让configure自动探测本机路径。2.3 时间成本两小时起步失败重来更崩溃我在一台四核ARM64机器上实测过全量编译使用make -j4编译Qt5.12.10的默认模块qtbase、qtdeclarative、qttools等全开耗时约2小时40分钟。如果中途缺某个库修复后接着make往往会在同一处反复失败因为部分生成的Makefile和临时文件已经损坏。最稳妥的是make clean重新来加上configure的时间小半天就没了。而这份预编译包解压后qmake -v验证不超过十分钟。2.4 预编译包的适用边界能省时间但不是万金油预编译包是根据特定系统版本和特定硬件设备编译的。它对应的glibc版本如果是2.30而你的系统较老、glibc停留在2.27Qt库加载时就会因为找不到符号而失败。此外即使同为ARMv8不同代际CPU的指令集扩展也有差异编译器可能开启-marcharmv8.2-a旧CPU执行到某些优化指令就直接触发未定义指令异常。我在部署前一定先跑三个命令确认环境uname -a cat /etc/os-release ldd --version | head -1参数说明uname -a查看内核版本和架构/etc/os-release确认发行版版本号ldd --version输出的glibc版本必须大于等于预编译包要求的最低值。这三个命令的输出决定这个包在目标机器上能不能跑起来。2.5 什么情况下仍然需要源码编译自定义Qt模块 / 特殊补丁如果只是做应用层开发预编译包完全够用。但你要二开Qt源码比如修改QtQuick渲染逻辑或者想裁剪掉不需要的模块以减小动态库体积那就必须自己编译。还有一种情况预编译包默认使用-O2优化如果你想用-O3或者加上调试符号-g来排查Qt内部问题也需要重新编译一个debug版本。另外预编译包一般不会包含qtserialport、qtcharts这些拓展模块如果项目依赖它们你需要去官方镜像拉取对应源码单独编译。这种情况下可以把预编译包提供的qmake当工具链使用用它来编译缺失的模块这样能在保留基础包的同时按需补充。2.6 资源包的目录结构解析为什么没有安装脚本打开压缩包你会发现它不是一个安装包而是一个带完整目录结构的文件夹。Qt本身不需要写入系统目录只要把库路径和工具路径配置好就算安装。压缩包里包含bin、include、lib、plugins等目录bin下有qmake和moc等工具lib下是libQt5Core.so等动态库plugins/platforms目录存放libqxcb.so。这种绿色解压方式让多版本Qt共存变得很容易我把它和系统自带Qt放在不同目录随时切换互不影响。3. 部署预编译包解压、环境变量、验证qmake三步走3.1 确认系统架构与基础依赖拿到包之前先确认目标机器的架构。虽然标题写着ARM64但系统里可能安装了armhf32位兼容层gcc默认目标却是armhf导致qmake能运行但生成的程序无法运行。uname -m输出必须是aarch64。如果不是说明系统是32位运行模式这个包完全不兼容直接换系统镜像吧。接着检查发行版版本cat /etc/os-release重点关注VERSION_ID。如果系统版本比V10旧或者包的release比你的系统新很可能出现glibc版本不够的问题。我习惯再用ldd --version确认glibc具体版本ldd --version | head -1通常要求glibc 2.28具体以包内readme说明为准。预编译包如果是在较新的环境编译的依赖的glibc会更高readme里都会写别忽略。3.2 解压并规划安装目录我习惯把这类第三方工具放到/opt和系统的/usr分隔开。这样卸载时直接删目录即可不影响系统环境。sudo mkdir -p /opt sudo tar -xzf Qt5.12.10-arm64-*.tar.gz -C /opt-C /opt指定解压目标目录。解压后的文件夹名可能包含设备型号或版本信息比如Qt5.12.10-lenovo。这里要注意如果文件夹名里有空格或奇怪字符后面配置环境变量会非常痛苦。我的习惯是先统一重命名sudo mv /opt/Qt5.12.10-* /opt/Qt5.12.10如果压缩包直接解压出Qt5.12.10目录就跳过这步。解压完成后看一眼目录结构ls /opt/Qt5.12.10必须看到bin、include、lib、plugins、mkspecs这几个核心目录缺任何一个都说明包不完整不要继续用。3.3 配置环境变量临时生效的配置适合测试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参数说明QTDIR是Qt根目录很多项目构建脚本会引用它PATH中加入bin是为了直接调用qmake、moc等工具LD_LIBRARY_PATH指定动态库搜索路径不设置的话运行程序时就找不到libQt5CoreQT_PLUGIN_PATH让Qt运行时找到平台插件platforms/xcb有些版本也用QT_QPA_PLATFORM_PLUGIN_PATH但QT_PLUGIN_PATH更通用。想让配置永久生效把上面四行追加到~/.bashrc。注意如果你用的是zsh要写到~/.zshrc。很多人在这一步踩坑打开终端发现qmake还是旧版本就因为shell启动文件没配对。配置后验证source ~/.bashrc which qmake qmake -vwhich qmake输出应是/opt/Qt5.12.10/bin/qmake。如果仍是/usr/bin/qmake说明系统PATH里/opt/Qt5.12.10/bin被排在后面需要把export语句改为export PATH/opt/Qt5.12.10/bin:$PATH并放在文件最前面。3.4 检查Qt库的系统依赖预编译包里的libQt5Core.so等动态库不是全静态的它依赖系统的libc、libstdc、libicu等。如果目标系统缺了某个运行库程序启动时就会崩溃或者报找不到库。用ldd检查ldd /opt/Qt5.12.10/lib/libQt5Core.so | grep not found如果没有输出说明核心库依赖齐全。如果出现类似libicuuc.so.60 not found就需安装对应软件包。国产桌面系统上另一个常缺的是libGL.so.1可以用find / -name libGL*全盘搜索确认。还有一种情况ldd显示找不到库但系统其实有只是路径不在标准搜索位置。比如libicuuc.so.60实际位于/usr/lib/aarch64-linux-gnu可以通过追加该路径解决export LD_LIBRARY_PATH/usr/lib/aarch64-linux-gnu:$LD_LIBRARY_PATH但更好的做法是安装对应的dev包让库文件同步到标准路径避免每次登录后都要手动设。3.5 快速验证先跑一个控制台程序在配置好环境后用Qt的信号槽机制写一个最简验证而不是急着打开GUI窗口。创建checkqt.cpp#include QCoreApplication #include QDebug int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); qDebug() Qt version: QT_VERSION_STR; return 0; }用qmake -project qmake make编译运行。这个程序验证了qmake生成的Makefile是否正常、链接是否成功。控制台程序能跑再继续测GUI否则别浪费时间去排查屏幕问题。4. 用这套Qt 5.12.10编译一个真实测试工程4.1 创建工程从最简单的Qt Widgets入手验证GUI栈完整。创建工程目录mkdir ~/test-qt cd ~/test-qt写main.cpp#include QApplication #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label(Hello from Qt 5.12.10 on ARM64); label.resize(240, 80); label.show(); return app.exec(); }这段代码创建一个标签并显示。如果平台插件正常屏幕上会弹出窗口。如果没有任何显示不要急着怀疑代码先检查平台插件。写工程文件testqt.proTEMPLATE app TARGET test-qt CONFIG console c11 QT widgets SOURCES main.cpp参数说明TEMPLATE app表示生成可执行程序CONFIG console允许在调试时输出日志即使GUI程序也建议保留QT widgets把Qt Widgets模块链接进来少了这一行会报QApplication not found。注意Qt5里必须写QT widgetsQt4是QT gui从旧项目迁移时最容易卡在这里。4.2 构建单独建build目录避免源码目录被临时文件污染mkdir -p build cd build qmake ../testqt.pro make -j4qmake根据.pro文件生成Makefilemake -j4用4个并行任务编译。如果机器内存小于2GB-j4可能编译到一半内存爆掉建议改成-j2。编译完成后ls -la test-qt生成的是ELF可执行文件。用file命令确认架构file test-qt输出里应该包含ARM aarch64。如果看到x86-64说明你的qmake不是从预编译包来的立刻停下来检查PATH。4.3 运行GUI程序运行前手动确认库路径和插件路径export LD_LIBRARY_PATH/opt/Qt5.12.10/lib:$LD_LIBRARY_PATH export QT_PLUGIN_PATH/opt/Qt5.12.10/plugins ./test-qt如果一切正常屏幕上会弹出窗口。如果没有窗口而是输出This application failed to start because no Qt platform plugin could be initialized.直接跳转到避坑章节的问题四查看。4.4 使用CMake配置这套Qt现在不少项目用CMake需要设置CMAKE_PREFIX_PATH指向Qt根目录cmake -DCMAKE_PREFIX_PATH/opt/Qt5.12.10 ..这个参数让find_package(Qt5)搜索到正确的Qt5Config.cmake。如果不设置CMake可能找到系统自带的Qt5。设置后find_package(Qt5 COMPONENTS Widgets)会从指定路径找到。如果依然失败再加一个更明确指向cmake -DQt5_DIR/opt/Qt5.12.10/lib/cmake/Qt5 ..这样强制CMake使用这个目录下的Qt5配置模块。4.5 检查qmake的实际安装路径有时候即使PATH配置了qmake查询到的前缀仍是编译时的路径。使用命令确认qmake -query QT_INSTALL_PREFIX qmake -query QT_INSTALL_LIBS输出应该分别是/opt/Qt5.12.10和/opt/Qt5.12.10/lib。如果输出的是其他路径比如/home/user/qt5说明当前qmake被别的副本覆盖了。强制使用绝对路径/opt/Qt5.12.10/bin/qmake -query QT_INSTALL_PREFIX这步能帮你确认到底是哪份qmake在工作。4.6 理解moc/uic是如何被调用的qmake生成的Makefile会自动调用moc处理含Q_OBJECT的头文件uic会处理.ui文件。很多新手上手时总担心moc等工具找不到。其实只要qmake是从/opt/Qt5.12.10/bin来的Makefile里就会写死对应的绝对路径不再依赖当前PATH。你可以打开build目录下的Makefile看一眼grep ^MOC Makefile输出类似MOC /opt/Qt5.12.10/bin/moc。如果这里出现/usr/bin/moc说明qmake用错了。5. 避坑五个高频问题和对应排查5.1 问题一程序运行时找不到libQt5Core.so.5现象执行编译好的程序提示error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory原因动态链接器没有搜到Qt库。通常是LD_LIBRARY_PATH没设或者设置后没有在当前终端生效。解决先用ldd检查ldd ./test-qt | grep QtCore如果显示libQt5Core.so.5 /opt/Qt5.12.10/lib/libQt5Core.so.5说明没问题如果显示not found就执行export LD_LIBRARY_PATH/opt/Qt5.12.10/lib:$LD_LIBRARY_PATH为了永久生效把export写进~/.bashrc并source。另一种隐蔽情况是LD_LIBRARY_PATH里同时包含了系统自带的Qt路径例如/usr/lib/aarch64-linux-gnu旧版libQt5Core被优先加载程序启动后表现诡异。解法是把/opt/Qt5.12.10/lib放在LD_LIBRARY_PATH最前面。5.2 问题二qmake使用的是系统旧版本现象运行qmake -v显示Qt version 5.12.7或更老而预编译包是5.12.10。原因PATH里系统自带qmake通常在/usr/bin比/opt/Qt5.12.10/bin靠前。解决直接使用绝对路径/opt/Qt5.12.10/bin/qmake -v或者调整PATH顺序export PATH/opt/Qt5.12.10/bin:$PATH注意把$PATH放在后面才能让新路径优先。改完后再执行which qmake确认。5.3 问题三编译时提示 cannot find -lGL现象链接阶段报错/usr/bin/ld: cannot find -lGL原因系统缺少OpenGL开发库或者libGL.so软链接不存在。Qt Widgets即使只显示QLabel链接时也需要GL库符号。解决在Debian/Ubuntu系安装sudo apt-get install libgl1-mesa-dev在国产系统上如果apt不可用使用yumsudo yum install mesa-libGL-devel安装后重新make。如果仍报找不到检查软链接ls -l /usr/lib/aarch64-linux-gnu/libGL.so软链接断裂就手动建一个sudo ln -s /usr/lib/aarch64-linux-gnu/libGL.so.1 /usr/lib/aarch64-linux-gnu/libGL.so5.4 问题四运行GUI程序时找不到平台插件xcb现象qt.qpa.plugin: Could not find the Qt platform plugin xcb in This application failed to start because no Qt platform plugin could be initialized.原因Qt无法从QT_PLUGIN_PATH或默认路径加载libqxcb.so。常见于三个情况路径没设、插件文件本身缺失、插件依赖的系统库缺失。解决第一步确认插件文件存在ls /opt/Qt5.12.10/plugins/platforms/libqxcb.so如果不存在说明压缩包不完整需要重新获取。如果文件存在用ldd检查依赖ldd /opt/Qt5.12.10/plugins/platforms/libqxcb.so | grep not found输出里常见缺失项有libxcb-xinerama.so.0、libxkbcommon-x11.so.0用包管理器安装对应库即可。另外手动指定插件平台路径export QT_QPA_PLATFORM_PLUGIN_PATH/opt/Qt5.12.10/plugins/platforms ./test-qt5.5 问题五程序启动时发生段错误现象直接崩溃终端输出Segmentation fault (core dumped)没有任何Qt提示。原因运行时加载了错误版本的Qt库或者CPU指令集不兼容。后者通常发生在相同架构但不同微架构的机器之间。解决先用ldd确认每个Qt库都来自/opt/Qt5.12.10/lib。如果路径没问题再用调试器看core dumpgdb ./test-qt core查看崩溃调用栈。最常见的情况是某个Qt模块用了当前CPU不支持的ARM指令。查看CPU特性cat /proc/cpuinfo | grep Features检查是否有asimd和crc32。如果预编译包要求lse指令而CPU不支持只能换包或重新编译。我的血泪经验拿到预编译包先别急着跑大工程先编译最小GUI程序测试只有最小程序过了才说明基础环境完全匹配。6. 进阶验证平台插件链与部署到无Qt环境预编译包最大的价值在于快速搭建开发环境但应用要交付到其他没有Qt的机器上还得自己做运行时部署。这里给出一套我经常用的小流程能在几分钟内把依赖尽量收全。先准备部署目录把编译好的可执行文件放进去mkdir -p ~/deploy/your_app cp ~/test-qt/build/test-qt ~/deploy/your_app/然后使用ldd查看程序依赖的所有Qt库ldd /opt/Qt5.12.10/plugins/platforms/libqxcb.so | grep Qt5 | awk {print $3} | sort -u将输出的Qt库拷贝到部署目录下的lib子目录。同时拷贝platforms插件mkdir -p ~/deploy/your_app/lib/platforms cp /opt/Qt5.12.10/plugins/platforms/libqxcb.so ~/deploy/your_app/lib/platforms/接着检查libqxcb.so的系统库依赖。那些非Qt的系统库如果目标机器上已有相同版本可以不必拷贝但为了稳妥我写一个启动脚本run.sh来设置环境变量#!/bin/bash DIR$(cd $(dirname $0) pwd) export LD_LIBRARY_PATH$DIR/lib:$LD_LIBRARY_PATH export QT_PLUGIN_PATH$DIR/lib export QT_QPA_PLATFORM_PLUGIN_PATH$DIR/lib/platforms export XDG_RUNTIME_DIR/tmp/runtime-$USER mkdir -p $XDG_RUNTIME_DIR chmod 700 $XDG_RUNTIME_DIR exec $DIR/test-qt $参数说明LD_LIBRARY_PATH指向应用私有lib目录确保Qt库优先加载QT_PLUGIN_PATH指向插件根目录这里platforms位于$DIR/lib/platforms所以QT_PLUGIN_PATH设为$DIR/libXDG_RUNTIME_DIR在Wayland或Weston环境下必须设置否则会出现could not connect to display 0等诡异问题。把这个目录拷贝到目标机器运行chmod x run.sh ./run.sh如果窗口正常说明部署成功。如果提示缺系统库比如libxkbcommon.so.0建议在目标机上用包管理器安装不要强行拷贝动态库覆盖系统目录那会破坏包管理的一致性。从那以后我每次拿到预编译包都会先做三件事uname -m确认架构、ldd检查核心库依赖、编译一个最小GUI程序验证平台插件。这套流程能筛掉90%的环境问题。希望帮到你。本文还有配套的精品资源点击获取