银河麒麟V10 SP1系统下QT5.12.8环境搭建避坑指南飞腾处理器实测接到一个任务在银河麒麟V10 SP1上搭一套 Qt 5.12.8 开发环境CPU 是飞腾 FT-2000。折腾了两天踩了不少坑编译失败、链接报错、xcb 平台插件起不来……这些我都遇了一遍。最后总算稳定跑通了把整个流程和坑点整理成文希望能帮到同样要在国产平台下做 Qt 开发的兄弟。这篇内容重点解决三个问题一是判断当前系统环境和硬件架构二是用源码方式编译安装 Qt 5.12.8三是把 Qt Creator 和运行环境调试到能正常出界面。适合刚接触银河麒麟/飞腾开发的朋友也适合之前只在 x86 的 Ubuntu 上配过 Qt、刚转过来的开发者。1. 环境准备与整体思路1.1 先搞清楚你的硬件和系统版本拿到机器以后别急着装东西先确认硬件架构和系统版本。这一步很多人会省略但在国产平台上特别关键。因为 x86 和 ARM 的预编译包不通用软件源里的包也可能跟你想象的不一样。打开终端先看系统和 CPU 信息cat /etc/os-release uname -m cat /proc/cpuinfo | grep -E Processor|model name | head -n 5我这台机器的输出大概是这样的NAMEKylin VERSIONV10 (SP1) IDkylin PRETTY_NAMEKylin V10 SP1 uname -m 输出aarch64也就是说这是 ARM 64 位架构AArch64CPU 是飞腾处理器指令集是 ARMv8。后续所有下载、编译参数、依赖包选择都要围绕这个架构来。接着看内存和磁盘free -h df -h /Qt 5.12.8 完整源码编译建议至少 8GB 内存、10GB 空闲磁盘。如果内存只有 4GB后面make的时候会很痛苦建议提前用fallocate -l 8G /swapfile扩展一个 swap具体细节在编译章节里再讲。1.2 为什么选择源码编译而不是直接 apt 安装银河麒麟V10 SP1 的软件源里其实有 Qt 相关包直接sudo apt install qt5-default也可能装得上但这里有个关键问题源里带的 Qt 版本和你想用的 5.12.8 不一定一致。我这边源里默认的 qtbase 版本是 5.11.1和项目要求不匹配。更重要的原因是源码编译可以把 Qt 安装到独立目录比如/opt/Qt5.12.8不会跟系统自带的 Qt 环境打架。银河麒麟系统本身有一些系统组件依赖系统自带的 Qt 库如果你直接覆盖或者用乱七八糟的 PPA 源去替换系统 Qt很容易把控制面板、设置界面搞挂。把自定义 Qt 放到独立 prefix用环境变量去切换互不干扰出问题了删掉目录就恢复原样省心得多。另外飞腾这种 ARM 平台很多预编译包虽然能跑但未必针对飞腾做过优化。源码编译虽然耗时但生成的二进制和当前系统的 glibc、库版本是严格对应的兼容性反而更好。1.3 下载 Qt 源码注意选择和校验Qt 5.12.8 不是最新版但属于 5.12 LTS 系列里修复比较多的一个版本。下载源码建议直接去 Qt 官方归档地址wget https://download.qt.io/archive/qt/5.12/5.12.8/qt-everywhere-src-5.12.8.tar.xz如果官方地址太慢可以用国内镜像加速把域名替换成清华镜像mirrors.tuna.tsinghua.edu.cn/qt/或者中科大镜像mirrors.ustc.edu.cn/qtproject/即可。在这里我要特别提醒一句完整源码包 qt-everywhere-src-5.12.8.tar.xz 非常大解压后占好几 GB编译所有模块可能要一两个小时。如果你只需要 Qt Widgets、Qt GUI、Qt Core、Qt Network 这些基础功能更建议只下载 qtbase 模块wget https://download.qt.io/archive/qt/5.12/5.12.8/submodules/qtbase-everywhere-src-5.12.8.tar.xzqtbase 是 Qt 的地基包含 qmake、Qt Core/GUI/Widgets/Network 等最常用的模块。单独编译这个时间大概能节省一大半。后面我的实际操作就是先全量编译失败过一次后来切到 qtbase 按需模块效率高很多。如果你确认只需要桌面应用开发直接走 qtbase 就够用。2. 系统初始化把依赖环境收拾干净2.1 基础编译工具链检查源码编译第一步是确保有 GCC、G、Make 这些基础工具。银河麒麟 V10 SP1 自带工具链版本一般比较靠谱但不排除有精简安装的情况。sudo apt update sudo apt install -y build-essential gcc g make perl gcc --version这里需要注意 GCC 版本。Qt 5.12.8 是 2019 年的项目C 标准用的是 C14/C17 过渡期写法。如果 GCC 版本太新比如 12/13编译 Qt 源码时可能会遇到一些比较老的语法告警甚至错误如果版本太旧比如 4.x又可能不支持 Qt 需要的特性。我这边系统自带的是 GCC 9.3.0和 Qt 5.12.8 配合没有遇到原则性问题所以如果你的系统自带 GCC 也是 8/9 系列就直接用系统的不需要额外折腾。用uname -m看到 aarch64 后其实还有一个隐性问题值得注意部分交叉编译文档会建议指定-platform linux-aarch64-gnu-g但我们这是在飞腾板子上本地编译Qt 的 configure 脚本会自动检测当前的主机平台通常不需要手动指定只需要确认--host没问题即可。2.2 图形显示相关依赖这个坑最多这是整个环境搭建里最容易出问题的部分。Qt 在 Linux 桌面上跑 GUI 程序默认走 xcb 插件也就是通过 X11 协议把界面画出来。如果 xcb 相关的开发包不完整即使 Qt 编译成功了运行程序时也会报类似这样的错误qt.qpa.plugin: Could not load the Qt platform plugin xcb in even though it was found.这个错误我这次遇到了好几次每次原因还不一样。为了少踩坑建议直接用下面的命令把常用的图形依赖一次装齐sudo apt install -y libx11-dev libxext-dev libxtst-dev libxrender-dev \ libxcb1-dev libxcb-util0-dev libxcb-icccm4-dev libxcb-image0-dev \ libxcb-keysyms1-dev libxcb-randr0-dev libxcb-render-util0-dev \ libxcb-shape0-dev libxcb-xinerama0-dev libxcb-xfixes0-dev \ libxcb-cursor0 libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev \ libfontconfig1-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev \ libdbus-1-dev libgles2-mesa-dev到这里还没完。飞腾平台走的是 ARM 架构很多机器用的还是板载显卡或者集显OpenGL 支持程度不一。Qt 编译时如果检测不到 OpenGL ES会直接禁用部分 GUI 渲染能力。所以libgl1-mesa-dev和libgles2-mesa-dev这两个包一定要装否则 configure 阶段会看到类似 OpenGL ES 2.0 not found 的提示编译出来的 Qt 在部分嵌入式环境下会有兼容问题。还有一个容易漏的是libxcb-xinerama0-dev如果这个缺失编译时未必报错但是程序启动时 xcb 插件加载会失败Qt 甚至会直接打印 Missing X11 xinerama 之类的提示。这个包在 ARM 源里也有直接装上就行。2.3 完全离线环境怎么准备依赖很多单位的内网开发机是不能直连外网的这是国产平台项目中非常常见的情况。如果你遇到这种情况不要慌依赖包可以提前准备。在有外网的银河麒麟同架构机器上或者虚拟机里先用apt-get install把上面列出的包下载下来注意不是直接安装而是只下载 .deb 包mkdir /tmp/kylin-deps cd /tmp/kylin-deps sudo apt-get download $(apt-cache depends libxcb1-dev | grep Depends | awk {print $2}) 2/dev/null更简单的思路是直接用apt-get install --download-onlysudo apt-get install -y --download-only build-essential libxcb1-dev libgl1-mesa-dev # 下载完的 .deb 文件在 /var/cache/apt/archives/ cp /var/cache/apt/archives/*.deb /tmp/kylin-deps/然后把整个目录拷贝到内网机器执行sudo dpkg -i /tmp/kylin-deps/*.deb如果提示依赖缺失再用同一个思路补下载一轮。这个方案我实测是可行的拷贝时注意保持 .deb 文件完整不要用优盘在中途断电。3. 编译安装 QT5.12.8完整流程与参数解析3.1 configure 参数如何取舍依赖装齐后解压源码包进入源码目录开始配置tar -xJf qtbase-everywhere-src-5.12.8.tar.xz cd qtbase-everywhere-src-5.12.8 mkdir build cd build这里我额外建了一个 build 目录做独立编译好处是源码目录保持干净想重新 configure 时直接清掉 build 目录即可。接着执行../configure -prefix /opt/Qt5.12.8 \ -opensource -confirm-license \ -release -shared \ -qt-xcb -xkbcommon \ -no-opengl -nomake examples -nomake tests逐项解释下我的选择-prefix /opt/Qt5.12.8指定安装目录隔离系统 Qt。强烈建议不要用默认的/usr/local否则后续卸载和切换版本很麻烦。-opensource -confirm-license选择开源协议并自动确认避免交互卡住。-release -shared只编译 release 版本、生成动态库。如果是纯开发学习不需要 debug 库能省不少编译时间。-qt-xcb让 Qt 自带 xcb 平台的实现。这里解释一下默认情况下 Qt 会选择链接系统已安装的 xcb 库但有时系统 xcb 库版本过老与 Qt 5.12.8 的期望 API 不一致导致编译或运行时行为诡异。用-qt-xcb后 Qt 会内置一份 xcb 相关代码稳定性大幅提升。代价是编译时间稍微增加但对国产 Linux 这种系统库版本比较固定的环境来说非常值得。-xkbcommon启用 X keyboard common 支持解决键盘输入和布局问题。-no-opengl我在飞腾板子上确认过没有 GPU 加速且 Qt Quick 不是必需项所以直接禁用 OpenGL。如果你后续要用 QML 或 Qt Quick 做复杂界面这里需要调整成-opengl es2并确保装了 Mesa 开发包。不过-no-opengl对纯 Widgets 应用没有任何影响。-nomake examples -nomake tests跳过示例和测试编译省时间。这里有一个非常重要的建议../configure -help里参数很多不要照搬网上 x86 平台的配置尤其是不要随便加-no-xcb或者-no-feature-*之类的裁剪项否则容易把基础功能剪掉。保持最小必要选项反而是最稳的。3.2 make 阶段并行度与内存的平衡configure 跑完后终端会提示Qt is now configured for building一类的话。接下来就是最费时间的编译环节了。nproc先看核数我这台飞腾机器显示 8 核16GB 内存。理论上可以用make -j8但我第一次全量编译时发现同时编译多个大文件会让内存飙到 90% 以上中途还出现过一次 OOM 导致编译进程被杀死。后来我改成make -j4过程就稳定了。如果在编译过程中遇到 virtual memory exhausted 或 g: internal compiler error: Killed (program cc1plus) 这类提示基本可以确定是内存不够解决办法只有两个方向一是减少并行度make -j2甚至make -j1二是增加 swap飞腾板子如果用的是 SSDswap 性能还能接受sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile至于编译时间按我实测的数据单独编译 qtbase4 线程大约需要 25 到 35 分钟如果是全量 qt-everywhere 源码1 至 2 个小时很正常。所以如果你不是需要 Qt Charts、Qt WebEngine 等高级模块真的建议只编 qtbase。编译完成后sudo make install安装过程比较快主要是拷贝文件。安装到/opt/Qt5.12.8后目录结构大概是/opt/Qt5.12.8/ ├── bin/ │ ├── qmake │ ├── moc │ ├── uic │ └── rcc ├── include/ ├── lib/ └── plugins/到这里 Qt 本体就编译完了。别急着高兴这只是第一步后面配置运行环境还会有几个大坑。3.3 编译结果验证与动态库检查先验证一下 qmake 是否正常工作/opt/Qt5.12.8/bin/qmake -v正常会输出QMake version 3.1 Using Qt version 5.12.8 in /opt/Qt5.12.8/lib接着检查 xcb 平台插件是否生成ls /opt/Qt5.12.8/plugins/platforms/正常至少应该看到libqxcb.so。如果这个文件不存在运行任何 Qt GUI 程序都会失败。此时可以用 ldd 看一下它依赖的库是否完整ldd /opt/Qt5.12.8/plugins/platforms/libqxcb.so如果出现 not found说明系统里缺运行库。我遇到过一次libxcb-xinerama.so.0找不到的问题解决办法是回到第 2 章把libxcb-xinerama0-dev装上。因为 Qt 编译时能找到头文件不代表运行时能找到动态库这是两个阶段的问题很多人就是栽在这里。4. 环境变量与 Qt Creator 集成4.1 把 Qt 路径固化到系统环境Qt 安装到自定义目录后不配置环境变量的话每次都要写绝对路径qmake 和运行程序时也找不到库。建议把下面这段写入~/.bashrcexport QTDIR/opt/Qt5.12.8 export PATH$QTDIR/bin:$PATH export LD_LIBRARY_PATH$QTDIR/lib:$LD_LIBRARY_PATH export QT_PLUGIN_PATH$QTDIR/plugins export XDG_RUNTIME_DIR/run/user/$(id -u)其中QT_PLUGIN_PATH尤其关键。Qt 在启动时会按这个路径查找 plugins 目录如果不设置默认去系统 Qt 插件目录找那样大概率找到的是系统 Qt 5.11 的插件和当前 5.12.8 平台插件混用可能出现 Cannot mix incompatible Qt library 的报错。保存后执行source ~/.bashrc然后验证which qmake qmake -v如果输出的是/opt/Qt5.12.8/bin/qmake说明环境变量生效了。这里需要注意一点LD_LIBRARY_PATH会让所有使用 Qt 的程序都优先加载这个目录下的库简单场景没问题但如果你开发的是某个嵌入到系统服务的程序建议用qt.conf文件配合QMAKE_RPATH来处理链接路径避免影响整个系统的 Qt 程序。4.2 设置 XDG_RUNTIME_DIR 避免运行警告很多程序跑起来后终端会输出一堆警告QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to /tmp/runtime-root这个不影响功能但确实烦人而且可能导致某些依赖会话总线的程序行为异常。在非 root 用户下系统初始化时通常会设置这个变量但如果你在终端直接以 root 身份运行 Qt 程序就需要手动加。我在上面第 4.1 节的环境变量里已经加了export XDG_RUNTIME_DIR/run/user/$(id -u)实测输出干净多了。如果$(id -u)对应的目录不存在可以先执行sudo mkdir -p /run/user/0 # root 用户时 sudo chmod 700 /run/user/04.3 Qt Creator 的安装与 Kit 配置Qt Creator 是开发 Qt 程序最常用的 IDE。银河麒麟的软件源里应该有 qtcreator直接安装即可sudo apt install -y qtcreator也可以用 Qt 官方镜像下载独立的 Qt Creator 套件包但那样还要额外处理依赖不如 apt 省事。源里的 Qt Creator 版本可能略旧功能上足够日常使用。安装完成后打开 Qt Creator选择菜单栏工具-选项-Kits在编译器页面确认自动检测到的编译器是GCC (aarch64-linux-gnu)或GCC (x86_64-linux-gnu)对应的本机编译器。如果没检测到手动添加which g # 通常在 /usr/bin/g 添加时选择该路径然后是 Qt Versions 页面点击添加选择/opt/Qt5.12.8/bin/qmakeQt Creator 会自动识别版本为 5.12.8。最后在 Kits 页面把 Qt 5.12.8 和对应的编译器关联起来作为默认套件。这里有个经验不要在 Kit 里勾选多个 Qt 版本尤其不要把系统 Qt 5.11 和自定义 Qt 5.12.8 同时设为默认可用的 Kit否则创建项目时容易选错莫名其妙出现一堆 qmake: could not find a Qt installation 的错误。配置好以后可以新建一个 Qt Widgets Application编译试跑。如果一切正常应该会弹出一个空白窗口。至此Qt Creator 集成已经跑通。5. 高频问题与排查技巧实录5.1 最容易踩的 6 个编译/运行错误我把这次搭建过程中遇到的和行业内高频出现的问题整理成了一张对照表方便你照着排查症状根本原因解决方案configure 提示xkbcommon not found缺少 xkbcommon 开发库sudo apt install libxkbcommon-dev libxkbcommon-x11-dev编译时提示g: internal compiler error: Killed内存不足编译进程被杀降低并行度如make -j2增加 swap运行程序提示could not load the Qt platform plugin xcbxcb 插件缺失或依赖不完整检查plugins/platforms/libqxcb.so是否存在用ldd查看是否缺库运行程序提示Cannot mix incompatible Qt library同时加载了系统 Qt 和自定义 Qt 的库检查LD_LIBRARY_PATH确认 qmake 和平台插件都来自/opt/Qt5.12.8运行程序提示GLIBCXX_3.4.26 not found编译器版本过旧或 libstdc 库不完整更新 GCC、g如sudo apt install gcc-9 g-9程序启动后无窗口进程直接退出OpenGL 初始化失败或显示环境异常确认QT_QPA_PLATFORM尝试export QT_QPA_PLATFORMoffscreen测试检查显卡驱动这张表里的前三个问题我这次全遇到了一遍。尤其是 xcb 插件的问题最隐蔽的就是编译时没问题、运行时报错建议所有遇到这个问题的朋友第一时间用ldd查依赖而不是盲目重编 Qt。5.2 libqxcb.so 依赖缺失的系统性排查思路xcb 插件加载失败本质上不是 Qt 的问题而是运行库路径问题。我建议按以下顺序排查第一步确认插件存在ls -l /opt/Qt5.12.8/plugins/platforms/libqxcb.so第二步查看它的依赖ldd /opt/Qt5.12.8/plugins/platforms/libqxcb.so | grep not found如果输出为空说明动态库依赖是完整的接下来用 Qt 的调试模式看加载过程的详细日志export QT_DEBUG_PLUGINS1 ./你的Qt程序开启后 Qt 会打印每个插件尝试加载的结果包括为什么失败。这个日志非常详细能直接看到是缺哪个符号或者哪个库。第三步如果依赖缺失优先安装对应库sudo apt install libxcb-xinerama0 libxcb-cursor0装完后再执行ldconfig刷新缓存重新运行程序。这套流程下来90% 的平台插件问题都能解决。5.3 版本混合使用引发的连锁问题还有一个非常典型的问题是系统中存在多个 Qt 版本。有时候你明明用的是/opt/Qt5.12.8/bin/qmake编译程序但程序运行起来却加载了系统/usr/lib/aarch64-linux-gnu/libQt5Core.so.5.11的库。这种情况在新装的 Qt 程序开发中特别常见尤其是那些通过.desktop文件启动的程序或者通过 LD_LIBRARY_PATH 被其他脚本改过的程序。排查方法ldd 你的Qt程序 | grep Qt看 Qt 库路径是哪里。如果指向系统目录说明环境变量没生效重新检查~/.bashrc中的LD_LIBRARY_PATH是否包含/opt/Qt5.12.8/lib或者用qmake生成 Makefile 时是不是带了不合适的RPATH。对于要交付给用户运行的程序我不建议依赖环境变量。更稳的方式是在可执行文件同级目录放一个qt.conf文件内容[Paths] Prefix/opt/Qt5.12.8 PluginspluginsQt 启动时会自动读取qt.conf从指定路径加载插件和库完全不依赖 shell 环境。这个方式在国产平台下交付程序时特别有用因为目标用户环境千奇百怪不一定配置了 Qt 环境变量。最后再分享一个实用技巧在飞腾这种 ARM 处理器上如果编译时遇到 undefined reference 且方法名看起来跟 xcb 或 OpenGL 相关不妨先检查一下是不是装的是libgl1-mesa-dev而不是libgl-dev或者驱动相关包。我在调试过程中发现很多看似深奥的编译错误追根到底都是基础依赖版本不匹配。遇到难题时优先用apt-cache policy查看包的版本再决定升级还是降级一般都能找到突破口。