news 2026/10/28 17:57:48

Kylin ARM64 源码编译 Qt 5.12.10 实战:依赖、配置与排障

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kylin ARM64 源码编译 Qt 5.12.10 实战:依赖、配置与排障

简介:面向国产化 ARM64 桌面环境的 Qt 开发场景,这份已编译产物对应麒麟桌面版 V10 GFB 020 系统,并针对联想昭阳 N4720Z 完成 Qt 5.12.10 的适配与可用性验证,适合需要在麒麟系统上开展 C++/Qt 图形界面开发、应用移植、依赖排查和环境核对的开发者与维护人员参考。压缩包共 2000 个文件,以 .h 头文件为主体,涵盖核心、图形界面、OpenGL、QML、网络、XML、多线程及平台适配等模块接口声明,同时保留 qmake 和可供 Qt Creator 识别的目录组织,包体约 84.62MB,便于按模块查找所需头文件和版本信息。已有 1075 人学习下载,在国产 ARM64 平台 Qt 环境资料中具有一定参考价值。读者可据此核对 Qt 版本匹配、头文件依赖、编译套件组织与接口完整性,减少从源码编译、交叉适配和兼容性验证所耗费的时间,也能为后续界面程序调试与迁移提供可对照的目录样本。

1. 在 ARM64 的 Kylin 上编出 Qt 5.12.10

在 Kylin-Desktop-V10-GFB-Release-020-ARM64 上把 Qt 5.12.10 从源码编出来,听上去只是 configure 加 make 几步,真正动手的人多半会在 xcb 依赖和内存上卡两个晚上。这份资源就是那次编译的落地记录:一套在 Kylin V10 ARM64 整机上验证通过的 Qt 5.12.10 配置参数、依赖清单和产物布局,配 qmake 与 Qt Creator 的接入方式。

它要解决的主要是“要一份版本、路径都自己说了算、又不跟系统包打架的 Qt”,并非“能不能用 Qt”这种问题。适合给 ARM64 桌面做客户端交付的、被系统自带 Qt 版本限制住的、以及接手整机厂商定制镜像还没摸清工具链的人。

下面按顺序走:量环境、定 configure、编译安装验证,最后把踩过的坑摊开。

2. 编译前把环境量清楚:ARM64 上必须确认的四件事

在 x86 上编 Qt,很多人靠试错也能走通;到 ARM64 桌面这套镜像上,试错的代价会翻好几倍,因为可选依赖包不全、gcc 版本偏新、机器内存普遍不大。所以第一步要做的是把“这台机器到底是什么”写成可复查的输出,而非直接下载源码包,后面所有报错才有对照基准。

我一般会把下面这几条命令的输出直接贴到一个env.log里存着,出问题时回头翻,比凭记忆猜快得多。

2.1 系统版本、架构与工具链摸底

先把架构、发行版、编译器三样钉死,这三样任意一个对不上,后面的 configure 参数就全是白写。

# 1) 架构必须是 aarch64;出现 armv7l 说明下错了镜像或装错了 rootfs uname -m # 2) 发行版与版本号,查资料、对包名时要用 head -n 4 /etc/os-release # 3) 工具链版本,gcc 7 以上要注意 C++ 标准库头文件不再隐式包含 gcc --version | head -n 1 ld --version | head -n 1 make --version | head -n 1 # 4) 并行度与资源,决定后面 make -j 给多少 nproc free -h df -h /opt /usr /home

逻辑说明:uname -m返回aarch64才是我们要的 64 位 ARM 环境;如果返回armv7l,说明系统是 32 位的,Qt 5.12.10 的很多模块在 32 位 ARM 上编译会缺原子操作支持,直接放弃这条路更省时间。gcc --version最关键,Kylin V10 桌面版常见搭配是 gcc 7 到 gcc 9,gcc 7 之后 C++ 标准库做了清理,<limits>、<cstdint>这类头文件不再被间接包含,Qt 5.12 的部分子模块源码会因此报错,这属于“已知要打补丁”的范畴,不是你的配置写错了。

nproc和free -h一起看:ARM64 桌面机器常见 4 核 4G 或 8 核 8G,前者直接make -j4基本必被 OOM killer 杀掉,后面 4.1 节会讲怎么定这个数。

