news 2026/9/25 4:54:00

银河麒麟ARM版离线搭建Qt5开发环境完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
银河麒麟ARM版离线搭建Qt5开发环境完整实战指南

最近在给客户交付一套基于Qt5的界面程序,目标平台是银河麒麟V10的ARM版,而且是完全的物理离线环境。折腾了整整两天,光是gcc和Qt5的依赖问题就来回撞了好几次墙。一边翻系统源一边手动补包,最后总算是把从编译器到Qt Creator的整条链路理顺了。这里把完整流程和踩过的坑一次性整理出来,给同样需要在银河麒麟ARM版上离线做Qt5开发的朋友做个参考。

这篇内容主要面向三类人:刚拿到麒麟ARM设备、准备从零搭建Qt环境的嵌入式开发者;需要在信创/隔离网环境下交付项目的工程团队;以及被“Qt5无法拖拽文件”“gcc升级后还是旧版本”这类问题折磨过、正在到处搜索解决方案的人。你不需要提前准备太多,只要有一台银河麒麟V10 ARM设备、一个可用的离线安装包来源(系统ISO镜像或另一台联网机器),按照下面的步骤就能把环境完整搭起来。

1. 开始之前:先搞清楚你拿到的到底是个什么环境

1.1 系统版本与CPU架构自查命令

很多人在第一步就走错了方向。拿到机器不问架构、不看系统版本,直接用一个x86世界里的安装包往ARM机器上怼,结果自然是各种not found和cannot execute binary file报错。银河麒麟V10有x86版也有ARM版,同样是“V10”,两者软件生态的安装方式差别非常大。

动手装任何东西之前,先执行下面三组命令,把系统的家底盘清楚:

# 查看操作系统具体版本和代号 cat /etc/os-release # 查看内核版本和架构 uname -a # 查看CPU架构详细信息 lscpu | grep Architecture

我在实际项目里拿到的是麒麟V10的ARM版,uname -m输出为aarch64,这说明系统跑的是64位ARM指令集。注意,aarch64和armv7l虽然都叫ARM,但前者是64位、后者是32位,软件包完全不通用。如果你是armv7l,下面讲到的arm64版deb包也用不了,需要单独找armhf版本。

另外用cat /etc/os-release看清楚系统基于哪个上游版本。银河麒麟V10有的基于Ubuntu,有的基于Debian,虽然包管理工具都是apt/dpkg,但软件源配置和依赖版本会有差异。我看到VERSION_CODENAME是focal,就知道它基本兼容Ubuntu 20.04的软件包,这为后面从联网机器拉取deb包提供了重要依据。

1.2 判断离线程度:三种网络形态决定安装策略

“离线安装”这个词其实很笼统,不同离线程度对应完全不同的操作路线。我先根据现场情况把离线环境分为三类,你对照自己手头的机器来判断:

  • 完全物理隔离:机器不出网,没有内网源,只有一个U盘或光盘可用。这种情况最麻烦,所有软件包都得提前在外面准备好。
  • 有内网软件源:机器能访问公司内部的apt源,只是不能上外网。这种情况最简单,直接改一下sources.list指向内网源,apt install基本畅通无阻。
  • 无源但有系统ISO镜像:机器不能联网,但是你有银河麒麟的安装光盘或ISO文件。这中等情况可以通过挂载ISO搭建一个本地源,装gcc、基础Qt5库都没问题。

我这次的现场属于第一种,机器连内网源都没有,只有一个清明上河图一样的ISO镜像。所以下面的方案会以“有ISO”和“无ISO”两条线来讲,一条是挂载ISO搭本地源,另一条是借助联网机器打包deb再拷贝进场。

先说一个直觉判断:如果只靠U盘随便拷贝几个.run安装包进去就想搞定Qt5开发环境,基本不可行。Qt5开发依赖庞大,gcc需要配套的libc6-dev、binutils,Qt5需要libxcb、libGL、fontconfig等一堆运行时库,缺一个都能让你编译失败或者程序起不来。正确思路是“准备一个完整可用的软件包集合”,而不是“拷贝一个安装程序进去”。

