4. 交叉编译工具链构建
好,咱们正式开始动手。这一章我带你走一遍交叉编译链的完整安装流程。别小看这一步,很多新手甚至老手都在这栽过跟头。我自己就见过同事因为环境变量配错,折腾了一整天——结果发现是路径里多了个空格。
说白了,交叉编译链就是一套工具集。它能在你的x86电脑上,编译出给ARM开发板运行的二进制程序。没有它,你写的驱动代码就是一堆文本,跑不起来。
4.1 选择Linaro工具链
Linaro是目前ARM Linux开发最主流的工具链提供商。它基于GCC,针对ARM架构做了大量优化。我个人习惯用它的稳定发布版,而不是每日构建版——稳定压倒一切。
你需要下载的是 gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz 这个版本。为什么选7.5.0?因为它在ARMv7-A架构上经过充分验证,兼容性好,坑少。
| 工具链版本 | GCC版本 | 目标架构 | 适用场景 |
|---|---|---|---|
| gcc-linaro-7.5.0-2019.12 | 7.5.0 | arm-linux-gnueabihf | ARMv7-A/Cortex-A系列,带硬件浮点 |
| gcc-linaro-6.5.0-2018.12 | 6.5.0 | arm-linux-gnueabihf | 老内核(3.x/4.x)兼容性更好 |
| gcc-arm-10.3-2021.07 | 10.3.0 | arm-linux-gnueabihf | 新特性支持,但可能有兼容性问题 |
4.2 下载与解压
下载地址我就不贴了,你直接去Linaro官网的Releases页面找。我建议用wget命令行下载,比浏览器下载靠谱——万一断网了还能断点续传。
# 创建工具链存放目录
mkdir -p ~/tools/arm-gcc
cd ~/tools/arm-gcc
# 下载(如果网络慢,可以用国内镜像)
wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
# 解压
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
解压完成后,你会得到一个 gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf 目录。里面结构大概是这样的:
gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/
├── arm-linux-gnueabihf/ # 目标系统的库和头文件
├── bin/ # 编译器、链接器等可执行文件
├── lib/ # 工具链自身的库
├── libexec/ # 内部工具
└── share/ # 文档和示例
4.3 配置环境变量
环境变量配置是这章的重头戏。说白了,就是告诉系统:当你输入 arm-linux-gnueabihf-gcc 时,去哪里找这个程序。
我个人习惯把配置写在 ~/.bashrc 里,而不是 /etc/profile。这样只影响当前用户,不影响系统全局,更安全。
# 编辑 ~/.bashrc
vim ~/.bashrc
# 在文件末尾添加以下内容
export PATH=$PATH:/home/你的用户名/tools/arm-gcc/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
# 保存退出后,使配置生效
source ~/.bashrc
这里有个细节要注意:PATH 变量是追加而不是覆盖。如果你写成 export PATH=/your/path,那系统原来的命令全找不到了——连 ls、cd 都会报错。嗯,我当年就干过这种事,吓得赶紧重启终端。
CROSS_COMPILE 和 ARCH 环境变量,后续编译内核和驱动时会用到:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
4.4 验证安装
配置完环境变量,怎么知道装好了?三步验证法,一步都不能少。
- 检查命令是否存在
which arm-linux-gnueabihf-gcc
如果返回了路径,说明PATH配置正确。如果返回 "not found",回去检查路径写没写对。
- 检查版本信息
arm-linux-gnueabihf-gcc --version
正常会输出类似:
arm-linux-gnueabihf-gcc (GCC) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- 编译一个测试程序
# 写一个简单的C程序
echo '#include <stdio.h>
int main() {
printf("Hello, ARM!\n");
return 0;
}' > test.c
# 用交叉编译器编译
arm-linux-gnueabihf-gcc test.c -o test_arm
# 查看生成的文件信息
file test_arm
如果输出是 ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),恭喜你,交叉编译链安装成功!
readelf -h test_arm 可以查看更详细的ELF头信息,包括架构、字节序、ABI版本等。我在调试驱动时经常用这个命令确认编译目标是否正确。
4.5 知识结构图
下面这张图帮你理清整个安装流程的逻辑关系:
4.6 避坑指南
安装过程中有几个坑,我帮你提前踩一遍:
- 32位库缺失:如果你用的是64位系统,运行
arm-linux-gnueabihf-gcc可能会报 "No such file or directory"。这不是文件不存在,而是缺少32位兼容库。安装lib32z1和lib32ncurses5就能解决。 - 权限问题:解压后的工具链目录要有可执行权限。如果遇到 "Permission denied",用
chmod +x bin/*修复。 - 多版本冲突:如果你系统里装了多个交叉编译链,PATH里谁在前谁生效。我习惯把最常用的版本放在PATH最前面。
source ~/.bashrc 或者重启终端。如果你发现刚才配好的环境变量不见了,八成是忘了这一步。
好了,到这一步你的交叉编译链已经装好并验证通过了。接下来就可以用它编译驱动模块、uboot、内核了。记住这个流程:下载 → 解压 → 配环境 → 验证。以后换版本、换机器,都是这个套路。