news 2026/10/5 8:39:10

RK3568+Ubuntu下Qt交叉编译环境搭建与远程调试实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3568+Ubuntu下Qt交叉编译环境搭建与远程调试实战

说实话,拿到RK3568开发板之后,真正让人头疼的往往不是硬件本身,而是软件环境。特别是你想在板子上跑Qt界面程序时,第一步就卡在一个问题上:怎么在Ubuntu上把Qt交叉编译环境搭起来,还要能在Qt Creator里一键编译、一键部署、一键调试。这活儿我折腾过好几回,踩过不少坑,今天把整个流程整理成一篇能直接照着抄的文章,从交叉编译原理、工具链选择、Qt源码编译,到Qt Creator配置和远程调试,一次说清楚。

这个流程适合的目标读者很明确:手上有RK3568开发板,打算用Qt做嵌入式GUI,宿主机是Ubuntu的开发者。不管你是刚接触嵌入式Linux的小白,还是从单片机转过来的老手,这篇文章都尽量讲得细致一些,至少让你少走我当年走的弯路。

1. 为什么要在Ubuntu上搭这套环境:先搞清楚交叉编译的原理

1.1 从x86到ARM:交叉编译到底解决什么问题

RK3568是瑞芯微旗下的一颗ARM64架构处理器,核心是四核Cortex-A55。我们日常开发用的PC,绝大多数是x86_64架构。x86和ARM是两套完全不同的指令集,这就像一个是简体中文、一个是繁体中文,虽然都认识,但直接混着用是不行的。

问题就来了:在板子上直接编译Qt工程不现实。RK3568虽然能跑Linux,但算力有限,编译一两千个源文件的Qt库可能得等半天甚至更久,而且板子上的存储一般也不宽裕。所以常规做法是在性能强劲的PC上,用一套能生成ARM指令集程序的编译器来编译代码,再把编译好的二进制拷到板子上运行。这个“在A架构上编译B架构程序”的过程,就叫交叉编译。

这里面有个关键概念需要先理解透彻:交叉编译器不止是一个gcc/g++那么简单。它背后是一整套工具链,包括汇编器、链接器、C标准库头文件、glibc运行库等等,它们共同决定了你能编出什么样的程序,以及这个程序将来能在什么环境里跑。很多时候大家把交叉编译叫“工具链”,原因就在这里。

1.2 RK3568平台的特殊性:工具链版本不是随便选的

RK3568是ARMv8-A架构,对应的是aarch64也就是64位ARM指令集。如果你拿一套32位的arm-linux-gnueabihf工具链去编译,虽然也能编出ARM程序,但不是针对RK3568优化的,而且很多依赖库的系统路径、库文件都不对,跑起来各种报错。所以第一步就要选对:aarch64-linux-gnu这套64位工具链。