2. 离线环境下的gcc:先从依赖地狱里爬出来

2.1 招式一:挂载ISO搭本地源,能救80%的场

银河麒麟V10的ISO镜像里带了一部分常用软件包,虽然不一定有完整的Qt5开发套件,但gcc、g++、make、binutils这些基础编译工具大概率齐。如果你手头有ISO文件或光盘,我建议优先用这个方案,因为它最省事、最不容易出依赖遗漏。

先把ISO文件拷进系统(或用光驱挂载),然后执行:

sudo mkdir -p /mnt/kylin sudo mount -o loop /path/to/Kylin-Desktop-V10-ARM.iso /mnt/kylin

挂载完以后,在/etc/apt/sources.list.d/下新建一个本地源文件:

echo "deb [trusted=yes] file:///mnt/kylin focal main restricted universe multiverse" | sudo tee /etc/apt/sources.list.d/kylin-local.list sudo apt update

这里有个坑要提醒:[trusted=yes]参数一定要加,因为本地源没有Release签名,不加的话apt update会直接拒绝使用,报NO_PUBKEY或InRelease相关错误。另外如果ISO解压出来的目录结构不是标准的Ubuntu源结构(比如只有/pool和/dists),你需要确认dists目录下确实存在focal这个代号,如果不是,就把sources.list里的focal改成实际的目录名。

搞定本地源之后,安装编译器就变成一条命令的事:

sudo apt install gcc g++ make

装完验证一下:

gcc --version g++ --version

这个方法能覆盖绝大多数“只需要gcc能用来编译”的场景。如果你做的是纯Qt Widgets项目,后面再补Qt5的包也能通过这个源装上一部分。但如果ISO里没有你要的包,就得用第二种方法。

2.2 招式二:同架构联网机器打包deb,一次拉齐依赖树

ISO源覆盖不了的情况太常见了。麒麟V10的ISO镜像体积有限,里面不可能把所有Qt5开发包都塞进去,这个时候就需要借助另一台“同架构、同系统版本”的联网机器,把目标包和它的整个依赖树全部下载成deb,再拷贝到离线机上安装。

先找一台能联网的aarch64机器(如果实在没有,用虚拟机跑一个Ubuntu ARM版也可以,但系统版本尽量贴近),配置好麒麟源或Ubuntu源,然后执行:

# 先安装一个递归查询依赖的工具 sudo apt install apt-rdepends # 查看目标包会引入多少依赖,心里有个数 apt-cache depends gcc g++ make # 使用--print-uris把所有deb包的下载地址打出来 apt-get install --reinstall --print-uris -y gcc g++ make libc6-dev

--print-uris会把每个包的实际下载链接列出来,你可以按这个清单逐个下载。但更省事的办法是直接用apt-get download配合递归依赖列表,一条命令拉全部:

sudo apt-get install -y --print-uris gcc g++ make | grep "^\'http" | awk '{print $1}' | tr -d "'" > /tmp/deb_urls.txt

然后借助wget逐个下载,或者直接用下面这个更实用的命令把deb包统一放到一个目录:

mkdir /tmp/offline_debs && cd /tmp/offline_debs # 方式A:如果你能联网且使用apt,直接下载指定包 apt-get download $(apt-rdepends gcc g++ make libc6-dev 2>/dev/null | grep -v "^ " ) # 方式B:如果依赖关系太乱,就直接手工把关键包下载下来再逐个试 apt-get download gcc g++ make libc6-dev binutils linux-libc-dev cpp

注意apt-rdepends输出里那些带Depends:缩进的部分才是依赖包名,直接取第一列即可。下载完把整个offline_debs目录拷贝到U盘,拿到离线机上。

离线机上安装deb包时,我最开始直接sudo dpkg -i *.deb,结果一团糟。因为dpkg按照文件名字母顺序安装,不会主动解析依赖顺序,经常装到一半报某个依赖还没有配置。正确的做法是分两步:先忽略依赖顺序套一层,再用apt-get -f install来自动修正。

cd /tmp/offline_debs sudo dpkg -i --force-depends *.deb sudo apt-get -f install -y