2.2 依赖清单:一次装齐,别让 configure 一点点暴露缺失

Qt 的 configure 是“缺什么报什么”的模式,但报的顺序不固定,你想一次装齐就得对着模块去凑包。下面这份列表是我在 Kylin V10 ARM64 上实际装通过的一组,覆盖了 xcb 平台插件、字体、OpenSSL、D-Bus、音频、打印这几条主线。

sudo apt update sudo apt install -y \ build-essential perl python3 git ccache pkg-config \ libgl1-mesa-dev libglu1-mesa-dev libegl1-mesa-dev \ libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev \ libxcb1-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev \ libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev \ libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev \ libxcb-xinerama0-dev libxcb-xkb-dev libxcb-util0-dev \ libxkbcommon-dev libxkbcommon-x11-dev \ libfontconfig1-dev libfreetype6-dev \ libssl-dev libsqlite3-dev libicu-dev libdbus-1-dev \ libasound2-dev libpulse-dev libcups2-dev \ libpng-dev libjpeg-dev libtiff-dev \ flex bison gperf

分组解释一下,方便你按需裁剪:build-essential perl python3 git是构建底座,Qt 的构建系统大量用 perl 脚本和 python 生成代码;以libxcb-开头的那一大串对应 xcb 平台插件,只要缺一个,编译阶段未必报错,但运行时会以“找不到 xcb 插件”的形式暴露,最难排查;libfontconfig1-dev和libfreetype6-dev决定中文字体能不能正常 fallback,少了它们编译能过,界面里的中文却会变成方块;libssl-dev给网络模块用,libdbus-1-dev、libasound2-dev、libcups2-dev分别对应单实例、多媒体和打印。

提示:麒麟的软件源里个别包名和 Debian 不完全一致,比如libxcb-util0-dev在部分版本里叫libxcb-util-dev。装不上时用apt-cache search xcb | grep dev对照一下,不要凭记忆硬装。

装完可以用一条命令自查关键包是否落地:

for p in libxcb-xinerama0-dev libxkbcommon-x11-dev libfontconfig1-dev libssl-dev; do dpkg -s "$p" >/dev/null 2>&1 && echo "OK $p" || echo "MISS $p" done

这段循环就是在dpkg的数据库里查这四个包的状态,OK打头的留下了,MISS打头的补装。看起来笨,但比等到运行时闪退再回头翻依赖强。

2.3 目录、磁盘与内存:给编译留够 30G 和 4G 交换

Qt 5.12.10 完整源码解压后约 2G 出头,但中间产物非常占地方。不开子模块裁剪的话,编译目录能涨到 20G 以上;我习惯按下面这个布局来分,好处是源码树永远干净,出问题直接删构建目录重来,不需要make distclean那种慢操作。

路径用途建议预留
/opt/src/qt-everywhere-src-5.12.10解压后的源码,只读不动3 GB
/opt/build/qt-5.12.10影子构建目录,所有中间产物25 GB
/opt/qt/5.12.10最终安装前缀4 GB
~/.ccache二次编译缓存,可选5 GB
sudo mkdir -p /opt/src /opt/build/qt-5.12.10 /opt/qt sudo chown -R "$USER":"$USER" /opt/src /opt/build /opt/qt # 内存不足 8G 的机器,先挂 4G 交换文件,比改 -j 更省心 sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile free -h

说明一下参数:fallocate -l 4G是预分配 4G 空间,比dd快很多;chmod 600是swapon的硬性要求,权限过宽会拒绝加载;swapon只对本次开机生效,要持久化得写进/etc/fstab,但编译机我一般不加,用完就swapoff删掉,免得长期占用。chown那一步是为了后面不用全程sudo make。在 ARM64 桌面机上用 root 编 Qt 会带来另一个麻烦,构建目录里的文件属主全变成 root,后面再想改源码就得一路 sudo。

3. configure 那一行怎么写:六个开关在 ARM64 上的取舍

configure 是整件事的分水岭。参数写宽了,编译三小时内存爆掉;写窄了,装完发现少个模块又得重来。下面这几个开关是我在这套镜像上反复调整后确定下来的组合,逐个说清楚为什么这么定。

