ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ARM统信UOS上源码编译Qt 5.15.2并定制Qt Creator

ARM统信UOS上源码编译Qt 5.15.2并定制Qt Creator 1. 环境准备与前期判断ARM 底座上跑统信 UOS桌面上自己编译一套 Qt 5.15.2再把 Qt Creator 按团队习惯改好这套流程看起来只是敲几条命令但真正做完之后后续的 ARM64 应用开发效率会提升一大截。我前后在不同 ARM64 板卡和 UOS 桌面环境上复现过踩过不少坑也理清了不少细节这里一次性写清楚。先说结论源码编译 Qt 并不难真正难的是把环境吃透。UOS 自带软件源里的 Qt 版本虽然能用但如果你想固定应用版本、打开某些默认没启用的 Qt 模块、或者给 Qt Creator 定制默认套件仓库提供的二进制包往往不够用。自己编译一遍后面做跨架构移植、接口调试、界面适配都会顺手很多。1.1 先确认你的 UOS 是不是 ARM 底子动手之前别凭感觉先看系统信息。很多人的 UOS 是 x86_64 的有些是海思麒麟有些是飞腾也有 RK3588 这类商用 ARM64 板卡操作步骤大体一致但依赖包和平台插件有细微差别。打开终端执行下面三条命令uname -m lscpu | grep Architecture dpkg --print-architecture如果输出是aarch64或arm64那这次的路径就是 ARM64软件包管理用的也是 arm64 架构的 deb 包。如果输出是x86_64那后面所有配置虽然能参考但依赖源里的包名可能不一样需要按自己的架构换一下。同时看一下系统版本cat /etc/os-releaseUOS 有很多桌面版本底层基本是 Debian 系所以 apt 源里的依赖基本通用。遇到缺失的开发库直接用apt search libxcb这类命令找包名即可。磁盘空间要认真看一眼。Qt 5.15.2 完整源码解压后大概 2.5GB 到 3GB编译中间产物至少再占 10GB安装到/opt/Qt还会占掉 2GB 左右。再加上 Qt Creator 的构建目录我建议预留 30GB 以上空间。1.2 依赖安装与磁盘规划在 UOS 上编译 Qt 5.15.2最怕的不是编译出错而是 configure 阶段提示缺这个库、少那个头文件来回折腾。建议先把编译工具链和常见依赖一把装齐。sudo apt update sudo apt install build-essential perl python3 git ninja-build cmake \ libxcb1-dev libxcb-util0-dev libxcb-shm0-dev \ libxcb-icccm4-dev libxcb-keysyms1-dev libxcb-xinerama0-dev \ libxcb-render-util0-dev libxcb-cursor0 libxcb-xkb-dev \ libxkbcommon-dev libxkbcommon-x11-dev \ libfontconfig1-dev libfreetype6-dev \ libgl1-mesa-dev libglu1-mesa-dev mesa-common-dev \ libssl-dev libicu-dev libdbus-1-dev libegl1-mesa-dev \ libpulse-dev libasound2-dev注意这些包名在 ARM64 UOS 上都能直接搜到个别包如果源里没有不必强求Qt 编译时会自动跳过对应功能。最关键的几类是 xcb、xkbcommon、OpenGL/EGL、fontconfig、freetype这些缺失会导致桌面程序没办法正常显示。磁盘规划上我建议单独建一个目录编译目录和安装目录分开export QT_BUILD_ROOT$HOME/work/qt-build mkdir -p $QT_BUILD_ROOT/src $QT_BUILD_ROOT/build编译目录和源码目录分开的好处是以后改配置重新构建不用把源码删掉重解压而且git管理补丁时不会把生成的.o文件都带进去。1.3 要不要从源码编译我的建议我知道有人会问UOS 软件源里明明有 Qt为什么还要自己编译软件源里的 Qt 版本一般比较旧而且拆成了几十个独立 deb 包Qt 模块之间的版本可能不统一。比如系统里qtbase5-dev是 5.11但你想用qtwebengine或qtcharts版本对不上就会很麻烦。源码编译的核心价值版本固定全团队都用同一个 Qt 源码版本行为一致。模块可选不需要的模块直接-skip需要的模块用参数打开。ARM 优化可以在编译时指定处理器特性参数。方便定制编译路径、安装路径、插件路径、甚至部分源码都可以自己改。如果你是做 ARM 板卡应用开发的后续很可能要把同样的 Qt 环境部署到多台设备上自己编译一套放在/opt/Qt里要比每台设备手动apt install再补依赖靠谱得多。2. 源码编译 Qt 5.15.2 全流程2.1 源码下载与目录结构准备Qt 5.15.2 属于 Qt 5.15 系列里比较稳定的一个版本好多嵌入式方案都拿它做基线。Qt 官方提供qt-everywhere-src源码包里面包含了 qtbase、qtdeclarative、qttools、qtmultimedia 等几乎所有基础模块一次下载统一编译。下载地址直接用 Qt 官方存档或者用镜像站。这里以官方存档为例cd $QT_BUILD_ROOT/src wget https://download.qt.io/archive/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz下载后建议校验一下 SHA256避免源站文件损坏sha256sum qt-everywhere-src-5.15.2.tar.xz然后解压tar xf qt-everywhere-src-5.15.2.tar.xz cd qt-everywhere-src-5.15.2解压之后你会看到一堆模块目录qtbase、qtdeclarative、qtgraphicaleffects、qtimageformats、qtmultimedia、qtquickcontrols2、qtserialport、qttools、qttranslations、qtwayland等等。Qt 5.15.2 是典型的多模块整合包编译时逐个模块来qtbase是最底层的核心必须先编译安装。这里有个实操细节不要直接在源码目录里执行./configure后再原地make虽然官方支持但你会把源码目录搞得很脏。我习惯在$QT_BUILD_ROOT/build下单独建一个构建目录也就是“out-of-source build”。mkdir -p $QT_BUILD_ROOT/build/qt-5.15.2 cd $QT_BUILD_ROOT/build/qt-5.15.2之后所有 configure、make 都在这个目录里执行源码目录保持干净方便以后对比补丁。2.2 configure 参数怎么给configure 是 Qt 构建的第一道关卡。参数给不好编译出来的库不是少功能就是编译到一半报错。我给 ARM64 UOS 桌面环境用的参数比较保守先保证能编译成功再谈裁剪../src/qt-everywhere-src-5.15.2/configure \ -prefix /opt/Qt/5.15.2 \ -opensource -confirm-license \ -release \ -nomake examples \ -nomake tests \ -xcb \ -xcb-xinput \ -bundled-xcb-xinput \ -no-sql-mysql \ -skip qtwebengine \ -skip qtwebview \ -skip qt3d \ -skip qtcanvas3d \ -skip qtdoc \ -skip qttools \ -ccache逐个说明这些参数-prefix /opt/Qt/5.15.2指定安装目录。建议统一装到/opt/Qt下后面 Qt Creator 配 Kit 时不容易搞混。-opensource -confirm-license选择 LGPLv3 或 GPLv2 开源协议。这里会交互式确认如果你不想手动按键这两个参数一起给就行。-release编译 release 版本。如果要调试 Qt 内部可以再加-debug但编译时间会翻倍先不用。-nomake examples -nomake tests不编译示例和测试省时间省磁盘。-xcb启用 X11 XCB 平台插件。UOS 桌面虽然很多场景走 Wayland但 X11 兼容还是主流这个插件必须开。-bundled-xcb-xinput使用 Qt 自带的 xcb input 模块避免系统库版本不匹配。-skip qtwebengine如果不需要内置浏览器内核一定要跳过。QtWebEngine 在 ARM 上编译极慢而且需要额外系统依赖。-skip qttools这里我要解释一下qttools 里包含 Qt Creator 相关工具链的一部分但我们现在是自己编译 Qt 库qttools 里的 designer、linguist 等工具可以后面单独装先跳过能减少编译量。如果你需要qtdiag、qdbus等编译完后再单独 make。configure 执行完之后仔细看输出Qt is now configured for building如果没有这段说明某个检查未通过。常见错误是找不到 xcb 相关头文件、找不到 OpenGL 库等先回头看 1.2 的依赖安装有没有漏。2.3 make 与 make install 的实际过程configure 通过后编译本身反而是最轻松的环节主要考验耐心。直接启动全核编译make -j$(nproc)ARM 板卡上nproc可能是 8 或更多但内存如果只有 8GB-j8很可能直接 OOM。我遇到过cc1plus: out of memory的情况。稳妥起见先看内存free -h如果内存小于 16GB建议make -j4编译时间看具体板子RK3588 这类八核 ARM64 大概一两个小时老一点的芯片可能要四五个小时。我习惯把日志写进文件编译完再翻make -j4 21 | tee $QT_BUILD_ROOT/build/qt-build.log如果不小心断开了终端可以直接查看日志最后几行判断进度tail -n 20 $QT_BUILD_ROOT/build/qt-build.log编译完成后安装sudo make installinstall会把所有头文件、动态库、插件、工具拷贝到/opt/Qt/5.15.2。检查一下/opt/Qt/5.15.2/bin/qmake -v输出类似QMake version 3.1 Using Qt version 5.15.2 in /opt/Qt/5.15.2这一步成功后Qt 库本身已经能用了。接下来做 Qt Creator 定制把它接进这套新环境。3. Qt Creator 定制与 Qt 版本绑定3.1 定制前想清楚要改什么很多人一听“定制 Qt Creator”就以为是改源码重编译其实大多数团队真正需要的定制是这几类默认的项目构建套件Kit让它自动指向新编译的 Qt 5.15.2。默认项目路径、作者信息、版权模板。外部工具里预设编译部署脚本。界面主题、字体、快捷键风格。插件目录只加载需要的插件。只有当你确实需要修改 Qt Creator 的 C 功能时才需要自己编译 Qt Creator 源码。绝大多数场景用配置文件和插件就足够。先讲最简单也最常用的给 Qt Creator 配置一个独立的 Qt Version 和 Kit指向我们编译出来的/opt/Qt/5.15.2。打开 Qt Creator依次进入“工具” - “选项” - “Kits” - “Qt Versions”点击“添加”选择/opt/Qt/5.15.2/bin/qmake。Qt Creator 识别后会自动读取 Qt 版本号。然后到“编译器”页确认使用的是系统的gcc/g。UOS ARM64 上默认编译器一般是which gcc which g通常是/usr/bin/gcc和/usr/bin/g架构是 aarch64-linux-gnu不用额外配置。最后在“Kits”页点“添加”名称建议写成UOS-ARM64-Qt5.15.2Qt 版本选上一步添加的 5.15.2编译器选 gcc/gCMake 工具选系统自带或你自己装的。确认无误后这个 Kit 就能直接用了。3.2 定制 Qt Creator 的默认工程模板与脚本工程模板是在 Qt Creator 新建项目时看到的那些向导。默认模板在 Qt Creator 安装目录的templates目录下源码仓库对应的目录是share/qtcreator/templates。如果你用 UOS 软件源直接装的 Qt Creator模板位置一般在/usr/lib/qtcreator/share/qtcreator/templates自定义方式有两种一种是直接改模板文件里的占位符默认值另一种是把整个模板目录拷贝出来在设置里加载。实操中我用得最多的是预置头文件路径、版权注释格式、作者信息。比如 C 头文件模板里一般有// Copyright (C) %YEAR% %USER%%USER%默认是环境变量里的用户名如果想统一改成公司名或团队名可以修改 Qt Creator 启动环境或者在模板里直接写固定字符串。如果你不想动系统目录更好的做法是写一个外部工具脚本。比如新建项目后自动创建build目录并运行#!/bin/bash mkdir -p build-arm64 cd build-arm64 /opt/Qt/5.15.2/bin/qmake .. make -j4在 Qt Creator “工具”-“外部”-“配置”添加一个工具命令指向这个脚本工作目录设为%{CurrentProject:Path}。这样每次点击外部菜单就会按照定制流程构建当前项目。3.3 自己编译 Qt Creator 的路线如果确实需要改 Qt Creator 源码比如改欢迎页、改插件行为、或者增加自定义构建步骤你需要下载对应版本的 Qt Creator 源码。Qt Creator 的源码和 Qt 版本最好匹配。Qt 5.15.2 对应比较稳妥的是 Qt Creator 4.14 系列。下载方式cd $QT_BUILD_ROOT/src git clone --branch v4.14.2 https://code.qt.io/qt/qtcreator.git如果没有code.qt.io的访问条件也可以从 GitHub 镜像下载对应 tag。源码目录里有一个dependencies脚本可以先看cd qtcreator cat scripts/install-dependencies.sh编译 Qt Creator 4.14 需要 CMake、Ninja还有 Qt 5.15 的开发头文件。因为我们已经把 Qt 装到了/opt/Qt/5.15.2CMake 可以直接通过CMAKE_PREFIX_PATH找到依赖cmake -S . -B build \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_PREFIX_PATH/opt/Qt/5.15.2 \ -DCMAKE_INSTALL_PREFIX/opt/qtcreator-custom然后编译安装cmake --build build -j4 sudo cmake --install build启动定制版/opt/qtcreator-custom/bin/qtcreator需要注意Qt Creator 的源码比较大编译也会比较久。而且这个项目对 Qt 头文件和编译器版本敏感如果编译时遇到语法错误先看是不是 GCC 版本过老或过新导致的再考虑改源码。对于大多数需求我仍然建议别直接编 Creator 源码把精力花在配置管理和构建脚本上性价比更高。3.4 把定制成果分发到其他机器在 ARM 环境下开发机一般不是只有一台经常要把 Qt 环境和 Qt Creator 配置搬到别的机器上。Qt 库部分简单直接打包cd /opt sudo tar czf Qt-5.15.2-arm64.tar.gz Qt/5.15.2到了新机器上解压到同样位置sudo tar xzf Qt-5.15.2-arm64.tar.gz -C /opt但要注意动态库路径。Qt 编译时如果-prefix /opt/Qt/5.15.2在编译生成的.pc文件和qmake里记录的底层路径就是/opt/Qt/5.15.2如果你把它解压到别的位置qmake 还能用但很多内部路径变量会错位。所以同架构分发时尽量保持/opt/Qt/5.15.2一致。Qt Creator 的配置分发要复杂一些常规方案是备份~/.config/QtProject目录tar czf qtcreator-config-backup.tar.gz ~/.config/QtProject这里的配置保存了 Qt Version、Kits、快捷键、外部工具和插件配置。拷贝到新机器后覆盖同路径再启动 Qt Creator基本就和原机器一致。如果外部工具脚本里引用了绝对路径比如/opt/Qt/5.15.2/bin/qmake也要保证新机器上路径相同。这是 ARM 环境定制分发时最容易忽略的坑。4. 常见报错与排查手册4.1 configure 阶段高频问题Configure 阶段报错集中在缺依赖上。我整理了几类最常见的报错关键字原因解决Basic XLib functionality test failedxcb 或 xcb-image 相关开发包缺失安装libxcb1-dev libxcb-util0-dev libxcb-shm0-devCould not find libGLOpenGL 开发库缺失安装libgl1-mesa-dev libglu1-mesa-devThe OpenGL functionality test failed显卡驱动或 EGL 库缺失安装libegl1-mesa-dev并检查-opengl参数Can not find feature xcb-xinput系统缺少 xcb-xinput 模块使用-bundled-xcb-xinput或者安装对应包ERROR: Unknown module(s) in QT: x11extrasqtbase 版本过旧或没启用在 configure 里加上-xcb后再配置有个技巧是看 configure 生成的config.loggrep -n error config.log | tail -n 30这个文件会记录每个检测命令的具体输出能直接看到是哪个函数没找到、哪个头文件缺了。如果 UOS 的 apt 源里缺某个特定开发包不要死磕可能是包名不一样。先搜apt search libxcb找出最接近的包名再安装。4.2 make 编译阶段崩溃处理编译阶段崩溃原因比 configure 要复杂但规律更强。第一种是内存不足。症状是cc1plus: out of memory或者Killed进程消失。解决办法是降低并发数或者临时增加 swapsudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfileARM 板卡内存不够是常态这个临时 swap 方案在编译*后及时关掉不然会影响 eMMC 寿命。第二种是编译器与源码不兼容。比如某些 GCC 版本对 C17 特性支持不完整导致 Qt 源码里报一堆模板错误。UOS ARM 上自带的 GCC 一般够用但如果报语法错误先确认版本gcc --versionGCC 8 以下编译 Qt 5.15.2 会比较吃力最好升级到 GCC 9 以上。第三种是磁盘占满。df -h看一下如果/满了清理一下$QT_BUILD_ROOT下的中间文件或者把构建目录移到更大的分区。4.3 运行 Qt 程序找不到平台插件编译完 Qt 后直接用命令启动一个 Qt 程序可能遇到qt.qpa.plugin: Could not find the Qt platform plugin xcb in 这个错误 90% 是平台插件路径没找到。Qt 程序在运行时用QApplication查询插件路径如果QT_QPA_PLATFORM_PLUGIN_PATH没有指向 plugins/platforms就会报这个。解决办法是把 Qt 库路径和插件路径写进启动脚本export QT_QPA_PLATFORM_PLUGIN_PATH/opt/Qt/5.15.2/plugins/platforms export LD_LIBRARY_PATH/opt/Qt/5.15.2/lib:$LD_LIBRARY_PATH如果系统和 xcb 库版本不匹配可能还会额外提示缺少libxcb-xinerama.so.0这类库直接在系统里装对应的运行时库就行。还有一类场景是纯命令行环境或远程桌面下没有 OpenGL会显示警告Could not initialize GLX这时可以临时用 offscreen 平台export QT_QPA_PLATFORMoffscreen不过这只是测试用做界面开发还是要有正常图形环境。4.4 Qt Creator 找不到自定义 Qt 版本这是配置 Kit 时最常见的问题你明明把/opt/Qt/5.15.2/bin/qmake加进 Qt Version但创建项目时列表里没有新 Kit。排查步骤确认 qmake 是否真的可执行直接运行/opt/Qt/5.15.2/bin/qmake -v。确认 Qt Creator 版本是否太老老版本 Creator 可能读不了新 qmake 的版本信息。删除 Qt Creator 的缓存关闭 Creator删除~/.config/QtProject/qtcreator/qmlCache或~/.cache/QtProject重启再试。检查权限/opt/Qt/5.15.2如果只有 root 可读普通用户下 Qt Creator 看不到 qmake 也很正常。用ls -l /opt/Qt/5.15.2/bin/qmake看一眼权限不行就chown或chmod.如果 Qt Creator 是从 UOS 软件源装的它自己的 Qt 版本比较低也可能对新 Qt 的 ABI 有兼容问题这时最好用新版 Creator 或者自己编译的 Creator。5. 跨架构扩展、维护心得与一些个人经验5.1 ARM64 下的增量编译与缓存加速Qt 是大型项目每改一次配置全量重编非常痛苦。ARM 开发机性能有限推荐做好增量编译。我的习惯是第一次编译全量做完后后续如果只是加一个模块不要重新 configure 整个源码树。Qt 5.15.2 支持按模块单独构建比如只编 qtserialportcd $QT_BUILD_ROOT/build/qt-5.15.2/qtserialport make -j4 sudo make install前提是你第一次 configure 时没有把它-skip掉。另外 configure 参数里加-ccache基本的重复编译会快很多sudo apt install ccacheccache 的默认缓存路径在~/.cache/ccache编译时不够用可以调大ccache -M 10G这个操作对日常 ARM 开发特别值得因为同一个 Qt 源码可能在多台开发机上反复构建。5.2 交叉编译与原生编译的不同如果你后续是要给更小的 ARM 设备(比如 rk3328 或基于 Cortex-A53 的嵌入式板卡)做应用可能想直接在 UOS ARM 开发机上做“本地编译”避免交叉编译带来的 sysroot 依赖问题。这个思路没问题UOS ARM 跑着完整的桌面环境所有 Qt 依赖库都能直接装编译出来的程序直接拷到目标板上运行只要目标板的系统库版本相差不大基本能跑。但如果你目标设备的系统盘空间极小、不带桌面环境那原生编译可能不适合因为 Qt 依赖的 X11/XCB/OpenGL 库目标板一并不存在。这种情况就要回到交叉编译路线在 UOS ARM 开发机上用同样的 Qt 源码配置一个 sysroot使用 aarch64 交叉工具链但目标平台还是 ARM64。这里有个很现实的问题如果开发机本身是 ARM64而目标板也是 ARM64那其实没必要做跨架构交叉编译直接原生编译然后把二进制和依赖库打包过去反而更省事。只有开发机是 x86_64、目标板是 ARM64 时才需要真正意义上的交叉编译。你在网上会看到很多人讨论 ARM 交叉编译但 UOS ARM ARM 目标板这个场景原生编译是更符合直觉的方向。5.3 版本记录、补丁管理和环境备份源码编译 Qt 最怕的是编了一次成功半年后想重新构建却忘记当初用了哪些参数。我强烈建议把 configure 参数和手工 patch 记录下来放到一个文档或脚本里。我自己的做法是建一个build-env/目录里面四个文件configure-args.txt记录 configure 的全部参数。system-deps.txt记录 apt 安装的依赖包列表。patches/记录所有对 Qt 源码的手工补丁。install.sh把上面三个文件串联起来一键复现整个构建过程。这个习惯在团队配合时尤其关键。别人拿到你的 Qt 包能跑但不知道你怎么编的出了问题无从下手。有了这份记录任何一台新的 ARM64 UOS 开发机都能十分钟内重新开始构建。还有一个很值得养成的习惯每完成一个阶段的构建就用 tar 打包整个/opt/Qt目录到外部存储。Qt 安装目录本身没有机器绑定关系拷贝到同架构机器上解压就能用这是 ARM 环境最可靠的环境备份手段。5.4 结尾说几句实在话这个流程本身不算高端技术但细节异常密集。ARM 架构上编译 Qt 5.15.2和 x86 上好大区别是内存和 I/O 性能更紧张动不动就卡在out of memory所以不要盲目追求-j数值。UOS 的软件源更新不像某些发行版那么激进依赖包的版本比较固定反而是好事确认一次依赖后后面很少变。我实际用过几套不同 ARM64 板卡性能好的编译快一些性能差的就慢慢等但最后出来的 Qt 环境只要配置一致行为基本一致。这也是我特别推荐大家把 Qt 和 Qt Creator 都固定到自建路径的原因不依赖系统包的变动后续做 CI、批量部署、多设备同步都会省心很多。如果你第一次编译就成功了恭喜你你有一台可用的 ARM64 Qt 开发环境了。如果中间失败了不要慌把日志翻出来对着第 4 节排查绝大多数问题都卡在那几张表里。下次再编译新版本 Qt 时你会发现自己比第一次从容得多。
返回列表