--force-depends可以跳过依赖检查先把所有包装上,最后apt-get -f install会自动把缺失的依赖关系补齐。实测这个方法比手工按依赖顺序不停dpkg -i要靠谱得多。如果最后还报缺包,那说明你在打包阶段漏了依赖,回到联网机器上用apt-cache depends逐个对照补一次就好。

2.3 gcc装完还是旧版本?PATH和软链的坑

gcc装完以后,很多人的第一反应是gcc --version验证,结果发现版本号和预期不符,甚至还是系统自带的旧版本。这个问题我见过太多次了,一般来说有三个原因:

第一,系统里本来就带了一个旧版gcc,新装的gcc被装到了不同路径。用which gcc看一下实际调用的路径,如果输出的是/usr/bin/gcc,而新版本装到了/usr/local/bin/gcc,说明是PATH顺序问题。执行echo $PATH看一下/usr/local/bin和/usr/bin哪个靠前。

第二,安装后系统存在多个gcc版本,可以通过update-alternatives手动管理:

sudo update-alternatives --config gcc sudo update-alternatives --config g++

这个命令会把系统里所有gcc版本列出来,你选择默认要用的那个即可。

第三,环境变量没有重新加载。source /etc/profile或者重新登录一次终端,不要用旧的bash窗口去验证,很多时候版本没变就是这个低级原因。

还有一个更隐蔽的坑:ARM机器上如果libc6-dev没有正确安装,gcc即使能运行,编译任何C程序都会报fatal error: stdio.h: No such file or directory。这是因为gcc本身正常,但标准头文件和glibc开发文件缺失。遇到这种报错不用怀疑gcc装坏了,第一反应应该是补libc6-dev。

3. ARM版Qt5离线安装的思路和实操

3.1 为什么在ARM上不要执着于Qt官网的.run包

很多第一次接触ARM Linux Qt开发的人,第一反应就是去Qt官网下载安装包。这里我必须泼一盆冷水:Qt官方的Linux离线安装包,绝大多数只有x86_64版本,官网那个qt-opensource-linux-x64-5.14.2.run在ARM机器上根本运行不了。

Qt官方提供的是在线安装器,确实支持aarch64,但离线环境用不了在线安装器。官方离线.run安装包又只面向桌面x86架构,ARM版几乎没有对应物。所以“在ARM上找Qt官方离线包”这件事本身就是一个死胡同,不要在这个方向上浪费时间。

在银河麒麟ARM版上装Qt5,最靠谱的路线还是走系统包管理器。麒麟是基于Debian系的系统,软件源里有现成的Qt5开发套件。虽然版本可能不是最新的(比如5.12、5.15之类),但对大多数工业界面、嵌入式应用来说已经完全够用,而且和系统库的兼容性最好,不需要你手动去配置运行时库路径。

3.2 用apt/离线deb装好qtbase5-dev和全套工具链

如果你之前搭好了本地源,或者能访问内网源,直接一条命令装齐:

sudo apt install qtbase5-dev qtbase5-dev-tools qttools5-dev-tools qtcreator libqt5svg5-dev libgl1-mesa-dev libxkbcommon-dev

这里几个包的作用我分别说明一下:

  • qtbase5-dev:Qt5的核心开发包,包含了QtCore、QtGui、QtWidgets这几个主力模块的头文件和链接库,没有它你连#include <QWidget>这关都过不去。
  • qtbase5-dev-tools:提供moc、uic、rcc这些Qt专用工具。Qt的元对象系统依赖moc生成代码,缺了它编译任何带Q_OBJECT的类都会报错。
  • qttools5-dev-tools:提供designer、linguist、assistant等辅助工具,如果你想在可视化界面里拖控件,这个包必须装。
  • qtcreator:Qt开发IDE。
  • libqt5svg5-dev:SVG格式支持,做界面设计经常用到。
  • libgl1-mesa-dev和libxkbcommon-dev:这两个是很多Qt5程序编译时的隐性依赖。Qt的GUI底层依赖OpenGL库和键盘输入处理库,缺了它们编译时可能出现找不到GL/gl.h或者链接失败,虽然报错信息不直接指向Qt,但就是这个原因。