3.1 平台 spec 与安装前缀

-platform linux-g++表示本机编译,用的是系统自带的 gcc。这里最常见的误解是把交叉编译那套-device和-device-option CROSS_COMPILE=aarch64-linux-gnu-混进来。如果你确实是在 x86 机器上给 ARM64 目标板编,那才需要设备 spec;我们这次是在 ARM64 机器上原生编译,多写反而会让 configure 去找不存在的工具链前缀。

-prefix /opt/qt/5.12.10是安装前缀,决定qmake -query里那一串路径。这里有个容易被忽略的点:-prefix写的是安装后的最终路径,make install之前的编译产物都在构建目录里。如果你打算编完打包拷到另一台机器,还要额外用-extprefix,否则装出来的 qmake 会把路径写死成/opt/qt/5.12.10,换台机器就找不到插件。

-release配合-no-pch是我在 4G 内存机器上的常用组合。预编译头能把编译速度拉起来,代价是单个编译单元的峰值内存高不少;在内存紧张的 ARM64 桌面上,宁可慢一点也别被 OOM 打断,因为中断之后你还得判断是编译错误还是内存问题,纯属给自己加活。

3.2 模块裁剪:先跳掉最贵的三个

Qt 5.12.10 的qt-everywhere包里包含几十个模块,其中qtwebengine基于 Chromium,在 ARM64 上编译要额外一堆依赖,构建目录能吃掉十几 G,而且跟大多数客户端项目没关系。qtwayland在你确定只在 X11 会话下跑的时候也是纯负担。qtwebview是给移动端用的封装,桌面场景基本没用。

-skip qtwebengine -skip qtwayland -skip qtwebview \ -nomake examples -nomake tests

-nomake examples和-nomake tests只控制“不构建示例和测试”,源码还在,模块本身照编。这两个开关能省掉相当可观的时间,而且示例工程往往会引入额外的依赖检查,属于纯粹的风险源。

注意:-skip掉的模块在make install之后就是真的没有,后面想补只能单独进模块目录编译,再装到同一个前缀下。所以哪些模块该留要先想清楚,尤其是qtmultimedia、qtwebchannel这类要用到的别顺手 skip。

3.3 图形与字体后端:xcb、opengl、fontconfig 怎么定

xcb 这块有两个方向:默认链接系统的 libxcb,或者加-qt-xcb用 qtbase 里自带的 xcb 源码一起编。两者的差别在于“依赖谁的版本”。用系统库,要求你把 2.2 节那一串-dev包装齐,好处是和系统其它 X11 程序行为一致;用-qt-xcb,系统依赖少一些,但自带的那份 xcb 子模块集合是固定的,缺xcb-xinerama之类的模块时会在链接阶段报undefined reference,而且报错信息很不直观。

我的做法是:先不加-qt-xcb,把系统依赖装齐。只有在系统源实在装不全的情况下,才退回去用它。后面 5.1 节有一条专门讲这个坑。

-opengl的取值要看目标机的驱动。桌面 ARM64 机器通常有完整的 GL 驱动,默认的 desktop GL 就行;如果目标机只有 GLES 驱动(一些精简的嵌入式镜像会这样),改成-opengl es2。这个参数写错的表现不是编译失败,而是运行时报“无法创建 OpenGL 上下文”,排查起来要绕一圈。

-fontconfig必须加。加了之后 Qt 走系统的字体配置,中文才能按 fontconfig 的规则找到 fallback 字体;不加的话 Qt 用内置逻辑,在只有几个字体的精简镜像上,界面文字很容易变成方块。这条在交付给客户之前一定要验证,别等验收现场才发现。

-openssl-runtime是默认行为,意思是运行时用 dlopen 加载系统的 OpenSSL,编译期不建立 ABI 绑定。对应的-openssl-linked会把 OpenSSL 静态绑进去,系统一升级 OpenSSL 就可能出问题,除非有明确要求,否则不建议开。

汇总成表更直观:

参数本次取值选它的理由
-prefix/opt/qt/5.12.10不污染/usr,卸载等于删目录
-platformlinux-g++本机原生编译,不用交叉工具链前缀
-release开交付用,不要调试符号
-no-pch开压低单编译单元峰值内存
-skipwebengine / wayland / webview省时间省磁盘,桌面项目用不到
-nomakeexamples / tests减少无谓构建和额外依赖
-fontconfig开中文 fallback 的唯一可靠路径
-openssl-runtime开避免和系统 OpenSSL 的 ABI 绑定
-system-sqlite可选少编一份 sqlite,前提是系统版本够新

3.4 完整配置脚本与日志自检

把上面这些拼起来,就是实际执行的这一条。注意cd到的是独立的构建目录,源码树保持只读,这是影子构建的基本要求。

cd /opt/build/qt-5.12.10 /opt/src/qt-everywhere-src-5.12.10/configure \ -prefix /opt/qt/5.12.10 \ -opensource -confirm-license \ -release \ -platform linux-g++ \ -nomake examples -nomake tests \ -skip qtwebengine -skip qtwayland -skip qtwebview \ -fontconfig \ -openssl-runtime \ -system-sqlite \ -no-pch \ 2>&1 | tee configure.log

-opensource -confirm-license是自动接受开源许可,不加会停在交互式确认上,脚本化构建时容易卡住。2>&1 | tee configure.log把 stderr 合并进 stdout 再同时写文件和终端,这一步很重要:configure 的依赖检测结果大部分打在 stderr 上,不合并的话日志里会缺一大块。

configure 跑完(通常几分钟)不要急着 make,先看三处。

# 1) 显式报错,任何一条都要处理 grep -inE "error|cannot find|not found" configure.log | head -n 30 # 2) 构建选项表,确认关键项是 yes grep -iE "xcb|fontconfig|openssl|sqlite|opengl" configure.log | grep -iE "yes|no" | head -n 20 # 3) 结尾摘要,最后一行正常应该是 "Qt is now configured for building" tail -n 20 configure.log

第一处是硬伤,not found出现但对应的是可选依赖时可以放过,出现error就必须处理。第二处看的是构建选项表,-fontconfig那行如果显示no,说明头文件没装上,装完得重新 configure,不能直接 make。第三处是最终结论,结尾没有那句 “Qt is now configured for building” 就说明中途退出了,tail往上多翻几行能看到真正的原因。

4. 从 make 到第一个窗口:并行度、安装前缀与冒烟测试

configure 通过只代表“参数被接受了”,真正的考验在 make。这一章把并行度怎么定、装完目录长什么样、环境变量怎么隔离、以及怎么用二十行代码验证整条链路走通,一次讲完。

4.1 并行编译与 OOM 的边界

并行度不是越大越好,在 ARM64 桌面上它是“内存 / 每核峰值”的除法。经验值是每个 g++ 进程编 Qt 的大文件时峰值在 1.2G 到 1.5G 之间,所以 4G 内存的机器最多-j2,8G 给-j4,16G 再考虑-j8。

# 先看当前可用内存和交换 free -h # 保守起步,出问题再往下调 make -j2 2>&1 | tee build.log

tee同样是必须的,因为编译几十分钟,终端缓冲区留不下全部输出,出问题时你只会看到最后几十行。真要定位,还得靠日志。

如果 make 中途退出,先别急着看编译错误,先确认是不是被系统杀的:

dmesg | tail -n 20 | grep -i -E "killed process|out of memory"

出现Out of memory: Killed process ... (cc1plus)就说明是内存不够,跟代码本身无关。这时候的处理顺序是:先降-j,再考虑加交换分区,最后才是关掉一些模块。反过来,如果是真正的编译错误,make会明确打印error:行,这时候重跑make -j1能让报错顺序和文件对应关系更清楚。

好消息是中断之后不需要清空重来。Makefile 的依赖关系还在,直接再执行一次make会从断点续编,前面编好的目标文件不会重做。

4.2 make install 之后的目录结构与 qt.conf

编译完成(ARM64 上 4 核机器大概几小时量级)就可以安装了。这一步会往/opt/qt/5.12.10写文件,如果之前目录属主给的是当前用户,不需要 sudo。

make install 2>&1 | tee install.log # 看关键路径有没有到位 ls /opt/qt/5.12.10 ls /opt/qt/5.12.10/bin | head ls /opt/qt/5.12.10/plugins/platforms

