2、交叉编译工具链安装:下载并配置ARM交叉编译器

好,咱们接着往下走。上一节我们把源码环境准备好了,这一节要解决一个核心问题——怎么让PC给ARM板子编译程序

说白了,你PC上的gcc编译出来的东西,是给x86架构用的。ARM板子不认识。所以我们需要一个交叉编译器,它跑在PC上,但生成的目标代码是ARM能跑的。

2.1 选哪个交叉编译器?

ARM交叉编译器有好几种,我个人的习惯是直接用gcc-arm-linux-gnueabihf。为什么选它?

  • gnueabihf 表示硬浮点(hard float),ARM Cortex-A系列基本都支持
  • 社区支持好,文档多,遇到问题容易搜到
  • Linaro维护的版本比较稳定,我一直在用

如果你用的是ARM64位板子,那就选 aarch64-linux-gnu 系列。不过咱们这课程以32位为例,原理是一样的。

2.2 下载工具链

我推荐从Linaro官网下载,或者用ARM官方的Arm GNU Toolchain。这里给两个常用地址:

版本 下载链接(示例) 说明
gcc-arm-linux-gnueabihf https://releases.linaro.org/components/toolchain/binaries/ Linaro维护,推荐
arm-none-linux-gnueabihf https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads ARM官方版本

我个人习惯用Linaro的,因为更新比较规律,而且压缩包直接解压就能用,不用安装。

下载命令示例:

wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz

注意:版本号可能会变,建议去官网看最新的稳定版。

2.3 解压与配置

下载完成后,解压到你的工作目录。我一般放在 /opt/toolchains/ 下面:

sudo mkdir -p /opt/toolchains
sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz -C /opt/toolchains/

解压完,你会看到一个文件夹,里面就是完整的工具链。接下来要配置环境变量,让系统能找到它。

小技巧: 我习惯把工具链路径加到 ~/.bashrc 里,这样每次打开终端自动生效。别加到 /etc/profile,万一搞错了影响整个系统。

编辑 ~/.bashrc,在末尾添加:

export PATH=$PATH:/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm

然后执行 source ~/.bashrc 让它生效。

2.4 验证工具链

配置完了,怎么知道好不好使?跑几个命令验证一下。

第一步:检查编译器版本

arm-linux-gnueabihf-gcc --version

如果看到类似这样的输出,说明工具链能正常调用:

arm-linux-gnueabihf-gcc (Linaro GCC 7.5-2019.12) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.

第二步:写个简单的C程序测试

创建一个 hello.c

#include <stdio.h>

int main() {
    printf("Hello from ARM!\n");
    return 0;
}

用交叉编译器编译:

arm-linux-gnueabihf-gcc -o hello hello.c

然后查看生成的文件信息:

file hello

你应该会看到:

hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3

看到 ARMEABI5 这几个关键词,就说明编译成功了。这个文件不能在PC上直接运行,但可以放到ARM板子上跑。

2.5 避坑指南

我曾经踩过的坑:

  • 路径写错: 有一次我把 bin 目录的路径写成了上一级,结果gcc找不到。检查路径时一定要确认 bin 目录下确实有 arm-linux-gnueabihf-gcc 这个文件。
  • 版本不匹配: 工具链的glibc版本如果比板子上的老,编译出来的程序可能跑不起来。建议用和板子内核版本相近的工具链。
  • 32位 vs 64位: 如果你的PC是64位的,但工具链是32位的,需要安装32位兼容库。Ubuntu下执行 sudo apt install lib32z1 lib32ncurses5

2.6 验证完整流程

为了确保万无一失,我建议再做一个更完整的测试——编译一个带依赖的程序。比如用到了数学库:

arm-linux-gnueabihf-gcc -o test_math test_math.c -lm

然后用 readelf 查看动态链接信息:

arm-linux-gnueabihf-readelf -d test_math

你会看到类似:

Tag        Type                         Name/Value
0x00000001 (NEEDED)                     Shared library: [libm.so.6]
0x00000001 (NEEDED)                     Shared library: [libc.so.6]

这说明工具链能正确链接ARM版本的库文件。嗯,到这里工具链就算配好了。

我的习惯: 每次配完工具链,我都会写一个简单的测试脚本,把上面这些验证步骤自动化。下次换机器或者重装系统,直接跑一遍脚本就完事,省得手敲命令。

好了,交叉编译工具链这块就到这。下一节我们开始真正编译Gstreamer,到时候你会频繁用到这个 arm-linux-gnueabihf-gcc,趁现在多熟悉熟悉它。