如果你是完全离线、只能用deb包迁移的环境,那就在联网机器上用前面第2.2节的思路,把上面这一串包连同依赖一起拉下来:

mkdir /tmp/qt5_debs && cd /tmp/qt5_debs apt-get download $(apt-rdepends qtbase5-dev qtbase5-dev-tools qttools5-dev-tools qtcreator libqt5svg5-dev libgl1-mesa-dev libxkbcommon-dev 2>/dev/null | grep -v "^ ")

这条命令拉下来的包数量会非常多,因为Qt5的运行时库依赖一堆xcb、freetype、fontconfig等图形栈组件。打包时耐心等它下载完,然后整个目录带进离线机,用同样的dpkg -i --force-depends *.deb加apt-get -f install -y处理。

安装完成后,可以用一个简单的命令验证Qt5的核心组件是否就位:

dpkg -l | grep qt5 qmake --version

如果qmake --version能输出类似QMake version 3.1 Using Qt version 5.15.2 in /usr/lib/aarch64-linux-gnu/qt5的内容,说明Qt5核心已经安装成功。

3.3 小范围内的选型建议:哪些包必须装,哪些踩过才知道

首次搭建Qt环境的人很容易陷入两个极端:要么只装一个qtbase5-dev就开干,等到具体模块缺了再手忙脚乱补包;要么一口气把qt5-*全部装掉,结果系统里塞满用不上的东西。结合我在麒麟ARM上跑Qt5的实际经验,给你一个参考清单:

必要组件(不装基本跑不起来):

  • qtbase5-dev:核心开发包
  • qtbase5-dev-tools:moc等编译工具
  • qtcreator:IDE

强烈建议安装(业务开发高频用到):

  • qttools5-dev-tools:designer和linguist
  • libqt5svg5-dev:SVG图标和图片
  • libqt5printsupport5和对应的开发包:如果需要做打印功能
  • libqt5serialport5-dev:如果做串口调试工具
  • libqt5networkauth5-dev:如果需要OAuth之类认证流程

按需安装(用到再补):

  • libqt5charts5-dev:图表绘制
  • libqt5webenginewidgets5:嵌入式浏览器组件(体积巨大,对资源占用也高,非必要别装)
  • libqt5multimedia5:多媒体播放

有一点你可能会踩坑:Qt5的版本和系统桌面环境(UKUI)之间的配合。麒麟的UKUI桌面本身基于Qt开发,系统里通常自带了某种版本的Qt5运行库,但开发头文件很可能没装。你通过apt额外安装qtbase5-dev时,如果版本比系统自带的运行时库版本略新或略旧,一般不会冲突,APT会把依赖关系自动处理好。怕的是你手动下载一个非系统源的Qt编译产物去覆盖,那就容易把桌面环境搞崩。所以在这个平台上的第一原则:能用系统源装就用系统源装,不要自己下载编译包覆盖。

4. Qt Creator装配与构建套件(Kit)配置

4.1 安装Qt Creator,版本别盲目追新

sudo apt install qtcreator装好的版本可能不是Qt官方最新版,这反而不是坏事。Qt Creator和Qt库的版本对应关系比较灵活,新版Creator通常可以兼容多个Qt5小版本,但反向不一定成立——特别老的Creator可能不识别新版本qmake生成的工程格式。

在麒麟这种比较克制的系统源里,Creator版本往往比官方最新版落后一两个大版本,但对开发Qt5 Widgets程序毫无影响。我甚至建议不要自己去Qt官网下载一个很新的Creator二进制包,因为新版Creator对GLIBC版本有要求,ARM版银河麒麟的glibc如果不够新,直接起不来。

安装完以后启动一下,命令行输入:

qtcreator

如果启动过程中遇到缺少libxcb-xinerama0之类的报错(这个报错在离线环境很常见,因为Qt Creator依赖xcb的扩展库),先去补装:

sudo apt install libxcb-xinerama0 libxcb-cursor0