装完之后你会看到这么几个关键位置:bin/qmake是构建入口;lib/libQt5Core.so.5等是运行库;plugins/platforms/libqxcb.so是 X11 平台插件,所有“界面起不来”的问题最终都要回到这个文件;mkspecs/里是编译规则,Qt Creator 配 kit 时要用到;qml/下是 QML 模块,用到 Qt Quick 的项目必须把QML2_IMPORT_PATH指过来。

如果你要把这份 Qt 打包到另一台同架构机器上用,路径可能对不上,这时候在bin/同级放一个qt.conf就能把路径改成相对形式:

[Paths] Prefix = .. Plugins = plugins Libraries = lib Qml2Imports = qml

Prefix = ..是相对于 qmake 自身所在目录的上级,也就是安装根目录。这样整个目录被搬到任何位置,qmake 都能算对路径。这个技巧在交付现场很实用,尤其是客户机器上没有/opt写权限的时候。

4.3 环境变量脚本与环境隔离

装好之后第一件事是确认qmake -query报的路径对不对。这一步要注意 PATH 顺序,系统里本来就有一份 Qt,qmake很可能是系统那个。

/opt/qt/5.12.10/bin/qmake -query # 关键几项应该是: # QT_INSTALL_PREFIX -> /opt/qt/5.12.10 # QT_INSTALL_PLUGINS -> /opt/qt/5.12.10/plugins # QT_VERSION -> 5.12.10

确认无误后写一个环境脚本,只在需要的时候 source,不要往全局环境里塞:

cat > ~/qt512.env <<'EOF' export QT512=/opt/qt/5.12.10 export PATH=$QT512/bin:$PATH export LD_LIBRARY_PATH=$QT512/lib:$LD_LIBRARY_PATH export QT_PLUGIN_PATH=$QT512/plugins export QML2_IMPORT_PATH=$QT512/qml EOF source ~/qt512.env which qmake # 必须指向 /opt/qt/5.12.10/bin/qmake

逐行说明:PATH放最前面是为了让qmake、moc、uic优先命中这一份;LD_LIBRARY_PATH让编译出来的可执行文件优先加载这一份libQt5Core.so.5;QT_PLUGIN_PATH强制插件从这个前缀下找,避免和系统插件目录混淆;QML2_IMPORT_PATH只在用 Qt Quick 时需要。

注意:不要用ldconfig把/opt/qt/5.12.10/lib写进全局搜索路径。系统里其它依赖自带 Qt 的桌面程序会跟着换库,症状是那些程序莫名其妙崩掉,而且很难联想到是你装 Qt 引起的。用环境脚本按需注入,或者干脆用 rpath 固化到可执行文件里,都比动全局配置安全。

4.4 冒烟测试:二十行代码验证整条链路

验证不能只看qmake -v,那只能证明二进制能跑。真正要验证的是:头文件能找到、库能链上、插件能加载、界面能起来。写个最小 demo 一次过完。

mkdir -p ~/qtdemo && cd ~/qtdemo cat > main.cpp <<'EOF' #include <QApplication> #include <QLabel> #include <QSysInfo> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 把版本号和 CPU 架构打到窗口上,肉眼确认没加载到系统那份 Qt QLabel w(QStringLiteral("Qt %1 on %2") .arg(QString(QT_VERSION_STR), QSysInfo::currentCpuArchitecture())); w.resize(380, 120); w.show(); return app.exec(); } EOF cat > qtdemo.pro <<'EOF' QT += widgets TARGET = qtdemo SOURCES += main.cpp EOF /opt/qt/5.12.10/bin/qmake qtdemo.pro make -j2

窗口里如果显示Qt 5.12.10 on arm64,说明头文件、链接库、版本三样全对。如果显示的是别的版本号,说明链接时用的是系统库,回去检查LD_LIBRARY_PATH和下面的ldd。

在没有图形会话的环境里(比如 ssh 登录、CI 容器),用 offscreen 平台插件跑一遍,同样能验证插件加载链路:

./qtdemo & # 有桌面时走这条 QT_QPA_PLATFORM=offscreen ./qtdemo & # 无桌面时走这条 # 确认链接的是自编译的库,不是系统库 ldd ./qtdemo | grep -i qt5

