最近在搭建 RK3576 + Debian12 + Qt5.15.8 交叉编译环境时,发现很多刚接触 Linux 嵌入式开发的同学都会遇到同一个问题:
-device linux-rk3576-g++
和
crossbuild-essential-arm64
到底是什么关系?
甚至有人认为:
安装了 crossbuild-essential-arm64 就不需要 linux-rk3576-g++。
或者:
linux-rk3576-g++ 就是 ARM64 编译器。
实际上,这两者根本不是一个层面的东西。
今天用最简单的方式彻底讲清楚。
一个最容易记住的结论
先记住一句话:
crossbuild-essential-arm64是工具链linux-rk3576-g++是Qt的配置文件
两者缺一不可。
关系类似于:
汽车发动机+导航地图=到达目的地
其中:
发动机=crossbuild-essential-arm64导航地图=linux-rk3576-g++
什么是 crossbuild-essential-arm64?
安装命令:
sudo apt install crossbuild-essential-arm64
安装完成后:
which aarch64-linux-gnu-g++
输出:
/usr/bin/aarch64-linux-gnu-g++
实际上安装的是:
aarch64-linux-gnu-gccaarch64-linux-gnu-g++aarch64-linux-gnu-araarch64-linux-gnu-ldaarch64-linux-gnu-strip
这一整套工具。
它的作用非常简单:
把C/C++代码编译成ARM64机器码
例如:
intmain(){return0;}
编译:
aarch64-linux-gnu-g++ test.cpp -o test
查看:
file test
输出:
ELF 64-bit LSB executableARM aarch64
说明已经生成 ARM64 程序。
所以:
crossbuild-essential-arm64=ARM64交叉编译工具链
什么是 linux-rk3576-g++?
很多人第一次看到:
-device linux-rk3576-g++
会误认为:
这是编译器
其实完全不是。
它本质上只是 Qt 的一个配置目录:
qtbase/mkspecs/devices/linux-rk3576-g++
里面最重要的是:
qmake.conf
例如:
QMAKE_CC = aarch64-linux-gnu-gccQMAKE_CXX = aarch64-linux-gnu-g++QMAKE_LIBS_EGL += -lEGLQMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGLDISTRO_OPTS += aarch64
它的作用是告诉 Qt:
使用哪个编译器如何链接使用什么OpenGL目标CPU是什么显示系统是什么
所以:
linux-rk3576-g++=Qt设备配置文件
两者是什么关系?
举个最直观的例子。
当执行:
../qt-src/qtbase/configure \-device linux-rk3576-g++
Qt首先读取:
linux-rk3576-g++
然后发现:
QMAKE_CXX=aarch64-linux-gnu-g++
于是调用:
aarch64-linux-gnu-g++
开始编译。
整个过程:
linux-rk3576-g++ │ ▼aarch64-linux-gnu-g++ │ ▼生成ARM64程序
所以:
linux-rk3576-g++并不会编译代码真正编译代码的是aarch64-linux-gnu-g++
为什么Qt必须要linux-rk3576-g++?
因为 Qt 需要知道:
目标板是什么平台使用什么编译器使用什么图形后端使用什么OpenGL方案
例如:
RK3576RK3588IMX8树莓派Jetson
虽然都是 ARM 平台,
但:
显示驱动不同图形栈不同OpenGL方案不同
Qt 必须提前知道这些信息。
所以需要:
linux-rk3576-g++
来描述目标平台。
linux-rk3576-g++ 是32位的吗?
这是很多人都会问的问题。
答案:
不是
RK3576属于:
ARMv8AArch6464位
你的工具链:
aarch64-linux-gnu-g++
已经说明:
aarch64=ARM64
如果是32位:
通常会看到:
arm-linux-gnueabihf-g++
对应:
ARMv732位
如果只有其中一个会怎样?
只有工具链
例如:
sudo apt install crossbuild-essential-arm64
但没有:
linux-rk3576-g++
Qt配置:
-device linux-rk3576-g++
会直接报错:
No device matching 'linux-rk3576-g++'
只有linux-rk3576-g++
如果:
aarch64-linux-gnu-g++不存在
Qt会报:
Cannot find compiler
或者:
aarch64-linux-gnu-g++ not found
所以:
工具链负责干活mkspec负责指挥
缺谁都不行。
RK3576项目中的完整关系
在实际项目中:
Debian开发机 │ ▼crossbuild-essential-arm64 │ ▼aarch64-linux-gnu-g++ │ ▼linux-rk3576-g++ │ ▼Sysroot │ ▼Qt5.15.8 │ ▼广告机应用
这就是完整的交叉编译链。
总结
对于 RK3576 Qt 开发来说,可以记住一句话:
crossbuild-essential-arm64 是“工具”,linux-rk3576-g++ 是“说明书”。
更准确地说:
crossbuild-essential-arm64=ARM64交叉编译工具链linux-rk3576-g++=Qt设备配置(mkspec)sysroot=RK3576系统环境镜像
三者共同配合,才能完成 Qt 库和 Qt 应用的交叉编译。
如果把交叉编译比作开车:
crossbuild-essential-arm64= 发动机linux-rk3576-g++= 导航地图sysroot= 目标城市环境Qt工程= 乘客
只有发动机、导航和目的地信息都齐全,最终才能顺利到达 RK3576 开发板。