4.2 Kit配置:qmake、gcc、gdb三件套

Qt Creator装上以后,真正的关口是构建套件(Kit)配置。打开菜单“工具” → “选项” → “Kits”(部分中文版叫“构建套件”),你会看到左侧有“Qt版本”、“编译器”、“调试器”等页签。这三个页签必须都配置正确,Kit前面的状态图标才会变成绿色,否则编译会报一堆莫名其妙的问题。

先看“Qt版本”页签:正常情况Qt Creator会自动扫描到系统安装的qmake,路径通常为/usr/lib/aarch64-linux-gnu/qt5/bin/qmake。如果列表为空,点击“添加”,手动选择qmake路径。这里要特别嘱咐一句:看清楚路径里的aarch64-linux-gnu,如果你不小心把x86架构机器的qmake路径配到这里,Creator会直接报“qmake无法执行”。

再看“编译器”页签:点击“添加” → “GCC” → “C++”,在“编译器路径”里填/usr/bin/g++,名称随便写,比如GCC-ARM64。C编译器同理填/usr/bin/gcc。如果Creator自动检测到了,你也可以直接用它检测出来的结果,但要确认架构列显示的是aarch64,不是x86_64。

最后在“调试器”页签添加/usr/bin/gdb。这个步骤很多人会忽略,导致能编译能运行,但一打断点就报“No debugger”。如果系统里没有gdb,先sudo apt install gdb装上。

三个组件都就位以后,回到“Kits”页签新建一个Kit,名称建议写成Kylin-ARM64-Qt5,Qt版本选刚才添加的那个,编译器C/C++都选GCC-ARM64,调试器选gdb,CMake工具如果有需要也可以指定。保存之后看到Kit前面的状态是绿色对勾,说明它已经可用了。如果显示红色警告,先在下方“错误/警告”信息栏查看具体原因,最常见的就是“没有设置Qt版本”和“编译器中C和C++没有匹配到同一套工具”。

4.3 第一个程序跑起来之前,先过一遍这几个细节

新环境上跑第一个Qt程序,最容易在下面四个细节上翻车。我在麒麟ARM上第一次建工程时,就因为在模板选择上多犹豫了一下。

第一,工程模板选择。新建工程时,如果选择“Qt Widgets Application”,cmake和qmake两套构建系统都能用。我建议在麒麟上用qmake,原因很简单:qmake和apt安装的Qt5集成度更好,路径配置更省心,几乎不需要额外指定任何参数。CMake虽然也能用,但要确保Kit里CMake路径配置正确,而且CMake在解析Qt5的Qt5_DIR时容易因为路径不对报错。

第二,编译器基线和-fPIC问题。ARM Linux上编译共享库或可执行文件时,qmake会自动加上-fPIC,一般不需要你手工干预。但如果你用纯命令行gcc去编译Qt程序,而不是通过qmake或Creator,很容易漏掉编译选项导致链接错误。新手阶段建议全程走Creator的构建按钮,不要自己手搓命令行。

第三,程序运行时提示找不到libQt5Widgets.so.5的解决方案。这种情况一般不是安装有问题,而是运行时库路径没被找到。用apt安装的Qt5库都在/usr/lib/aarch64-linux-gnu/目录下,系统的ldconfig默认是能搜到的。如果你手动把编译好的程序拷贝到别的机器上运行,才需要考虑LD_LIBRARY_PATH或rpath问题。在本机调试阶段遇到这个报错,先执行sudo ldconfig刷新缓存。

第四,检查~/.bashrc里是否有人为设置过QTDIR或LD_LIBRARY_PATH环境变量,如果指向了不存在的目录,会影响Qmake和Creator的自动检测。我在一台机器上就遇到有人配了个过时的QTDIR=/opt/Qt5.9.2,导致一切自动检测都失效。检查方法:

echo $QTDIR echo $LD_LIBRARY_PATH

有任何残留配置,先注释掉再重启Creator。

5. 现场常见故障排查与实用技能补充

5.1 Qt5无法拖拽文件到界面的原因和对策