ldd的输出里每一行 Qt 库都应该指向/opt/qt/5.12.10/lib/。如果有指向/usr/lib/aarch64-linux-gnu/的,那就是版本混用了,后面运行时会以各种诡异方式出问题。

在麒麟上还有一个高频小坑:用sudo ./qtdemo测试时窗口起不来,报QXcbConnection: Could not connect to display。原因是 sudo 切换用户后DISPLAY和XAUTHORITY丢了。要么用sudo -E保留环境,要么就老老实实用普通用户测,别拿 root 去验图形程序。

5. 避坑与排查:编译期最容易翻车的五个点

这几条都是我在 ARM64 麒麟桌面上真实撞过的,按“现象 → 原因 → 解决”整理,遇到同类症状可以直接对号入座。

5.1 依赖与链接:报错信息最不直观的一类

第一条:运行时报Could not load the Qt platform plugin "xcb"

现象:程序编译链接全过,一运行就打印qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.,然后Aborted。

原因:这句提示有误导性,“even though it was found” 只说明文件存在,不代表它的依赖能满足。最常见的是libqxcb.so依赖的某个 xcb 子模块或libxkbcommon-x11.so.0在目标机上缺失;其次是QT_PLUGIN_PATH误指到系统 Qt 的插件目录,导致加载了版本不匹配的插件。

解决:先定位到底缺什么,别猜。

ldd /opt/qt/5.12.10/plugins/platforms/libqxcb.so | grep "not found" QT_DEBUG_PLUGINS=1 ./qtdemo 2>&1 | head -n 40

第一条命令列出缺失的.so,缺哪个装哪个;第二条让 Qt 打出插件搜索的完整路径和失败原因,能看到它到底扫了哪些目录。这两条一起用,这类问题基本十分钟内能定位。

第二条:链接阶段undefined reference to 'xcb_xinerama_query_screens'之类

现象:make 跑到链接某个模块时报一堆undefined reference to xcb_xxx,全是 xcb 相关的符号。

原因:configure 时加了-qt-xcb,用 qtbase 自带的 xcb 源码编译,但自带的子模块集合里没有你系统上用到的那个扩展;或者系统 libxcb 和自带版本混链,符号对不上。

解决:去掉-qt-xcb,改用系统 libxcb,同时把 2.2 节那一串libxcb-*-dev装齐,重新 configure。反过来,如果确定是系统源里实在没有某个包,就用-qt-xcb并接受它带来的模块裁剪,两者不要混着来。

5.2 编译中断:跟代码无关,跟机器有关

第三条:error: 'numeric_limits' is not a member of 'std'

现象:编译到qtdeclarative或qt3d时大量报这个错,同一个文件里往往还伴随'UINT_MAX' was not declared。

原因:gcc 7 之后,C++ 标准库不再间接包含<limits>、<climits>这些头文件。Qt 5.12.10 的部分源码写的时候没显式包含,在旧 gcc 下能过,在新 gcc 下就断。

解决:给报错的文件补上头文件。手动改几个文件太慢,我会用一段循环批量处理,改完继续make,已编好的目标不会重做:

cd /opt/src/qt-everywhere-src-5.12.10 # 找出用了 numeric_limits 但没包含 <limits> 的文件,在首行补 include grep -rl "std::numeric_limits" --include=*.h --include=*.cpp . | while read -r f; do grep -q "#include <limits>" "$f" || sed -i '1i #include <limits>' "$f" done

参数说明:grep -rl递归找文件只输出文件名;grep -q静默判断有没有包含过,避免重复插入;sed -i '1i'在第一行前插入。这类补丁只对源码副本生效,重新解压源码就得再打一次,所以打完记得留一份 diff。

第四条:g++: fatal error: Killed signal terminated program cc1plus

现象:make 跑到一半突然停,报错信息里没有error:,只有Killed signal terminated program cc1plus,重跑同一个位置又会挂,但换成-j1就过了。

原因:内存不足被内核 OOM killer 杀了编译器进程。ARM64 桌面机内存普遍不大,-j给大了必然撞上。

解决:先用dmesg | grep -i "killed process"确认,然后按 4.1 节的公式降-j,或者扩交换分区。这两条都不行,就在 configure 里加-no-pch再重来一遍,预编译头是峰值内存的大头。

