在嵌入式开发或跨平台开发中,经常会遇到一个概念:交叉编译(Cross Compilation)。这篇文章将简要介绍什么是交叉编译,以及交叉编译工具链中常见的工具前缀含义。


一、什么是交叉编译?

交叉编译是指在一种平台上生成另一种平台可执行代码的编译过程。

举个例子:你在一台运行 Ubuntu(x86 架构)的 PC 上编写程序,并希望将它部署到一台运行 ARM 架构的嵌入式设备上。那么你就需要一个可以在 x86 上运行、但能编译出 ARM 平台代码的编译器,这个过程就叫交叉编译

  • 编译器运行的平台:宿主机(Host)
  • 生成代码要运行的平台:目标机(Target)

通常情况下,宿主机和目标机架构不同,因此不能直接使用本地的 gcc 进行编译。

常见用途

  • 嵌入式开发(如:开发板、物联网设备)
  • 构建 Android/iOS 应用
  • 为多平台生成二进制包

二、交叉编译工具链和前缀

交叉编译依赖于一整套工具链,包括:

  • gcc 编译器
  • ld 链接器
  • as 汇编器
  • ar 静态库打包器
  • strip 去除符号信息

这些工具通常会以一个前缀开头,用于标识它们是为某个特定目标平台服务的。

工具前缀格式

常见格式为:

aaa-bbb-ccc-
  • aaa:目标架构,例如 armaarch64mipsriscv64
  • bbb:厂商或系统(可选)
  • ccc:操作系统,例如 linuxnone(裸机)、elf

aarch64-none-linux-gnu- 这样的前缀出现在交叉工具链的每一个工具名之前,例如:

  • aarch64-none-linux-gnu-gcc
  • aarch64-none-linux-gnu-ld
  • aarch64-none-linux-gnu-ar

这是 GNU 工具链使用的一种 三元组(triplet)命名格式,表示目标平台:

<arch>-<vendor>-<os>[-<abi>]

举例说明:

工具前缀 说明
arm-linux-gnueabi- 用于 32 位 ARM Linux 系统,使用 EABI
aarch64-none-linux-gnu- 用于 64 位 ARM Linux 系统(无特定厂商)
riscv64-unknown-elf- 用于裸机 RISC-V 应用
mipsel-linux-gnu- 用于小端 MIPS Linux 系统

这些前缀加上命令名组成实际工具命令,比如:

aarch64-none-linux-gnu-gcc
arm-linux-gnueabi-ld

是否换芯片就要换工具链?

  • 同一架构,不同厂商:如果内核版本、ABI、库版本兼容,原工具链可以复用;否则推荐使用对应厂商提供的工具链。
  • 不同架构(如 ARM 换成 RISC-V):必须换工具链,因为指令集、ABI 完全不同。

以下情况通常需要更换工具链:

情况 是否需要换工具链 说明
架构变了(aarch64 → arm) ✅ 是 指令集不兼容
OS 类型变了(Linux → RTOS) ✅ 是 系统接口不同
C 库变了(glibc → musl) ✅ 是 ABI 不兼容
编译为裸机(无操作系统) ✅ 是 需使用 elf 工具链
仅芯片厂商变了 ❌ 否 工具链兼容

三、如何获取工具链?

  1. Linux发行版提供的交叉工具链:如 Ubuntu 提供的 gcc-arm-linux-gnueabihfgcc-aarch64-linux-gnu

  2. Linaro、Sourcery 等组织提供的预编译工具链:通常提供 tar 包下载。

  3. Yocto、Buildroot 自构建工具链:适用于高度定制的嵌入式系统。

  4. 厂商 SDK 提供的工具链:推荐优先使用,对目标硬件更有保障。