“Qt5无法拖拽文件”这个问题,在银河麒麟ARM平台上非常典型,而且网上答案碎片化严重,这里我把排查路径完整捋一遍。

首先要明确:拖拽分为“从系统文件管理器拖文件到你的程序窗口”和“在你的程序内部拖控件”两种。前者依赖系统级拖拽协议,后者依赖Qt内部的事件系统。用户通常抱怨的是前者。

在麒麟V10的UKUI桌面上,Qt5程序无法接收系统文件拖拽,我排查下来主要是这四个原因:

第一,程序没有调用setAcceptDrops(true)。这是最常见的新手错误。QWidget默认不接受drop事件,你必须在构造函数或初始化函数里显式开启:

setAcceptDrops(true);

然后在类里重写dragEnterEvent和dropEvent两个函数,并正确调用event->acceptProposedAction(),否则文件拖进来不会有任何响应。

第二,平台插件没有走X11而走了Wayland。Qt5在Linux下默认会根据当前桌面环境选择平台插件,如果系统的图形会话是Wayland,而你的程序没有使用Wayland适配层,拖拽功能就很容易失效。麒麟V10默认的登录会话基本是X11,但如果你通过某些远程软件或切换过显示服务器,就可能在Wayland环境下运行。遇到这种问题,强制指定XCB插件启动:

export QT_QPA_PLATFORM=xcb ./your_app

第三,以root身份运行导致拖拽受限。在麒麟上很多用户喜欢sudo ./your_app,但某些桌面组件的拖拽在root权限下会被窗口管理器限制。如果程序非要用root权限,可以先试试不用root运行,看拖拽是否恢复,从而确认是不是权限问题。

第四,事件过滤器拦截了拖拽事件。如果程序里给控件安装了eventFilter,并且在过滤器里吞掉了QEvent::DragEnter或Drop,那无论如何设置setAcceptDrops都不生效。排查方法是暂时关闭事件过滤器,逐一确认。

从我的经验看,第三和第四个原因在真实项目里出现频率很高,尤其是root运行的问题,很多测试工程师会在root环境下得出“拖拽功能坏了”的结论,实际上切回普通用户一切正常。

5.2 编译报错与运行时缺库的定位方法

Qt5开发时遇到编译错误,先别急着重新安装整个Qt,大部分问题定位一下就能解决。

编译期最常报的错是fatal error: QWidget: No such file or directory。这个报错出现,只能说明头文件搜索路径没配上。用qmake构建时,检查.pro文件里是否确实包含了QT += widgets。如果漏写,qmake生成的头文件路径里就不会包含QtWidgets模块,编译才会找不到头文件。

如果报的是undefined reference to vtable之类的链接错误,基本可以断定Q_OBJECT宏所在的类的头文件没有跑过moc。这在qmake工程里通常是因为把含Q_OBJECT的类写在了.cpp文件里(虽然现在moc也能处理这种情况,但需要额外配置QMAKE_MOC),或者忘了在.pro文件里声明对应的头文件。Qt的规则是:头文件里有Q_OBJECT,这个头文件必须出现在HEADERS变量里,moc才会处理它。

运行期缺库的报错长这样:

error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file: No such file or directory

第一反应不应该是重装Qt,而是先看这个库是否存在:

ldconfig -p | grep Qt5Widgets find /usr/lib/aarch64-linux-gnu -name "libQt5Widgets*"

如果库存在但程序仍然报“找不到”,多半是程序里设置了LD_LIBRARY_PATH把系统库路径覆盖了,或者程序是用rpath固定了错误的库目录。执行一下ldd ./your_app | grep Qt5能看到实际链接到的路径。如果库真的不存在,说明开发包装了但运行时库没装,补装对应的libqt5widgets5以及libqt5gui5即可。

5.3 顺手解决几个高频小问题:中文字体、信号槽结构体、GDB数据断点

开发过程中还有几个高频问题,几乎每台新机器上都会被问一遍,我在这里一起处理掉。

第一个是中文乱码和方块字。在麒麟ARM上跑Qt5程序,界面显示中文全部变成方块,这是典型的字体缺失。系统可能带了基本的中文字体,但Qt5默认字体回退没有选择到它们。解决办法是安装开源中文字体:

sudo apt install fonts-wqy-microhei fonts-wqy-zenhei fonts-noto-cjk

安装完成后重启程序,如果还不行,在代码里显式设置字体:

QApplication::setFont(QFont("Noto Sans CJK SC", 10));

第二是信号槽传递结构体的问题。很多人在Qt5里自定义了一个结构体,然后用信号槽传递,编译能过,但槽函数收到的数据是空的,甚至连接不生效。原因很简单:跨线程队列连接时,结构体需要注册到Qt的元类型系统。在结构体定义下面加一行:

Q_DECLARE_METATYPE(MyStruct)

然后在连接前注册类型:

qRegisterMetaType<MyStruct>("MyStruct");

如果是跨线程信号槽,连接时最好显式使用Qt::QueuedConnection,避免因为连接类型自动判断错误而丢失信号。

第三是Qt Creator里怎么下数据断点。这个问题问的人也很多。在Qt Creator的调试模式下,右键左侧断点边栏,选择“添加数据断点”,在弹出的编辑框里输入要监视的内存地址。更常用的做法是在断点命中后,在“调试器” → “监视” 表达式列表里右键变量,选择“在内存地址处设置数据断点”。数据断点在排查栈溢出、数组越界和指针被意外改写时非常有用。注意数据断点只在GDB后端下可用,而且ARM Linux上硬件数据断点数量有限,一般同时只能设4个,设太多会提示资源不足。

写在最后的小经验

这套环境我在两台不同的麒麟ARM设备上各装了一遍,第二次明显比第一次快了很多。最大的体会是:离线安装的成功率,基本取决于你在“打包阶段”是否把依赖树一次理清。与其在目标机器上反复试错、逐个补包,不如在联网机器上把所有依赖一次性用apt-rdepends拉干净,哪怕打包体积大一点,也比现场缺库强十倍。

另外还想分享一个小习惯:每次装完一个阶段(比如gcc装完、Qt5装完),都随手做一个dpkg -l > /tmp/pkg_manifest.txt的快照。如果后续环境被改坏了,对照快照排查比从头重装快得多。这个习惯在隔离环境交付项目时尤其有用,客户现场的运维看到你能直接告诉他要补哪个包,会省掉很多沟通成本。

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

Agent上下文工程:分层压缩与业务指标驱动的实战方法论

1. 项目概述&#xff1a;当Agent开始“记不住事”&#xff0c;我们到底在压缩什么&#xff1f;你有没有遇到过这样的情况&#xff1a;一个精心设计的Agent&#xff0c;在处理一份30页的PDF合同分析任务时&#xff0c;前20页还能条理清晰地提取条款、比对风险点&#xff0c;到了…

作者头像 李华
网站建设 2026/9/25 4:53:02

CE指针扫描定位游戏血量地址:基址偏移与指针链实战教程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 4:50:58

华为昇腾Atlas 300V 24G推理卡部署YOLOv5/v8完全指南

搞推理加速这几年&#xff0c;我手里过过不少卡&#xff0c;但头一回拿到华为昇腾Atlas 300V 24G这块卡的时候&#xff0c;还是被周围人问过同一个问题&#xff1a;这玩意儿到底是不是运算加速卡&#xff1f;它能干嘛&#xff1f;能不能拿来跑YOLO&#xff1f;带着这些疑问&…

作者头像 李华
网站建设 2026/9/25 4:50:42

pygame俄罗斯方块实战:逻辑与渲染分离的完整开发指南

简介&#xff1a;基于Python pygame的经典俄罗斯方块小游戏开发资源包&#xff0c;面向计算机相关专业高校学生与Python游戏开发初学者&#xff0c;可完成课程实训、课程设计或期末作业&#xff0c;也可作为毕设或项目立项演示。资源共6个文件&#xff0c;包含tetris.py主程序、…

作者头像 李华
网站建设 2026/9/25 4:50:33

Android注册页无数据库实现:输入校验与状态保存实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/25 4:49:40

微信公众号历史文章列表页获取实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华