工具链版本这事儿我多说一句。别不听劝就上最新的gcc 13、gcc 14,我实测下来,RK3568这类板子配套的官方SDK里通常自带工具链,版本稳定在gcc 9.3到10.3之间。这个版本范围内的工具链,和板子自带的glibc版本是能匹配的,编译出来的程序放上去直接就能跑。如果你用太新的工具链,很有可能编出来的程序在板子上报“version `GLIBC_X.XX' not found”,然后你就要去折腾板子的rootfs降级,那是真的痛。

1.3 环境搭建的两条路线:SDK工具链和独立工具链怎么选

搭建交叉编译环境有两条路线,我先说清楚,你自己权衡。

第一条路线是用厂商SDK自带的工具链。RK3568的开发板不少,正点原子、迅为、飞凌这些都有配套SDK,解压之后在prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-x86_64-aarch64-none-linux-gnu/bin/路径下就能找到现成工具链。这种方式的好处是和板子的内核版本、库版本高度匹配,基本不会出现跑不起来的问题,缺点是路径藏得比较深,环境变量得自己配。

第二条路线是用ARM官方发布的工具链,或者Linaro工具链,自己去gcc.arm.com下载解压。这种路线的好处是版本选择灵活,坏处是你要多花精力去匹配板子rootfs里的glibc版本。我个人的建议是:如果你手头有厂商SDK,优先用SDK里的;项目一旦稳定下来,版本就不要改了,换来换去早晚出事。

2. 基础环境准备:Ubuntu、工具链与验证小实验

2.1 宿主机需要装什么

我默认你已经装好了Ubuntu系统。版本上,20.04和22.04我都跑过,都行。如果你用的是虚拟机,建议给虚拟机分配至少4核CPU和8GB内存,否则后面编译Qt源码,在看片转圈的时候真的会怀疑人生。

首先把基础工具装齐,打开终端执行:

sudo apt update sudo apt install -y build-essential gdb-multiarch rsync ssh vim

这四条命令分别做了什么事,我说明一下:

  • build-essential:包含编译必需的make、gcc、g++等,宿主机本地的编译环境得先立起来。
  • gdb-multiarch:一个跨架构的gdb调试器,x86上调试ARM程序就靠它。很多教程会让你装aarch64-linux-gnu-gdb,如果工具链包里没有,用gdb-multiarch一样能干这活儿,Qt Creator也能识别。
  • rsync:后面把板子的系统目录同步到宿主机,以及文件部署,都离不开它。
  • ssh:远程连接板子、执行命令上传文件的基础,不装什么都干不了。

额外提醒一个容易忽略的包:libxkbcommon-dev。后面你编译Qt源码时如果开了xcb相关模块,很容易因为缺少这个依赖直接报错。既然要搭环境就一步到位装好吧:

sudo apt install -y libxkbcommon-dev

2.2 下载并配置ARM64交叉编译工具链

不管你用哪条路线拿到工具链,本质上都是一堆解压即用的文件。以SDK内举例,假设工具链目录位于~/rk3568_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-x86_64-aarch64-none-linux-gnu,我需要把它加进PATH里。

我习惯在~/.bashrc末尾追加一段环境变量配置:

export RK_TOOLCHAIN=~/rk3568_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-x86_64-aarch64-none-linux-gnu export PATH=$RK_TOOLCHAIN/bin:$PATH

然后执行:

source ~/.bashrc

这里有个细节值得注意:环境变量最好写在最后面,不要覆盖系统原有的PATH。很多代码编译工具依赖宿主机的python、perl等解释器,如果你把PATH里宿主机命令的优先级挤掉,后面编译Qt源码时会冒出一堆莫名其妙的问题。

2.3 用一个小程序验证工具链是否可用

工具链配好只是第一步,真金白银要经过火炼。写一个最简单的Hello World验证一下:

mkdir -p ~/rktest && cd ~/rktest cat > hello.c << 'EOF' #include <stdio.h> int main() { printf("Hello RK3568!\n"); return 0; } EOF

然后交叉编译:

aarch64-linux-gnu-gcc hello.c -o hello_arm file hello_arm

如果输出中包含ELF 64-bit LSB executable, ARM aarch64这样的字样,恭喜,工具链基本没问题了。我习惯再用readelf -l hello_arm | grep interp看一眼程序依赖的动态链接器路径,正常情况下应该是/lib/ld-linux-aarch64.so.1,这能提前预判glibc兼容性问题。

这个验证程序到后面还会用到,先别删。

3. Qt源码交叉编译:整个过程最核心也是最磨人的一步

3.1 为什么不能用apt直接装的Qt来交叉编译

我知道很多新手习惯在Ubuntu上sudo apt install qt5-default,这没问题,但在交叉编译这个场景里完全行不通。用apt装的是面向x86宿主机编译好的二进制包,它调用的qmake、Qt库都是x86指令集。你拿着这个qmake去编译ARM程序?它会很认真地告诉你:我只会编x86。

所以交叉编译Qt,必须走这条老路:下载Qt官方源代码包,用交叉工具链在x86机器上编译出一套ARM架构的Qt库,这套库加上配套的qmake,才是有资格参与RK3568交叉编译的完整工具链。

这一步是整个搭建过程中最容易让人崩溃的环节,因为Qt源码体量大、依赖面广,你configure时候漏掉一个选项,编译到一半才报错,返工成本极高。我下面把每一步的关键参数和背后的原因都拆开讲。

Qt的源码包,我建议选qt-everywhere-src-5.15.2.tar.xz。5.15是LTS长期支持版本,RK3568的嵌入式GUI场景下稳定性有保障。Qt6系列的configure参数变化较大,不是不能用,但网上参考案例少,踩坑了你连个问的地方都不好找,先把5.15跑通再说。

解压源码:

mkdir -p ~/rk3568/qt && cd ~/rk3568/qt tar xf qt-everywhere-src-5.15.2.tar.xz

3.2 准备sysroot:把板子的库同步到宿主机

这是很多教程会一笔带过、但实际特别关键的一步。Qt交叉编译时,编译器需要找到目标平台的头文件和库文件,比如c标准库、tslib触摸库、各种Linux系统库。这些文件从哪里来?答案是直接从开发板的rootfs里同步过来,那套文件集合就叫sysroot。

先在你的PC上建目录:

mkdir -p ~/rk3568/sysroot cd ~/rk3568/sysroot

然后用rsync连接你的板子同步目录。我假设板子的IP是192.168.1.100,用户名root:

rsync -av root@192.168.1.100:/lib . rsync -av root@192.168.1.100:/usr/lib sysroot/usr/

注意我这里是同步到sysroot/usr/子目录里,因为工具链默认会去sysroot/usr/lib寻找库文件。操作完成后,务必确认目录结构像这样:

~/rk3568/sysroot/ ├── lib └── usr └── lib

有一个细节必须特别注意:rsync同步的时候会保留符号链接,这本身是好事,但很多板子上的符号链接是指向绝对路径的,比如/lib/aarch64-linux-gnu/libm.so.6 -> /lib/aarch64-linux-gnu/libm-2.28.so,到了宿主机上依然指向绝对路径,结果就是工具链找不到文件。遇到这种情况,我建议你在sysroot里手动创建一个从sysroot根目录到实际库目录的软链接,或者干脆重新调整库文件目录,把板子的/usr/lib/aarch64-linux-gnu整个同步进来。稳妥做法是:

rsync -av root@192.168.1.100:/usr/lib/aarch64-linux-gnu sysroot/usr/lib/

具体路径以你板子的实际目录为准,先ssh到板子上用ls确认,别想当然。

如果你的应用还要用tslib触摸库,检查一下板子上有没有/usr/include/tslib.h,没有就得先把tslib编译安装到板子上,再从板子同步。这属于前置依赖,漏了后面Qt configure必然过不去。

3.3 configure参数详解:哪些项必须开、哪些项必须关

进入Qt源码目录,创建一个build目录独立编译,这是我一直坚持的好习惯,编译产物和源码分开,以后清理非常方便:

cd ~/rk3568/qt/qt-everywhere-src-5.15.2 mkdir build && cd build

然后执行configure。下面这份配置是我在RK3568上经过多轮验证的,可以直接拿来用:

../configure -prefix /opt/qt5.15.2-aarch64 \ -opensource -confirm-license \ -release \ -xplatform linux-aarch64-gnu-g++ \ -sysroot $HOME/rk3568/sysroot \ -linuxfb \ -eglfs \ -opengl es2 \ -tslib \ -no-xcb \ -no-openssl \ -skip qtwebengine \ -skip qtmultimedia \ -nomake examples -nomake tests

每个关键项我都解释一下,因为光会抄参数不行,你得知道动了什么:

  • -prefix /opt/qt5.15.2-aarch64:最终编译好的Qt库安装路径。这个路径是你宿主机的路径,不是板子的。
  • -xplatform linux-aarch64-gnu-g++:告诉Qt源码用哪个平台定义文件来编译。在源码的qtbase/mkspecs/目录下你会看到linux-aarch64-gnu-g++这个文件夹,里面是qmake.conf和qplatformdefs.h,专门针对aarch64交叉编译写的。如果你的工具链前缀不是aarch64-linux-gnu,这个mkspec可能也要微调,但大多数情况直接用就行。
  • -sysroot:指向刚才同步的sysroot目录,这是Qt交叉编译和宿主机编译最大的区别之一。有了它,编译器才知道去哪里找头文件和库。
  • -linuxfb -eglfs -opengl es2:这三个是嵌入式Qt最常用的平台插件。RK3568有GPU,支持Mali GPU的OpenGL ES 2.0,编译进去之后,程序就能用eglfs模式跑硬件加速,也可退回到linuxfb纯软件渲染。两个都编进去,运行时候用命令行切换,灵活很多。
  • -tslib:如果你的板子用了电阻式触摸屏,多数情况会外接tslib库,这里打开选项,Qt的linuxfb平台就能读取触摸事件。如果板子用的是电容触摸屏,走的是evdev协议,其实开不开tslib影响不大,但我个人建议开到,防止以后换屏麻烦。
  • -no-xcb:RK3568上跑Qt GUI,主流是不跑桌面环境,直接用framebuffer或EGLFS,不需要X11,更不需要xcb插件。关掉xcb能省一长串依赖,省去很多不必要的烦恼。
  • -no-openssl:如果你的程序将来要跟HTTPS服务器交互,这个选项要慎重关掉。但交叉编译OpenSSL本身是个独立工程,且会把configure复杂度拉高一个数量级,我建议第一版先关掉保平安,后面有需求再单独编。
  • -skip:跳过一些在嵌入式场景下用不到的重量级模块,qtwebengine编译起来能让你等到怀疑人生,skip掉能大幅节省编译时间。

configure执行完之后,终端会显示一大堆配置总结。我每次都会在输出里找三个关键词:linuxfb yes、eglfs yes、tslib yes。只要这三个都是yes,后面编译基本就稳了。

3.4 编译、安装和一次常被忽略的验证

configure通过后,真正的考验开始了。执行编译:

make -j$(nproc)

这里的-j$(nproc)会自动把并发线程数设成CPU核心数。如果是在虚拟机上,建议相对保守一点,比如-j4,否则内存不够的话编译到一半直接OOM被杀死,前面的等待全部白费。

编译完成后安装到指定prefix目录:

sudo make install

为什么需要sudo?因为/opt目录默认root权限,而prefix指向那里。如果你不想用sudo,也可以把prefix改成$HOME/qt5.15.2-aarch64,这一层次可以自己定。

装完后,到/opt/qt5.15.2-aarch64/bin/目录下看一眼,确认qmake文件存在。然后做一个最关键的验证,执行:

/opt/qt5.15.2-aarch64/bin/qmake -query

输出的QT_INSTALL_PREFIX应该指向 /opt/qt5.15.2-aarch64,QMAKE_SPEC应该是linux-aarch64-gnu-g++。如果这两个值不对,后面Qt Creator里所有的自动查找都会乱套。

我还习惯用这个qmake来编译一个最小Qt程序测试,避免Qt库编完了但没法用的尴尬:

cd ~/rktest cat > qt_test.cpp << 'EOF' #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label("Qt on RK3568 OK!"); label.show(); return app.exec(); } EOF

用交叉qmake编译:

/opt/qt5.15.2-aarch64/bin/qmake -project /opt/qt5.15.2-aarch64/bin/qmake make

如果这一步能顺利生成可执行文件,且file qt_test显示aarch64,说明Qt交叉编译环境核心链路已经打通了。

4. Qt Creator配置:把交叉编译环境“带劲”起来

Qt库编好了,但日常开发总不能命令行敲全套make吧?接下来把这一切配置进Qt Creator,让IDE自动完成编译、部署、调试,这才能谈开发效率。

4.1 配置交叉编译器与调试器

打开Qt Creator,进入Tools -> Options -> Kits。左侧选Compilers,点击Add -> GCC -> C,在Compiler path里选择工具链bin目录下的aarch64-linux-gnu-gcc。按同样操作添加C++编译器,选择aarch64-linux-gnu-g++。

这里我要重点提醒一个界面细节:Qt Creator的编译器配置页里有个ABI下拉框,很多时候自动识别成Generic,会导致后面的Kit识别不了。你应该手动把ABI设置成arm-linux-generic-elf-64bit,不行的话就选aarch64-linux-generic-elf-64bit。这一步是很多新手第一次配Kit失败的直接原因。

接着切到Debuggers标签页,点Add -> GDB:

  • 如果工具链bin下有aarch64-linux-gnu-gdb,直接选它。
  • 如果用的是缩水版工具链没有,就用系统装好的/usr/bin/gdb-multiarch。

两个都能跑,但注意gdb-multiarch需要你在启动调试前手动指定目标架构,Qt Creator 新版本一般会自动带上,老版本偶尔会忘,到时我下面调试环节再讲怎么处理。

4.2 添加Qt版本与qmake路径

在同一个Kits窗口中,切到Qt Versions,点击Add,选择/opt/qt5.15.2-aarch64/bin/qmake。确认后在下方显示“Qt 5.15.2 (qt5.15.2-aarch64)”就说明识别成功了。

这里有第二个坑:Qt Creator 会尝试运行qmake -query来获取Qt的信息,如果你的PATH环境变量在GUI启动时没加载qmake相关路径,可能显示“Error”。解决办法不是去改环境变量(因为GUI环境不一定读取.bashrc),而是直接用按钮切换到/opt/qt5.15.2-aarch64/bin/qmake这个绝对路径,通常情况下它会重新运行查询并恢复。

4.3 配置远程设备与Kit:把三者串起来

还是在这个窗口,切到Devices标签页,点击Add,选择Generic Linux Device。填写:

  • Name:RK3568 Board
  • Host name:192.168.1.100
  • Username:root
  • Password:你板子的root密码(默认一般是rockchip)

配置完成后,Qt Creator会尝试通过ssh连接板子并在启动时做连通性测试。这一步如果失败,优先检查板子的SSH服务是否开启,命令是:

sudo systemctl status sshd

如果没有,就在板子上安装或自启动:

sudo systemctl enable ssh

最后回到Kits标签页,点击Add,新建一个Kit,取名叫RK3568 Qt 5.15.2,然后在各个下拉框里选:

  • Compiler:C和C++都选刚才添加的RK3568 GCC/G++
  • Debugger:选刚加的gdb
  • Qt version:选5.15.2-aarch64
  • Device type:Generic Linux Device
  • Device:RK3568 Board
  • Sysroot:填~/rk3568/sysroot

注意,Sysroot这项必须填,否则你将来在Qt Creator里打开Qt的头文件、查看Qt库源码时会定位到宿主机的Qt头文件,最后看到的源码根本对不上,调试信息也会乱一截。

4.4 新建一个测试工程验证整套链路

在Qt Creator里新建一个Qt Widgets Application,把构建套件选成刚配好的RK3568 Qt 5.15.2。写一个简单界面,然后直接点左下角的“构建”按钮。

如果构建顺利,会生成一个aarch64架构的二进制。部署到板子上有两种方式:

一种是直接用Qt Creator的部署功能,在Projects -> Run页面里配置部署步骤,勾选“Upload files via SFTP”之类的选项。这个方式适合文件量少的场景。

另一种是我个人偏爱的:命令行手动scp。原因很简单,部署到嵌入式板子时,你还需要把整个Qt运行库上传过去,那是一个大目录,IDE的部署功能处理起来既慢又容易遗漏。

scp ./qt_test root@192.168.1.100:/root/ scp -r /opt/qt5.15.2-aarch64/lib root@192.168.1.100:/opt/qt5.15.2-aarch64/

上传完库文件后,在板子上设置环境变量:

export LD_LIBRARY_PATH=/opt/qt5.15.2-aarch64/lib:$LD_LIBRARY_PATH export QT_QPA_PLATFORM=linuxfb

然后运行:

./qt_test

看到板子屏幕上出现“Qt on RK3568 OK!”的窗口,这一步通关。

5. 远程部署与调试实操

在板子上能看到界面是一回事,能用Qt Creator断点调试代码又是另一回事。嵌入式开发最痛苦的时刻就是程序崩了,却只知道printf一行行加。远程调试能很大程度缓解这个问题。

5.1 部署机制:rsync同步、权限与依赖处理

上面提到了用scp上传文件,但实际项目越做越大,文件越改越频繁,scp就变得不高效了。我给一个更省心的方案:用rsync做增量同步。

在宿主机上写一个简单的部署脚本deploy.sh:

#!/bin/bash rsync -avz --progress \ --exclude='*.o' --exclude='*.user' \ ./build/rk3568/your_app root@192.168.1.100:/root/app/

每次编译完后执行一下脚本,只有变更的文件会被传上去,带宽和时间节省非常明显。同时记得脚本里加上--exclude,把不需要的对象文件排除掉。

还有个必须养成习惯的点:板子上的库依赖。如果Qt程序依赖/opt/qt5.15.2-aarch64/lib下的动态库,你在板子上运行前必须确认环境变量:

export LD_LIBRARY_PATH=/opt/qt5.15.2-aarch64/lib:$LD_LIBRARY_PATH

每次ssh登进去都要重设,很烦。推荐直接把这一行写进板子的/etc/profile里,一劳永逸。

5.2 在开发板上准备gdbserver

远程调试的架构是:板子上跑一个轻量gdbserver程序,负责接收调试指令并控制目标进程;宿主机上由gdb(Qt Creator 内置)通过网络发送调试指令。两边可以不同架构,gdbserver是ARM版,gdb是x86版,但它们之间通过调试协议通信,架构无关。

Ubuntu的apt源里不一定有aarch64版的gdbserver,所以推荐在板子上直接安装:

apt update && apt install gdbserver

安装完成后验证一下:

gdbserver --version

如果板子的rootfs里面没有apt源,或者装不上,还有一个办法:直接从宿主机工具链SDK里拷贝。很多工具链自带一个aarch64-linux-gnu-gdbserver,路径在bin目录下,把它scp到板子上用就行。

5.3 Qt Creator远程调试设置细节:路径映射与运行环境变量

回到Qt Creator,先配置Run选项。在Projects -> Run页面里,把Run locally取消掉,勾选Run on device,设备选RK3568 Board。这样Qt Creator会通过SSH在板子上启动程序,并且能够自动接入调试器。

这里有一个特别常见的问题:Qt Creator通过device启动程序时,运行环境变量跟板子上手动设置的不一样。你必须在Run页面下方的Run Environment里手动添加:

键值
LD_LIBRARY_PATH/opt/qt5.15.2-aarch64/lib:$LD_LIBRARY_PATH
QT_QPA_PLATFORMlinuxfb

不配好这两项,你在Qt Creator里一点调试按钮,程序在板子上可能还没跑到main()就崩了,报错信息还特别隐晦,说的是“加载共享库失败”之类的,让人一头雾水。

接着配置路径映射。调试的本质是拿板子上的符号信息跟宿主机上的源码做匹配。你在宿主机用/home/oem/RK3568_Qt/hello/main.cpp这个路径打开源码,但板子上gcc编译出来的调试符号里记录的是板子上的编译路径,两者对不上,断点就打不上。解决方法是:

Tools -> Options -> Debugger -> General -> Source Paths Mapping里添加一条映射,比如:

/opt/qt5.15.2-aarch64 -> /home/oem/RK3568_Qt/hello

如果你整个工程都放在固定路径下,也可以在项目设置 -> Debugger Settings -> Debugger里单独配置,作用域更精确。

配置完成后,整体流程就是:写好代码,点编译,Qt Creator自动上传到板子,调用gdbserver启动进程,宿主机连接上去,然后就可以像调试本地程序一样加断点、看变量、看调用栈。

有一点要提醒:嵌入式远程调试比本地调试多了一个网络延迟,单步执行会有肉眼可见的卡顿,这是正常的,不是你的电脑坏了。我在实际开发中一般用远程调试来定位崩溃和逻辑bug,性能调优则靠打印日志辅助,两者结合效率最高。

6. 踩坑实录:高频问题与排查思路速查

环境搭建类的话题,光讲流程不讲坑等于白讲。这节我把这些年遇到过的典型问题整理成一个速查表,按阶段分类,方便你到时候直接翻。

6.1 编译阶段的常见报错

报错信息原因分析解决思路
cannot find -ltssysroot里没有tslib库文件在板子上安装libts-dev,重新同步sysroot
GL/gl.h: No such file or directory缺少OpenGL相关头文件检查sysroot的usr/include里有没有mesa、GLES头文件,必要时同步板子的/usr/include
qatomic.h: No such filesysroot不完整,Qt版本和头文件mismatch重做sysroot同步,确保目录结构完整
error: unknown type name ‘bool’编译器参数或C语言标准问题检查是否在纯C文件中混编了C++代码,用g++编译
libQt5Core.so: undefined reference todlopen@GLIBC_2.x板子的glibc版本太老,工具链太新换用更低版本工具链,或升级板子rootfs

编译阶段还有一个很典型的坑:make -j6 时编译到一半突然报internal compiler error: Killed (program cc1plus),这是内存不足把编译器杀了。解决办法是减少并行线程数,或者给虚拟机多分配内存,没有别的捷径。

6.2 运行阶段的高频问题

程序编译出来了,拷到板子上跑,报错也是五花八门。我把最常见的几种列出来:

报错信息原因分析解决思路
application could not be executed二进制格式不对用file检查文件头,确认是ELF 64-bit ARM aarch64
error while loading shared libraries: libstdc++.so.6缺少C++运行库把/opt/qt5.15.2-aarch64/lib和板子上的/usr/lib相应对齐,确认工具链的库都部署了
The wayland display couldn't be opened默认走了wayland平台插件显式设置QT_QPA_PLATFORM=linuxfb或eglfs
could not find or load the Qt platform plugin "xcb"之前configure开了xcb选项,但相关依赖缺失运行时设置QT_QPA_PLATFORM=linuxfb,或者重新编译时加-no-xcb

这里我要重点说下QT_QPA_PLATFORM这个东西。Qt从5.0开始抽象出一层QPA(Qt Platform Abstraction),它在运行时决定Qt怎么跟底层显示系统交互。在开发板上,最保险的启动方式就是先设成linuxfb,它走Linux framebuffer,不依赖任何显示服务,兼容性最强。如果你在板子上装了完整的桌面环境,想跑在X11下面,才需要设置成xcb。而在RK3568上,如果想调用GPU硬件加速,设成eglfs会是最佳选择,但前提是Mali驱动已经正确加载,且你的Qt编译时带了-eglfs选项。

6.3 远程调试阶段的常见坑

现象原因分析解决思路
点击调试后,Qt Creator卡在“Connecting to server”板子上gdbserver没启动,或端口被防火墙挡了先手动在板子上启动gdbserver :2345,确认能连
断点显示灰色,提示“not valid at this line”源码路径映射没配好,或有优化release编译导致行号错位检查Debugger的Source Paths Mapping,改成release为debug
断点命中后看不到变量值编译时没加调试符号确保编译时是debug模式,qmake工程中CONFIG += debug
调试器报“Remote connection closed”gdbserver崩溃或板子掉线查看板子端gdbserver的日志,确认程序没有在启动阶段直接segfault
单步调试卡死网络延迟或同步点卡住减少单步频率,多在不常变化的行打断点跳着走

远程调试还有一个特殊情况:如果你的程序在main()之前就崩了,比如动态链接库加载失败,Qt Creator的调试器是不好抓到的。这时候我会在板子上手动执行:

gdbserver :2345 ./your_app

然后在宿主机用gdb attach上去,用info sharedlibrary查看哪些库没加载,往往能飞快定位到缺失依赖。

整个环境搭好之后,日常开发就进入一个相对舒服的节奏:宿主机写代码、编译、一键部署、远程调试,板子上的逻辑用断点和日志并行定位。这套流程我现在用得很顺手,但前期的坑也算踩了个遍。说实话,如果让我重来一次,我会在下载Qt源码之前,先把板子上的glibc版本、tslib依赖、工具链版本这三角关系理清楚,能省下非常多返工时间。希望这篇文章能帮你把这段路走得顺一点。

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

把 AgentScope Harness 装进 RuoYi-Vue-Plus:纯 Java AI 平台的集成实践

前两篇讲了「是什么」和「权限怎么落地」。这一篇讲工程&#xff1a;智能体内核怎么与一个成熟的 Java 中台对接&#xff0c;以及我们踩过的坑。 一、目标&#xff1a;让中台「长出」智能体内核 我们不想要一个独立的 Agent 服务&#xff0c;再让业务系统去调它。目标是把智能…

作者头像 李华
网站建设 2026/10/5 8:38:35

灾难片特效幕后:蓝幕微缩模型与AI生成技术拆解

1. 灾难大片是怎么拍的&#xff1f;蓝幕微缩特效幕后拆解 1.1 从“炸了一栋楼”说起&#xff1a;灾难片的视觉真相 很多人看完灾难片&#xff0c;第一反应是“这得烧多少钱”。一栋摩天大楼在镜头前拦腰折断、海啸吞没整座城市、火山灰遮天蔽日——这些画面如果全部实拍&#…

作者头像 李华
网站建设 2026/10/5 8:38:12

国内开源MES框架选型与落地实践:从原理到部署全解析

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

作者头像 李华
网站建设 2026/10/5 8:37:59

MPU6050姿态解算:避开欧拉角死锁,四元数与Mahony滤波实战

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

作者头像 李华
网站建设 2026/10/5 8:37:40

fMRI特征提取本质:ALFF/fALFF/ReHo的信号建模原理与实践

1. 这不是“点几下就能出图”的流程——fMRI特征提取的本质是信号建模&#xff0c;不是图像处理很多人第一次打开DPABI&#xff0c;点开“Preprocessing”菜单&#xff0c;看到ALFF、fALFF、ReHo几个按钮&#xff0c;下意识觉得&#xff1a;“哦&#xff0c;这就是脑功能分析的…

作者头像 李华
网站建设 2026/10/5 8:37:11

上下文模式怎么选?AI工具context-mode原理与省token配置指南

1. context-mode 到底在调什么&#xff1a;先搞清楚这个模式控制的是哪块记忆先说个我自己的经历。早先用 AI 辅助写代码、写文档的时候&#xff0c;经常遇到一种诡异的情况&#xff1a;明明上一个问题它还答得好好的&#xff0c;我补了一句"顺便把刚才那个函数也改了&quo…

作者头像 李华