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
看到 ARM 和 EABI5 这几个关键词,就说明编译成功了。这个文件不能在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,趁现在多熟悉熟悉它。