5.3 运行时:编过了不等于跑对了

第五条:程序跑起来是系统那份 Qt 的行为

现象:qmake -v显示 5.12.10,但程序运行时报version 'Qt_5.15' not found,或者界面行为跟预期不一样,ldd一看库指向了/usr/lib/aarch64-linux-gnu/。

原因:LD_LIBRARY_PATH没生效、被别的脚本覆盖,或者可执行文件本身带着 rpath 指向系统库。麒麟桌面上还多一种情况:应用是从桌面图标双击启动的,那个环境跟你终端里的环境完全是两套,终端里 source 过的环境脚本对双击启动不生效。

解决:先看可执行文件自己的搜索路径,再决定是改环境还是改文件。

readelf -d ./qtdemo | grep -iE "rpath|runpath"

有RUNPATH就说明路径被写死在二进制里了。要么在.pro里加QMAKE_RPATHDIR += $$PWD/../lib重新链一次,要么用patchelf --set-rpath '$ORIGIN/../lib' ./qtdemo事后改。交付场景我更倾向后者,改完一个二进制就能跑,不用动客户机器的任何环境变量。至于双击启动的场景,最省事的办法是写个启动脚本,脚本里 source 环境再 exec 程序,桌面图标指向这个

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 17:57:37

USSD信令通道与USSDC会话机制及路由排障

简介&#xff1a;中国移动通信USSD应用接口协议系列企业标准文档&#xff0c;面向移动通信网络工程师、业务平台开发人员及通信专业师生&#xff0c;用于系统了解USSD业务从系统结构、组网方式到应用接口的实现要求。文档以QB-D-069-2009《USSD业务总体技术要求》为主线&#x…

作者头像 李华
网站建设 2026/10/28 17:57:14

YOLOv9低对比度目标检测优化:平滑CIoU损失函数实践

1. 项目背景与核心挑战在目标检测领域&#xff0c;YOLO系列算法因其出色的实时性能一直备受关注。YOLOv9作为最新一代版本&#xff0c;在保持高速推理的同时进一步提升了检测精度。但在实际工业应用中&#xff0c;我们发现当目标与背景对比度较低时&#xff08;如雾天监控、医学…

作者头像 李华
网站建设 2026/10/28 17:56:58

工业视觉漆面检测中的取图映射技术详解

1. 漆面检测技术概述在工业质检领域&#xff0c;漆面检测一直是汽车制造、家电生产等行业的关键环节。传统的人工目检方式存在效率低、标准不统一等问题&#xff0c;而基于机器视觉的自动化检测方案正在逐步替代人工。其中&#xff0c;取图映射逻辑作为检测系统的核心算法模块&…

作者头像 李华
网站建设 2026/10/28 17:56:38

微软Copilot新变革:超级App、按量计费到Copilot Studio全面解析

最近这一两个月&#xff0c;微软在 Copilot 上的动作快得让人有点跟不上节奏。先是 Office 那一堆熟悉的图标被重新整合成 Microsoft 365 这个“超级 App”&#xff0c;紧接着 Microsoft 365 Copilot 的计费方式也迎来了大改&#xff0c;从以前“每人每月固定交钱”的老路子&am…

作者头像 李华
网站建设 2026/10/28 17:54:07

Agentic选型避坑指南:gpt-6.1-sol实测与多模型路由实践

1. 从一条报错说起&#xff1a;Agentic 选型为什么突然成了热门话题最近在几个开发者社群里&#xff0c;反复出现同一条报错信息&#xff1a;the gpt-6.1-sol model is not supported when using codex with a chatgpt account。这条报错本身并不复杂&#xff0c;但它背后牵出的…

作者头像 李华
网站建设 2026/10/28 17:50:52

MATLAB实现ANFIS+PSO:粒子群优化初始参数的模糊系统实战

简介&#xff1a;这是面向Matlab用户的自适应神经模糊推理系统(ANFIS)与粒子群优化(PSO)融合实现代码包&#xff0c;解决ANFIS参数难以手动整定的问题。ANFIS结合了模糊推理的可解释性与神经网络的非线性学习能力&#xff0c;而PSO通过群体协作进行全局寻优&#xff0c;两者结合…

作者头像 李华