3. 搭建交叉编译环境:交叉编译工具链安装、环境变量配置、验证工具链
好,咱们正式开始动手干活了。
这一节要解决的是「怎么让代码在开发机上编译,然后扔到目标板子上跑」的问题。说白了,就是搭建交叉编译环境。我刚开始接触嵌入式时,觉得这步挺玄乎的,后来发现其实就是装个工具链、配个路径、跑个验证。别怕,一步步来。
3.1 什么是交叉编译?为什么需要它?
你想想看,你的开发机是 x86 架构的,但目标板子可能是 ARM 架构的。x86 上编译出来的程序,ARM 板子根本看不懂。怎么办?
答案就是交叉编译——在 x86 机器上,用一套专门生成 ARM 机器码的编译器,编译出能在 ARM 上运行的程序。这套编译器 + 链接器 + 库的集合,就叫交叉编译工具链。
核心概念:交叉编译 = 在 A 架构上编译出 B 架构能运行的程序。
我个人习惯把工具链比作「翻译官」。它把咱们写的 C 代码,翻译成 ARM 处理器能理解的机器指令。没有它,你写的驱动代码就是一堆废纸。
3.2 选择工具链:arm-linux-gnueabihf-gcc
咱们课程用的是 arm-linux-gnueabihf-gcc。这个命名其实很有讲究,我拆给你看:
| 字段 | 含义 |
|---|---|
| arm | 目标架构是 ARM |
| linux | 目标操作系统是 Linux |
| gnueabihf | 使用 GNU 的 EABI 规范,且支持硬件浮点(hf = hard float) |
| gcc | 编译器是 GCC |
小提示:如果你的板子不支持硬件浮点,要用 arm-linux-gnueabi-gcc(没有 hf)。我在项目中遇到过因为选错工具链,导致浮点运算性能暴跌的情况,嗯,那次排查了好久。
3.3 安装交叉编译工具链
安装方式有很多种,我推荐用包管理器或者直接下载预编译包。这里以 Ubuntu 系统为例:
方式一:apt 安装(推荐,省心)
sudo apt update
sudo apt install gcc-arm-linux-gnueabihf
装完后,工具链默认安装在 /usr/bin/ 下。你直接敲 arm-linux-gnueabihf-gcc --version 就能看到版本信息。
方式二:下载 Linaro 预编译包(更灵活)
有时候你需要特定版本,比如为了和老内核匹配。我会去 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
tar -xvf gcc-linaro-*.tar.xz
sudo mv gcc-linaro-* /opt/
注意:下载的版本要和你的内核版本匹配。我曾经因为用了太新的工具链编译老内核,结果链接阶段报了一堆莫名其妙的错误。后来换成 Linaro 7.5 就没事了。
3.4 配置环境变量
装完工具链,你得让系统知道它在哪里。环境变量配置是这步的关键。
我个人习惯把工具链路径加到 ~/.bashrc 里,这样每次打开终端自动生效:
echo 'export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin' >> ~/.bashrc
source ~/.bashrc
如果你用的是 apt 安装,路径已经在系统 PATH 里了,这步可以跳过。但为了保险,我还是建议验证一下。
我的习惯:我还会在 ~/.bashrc 里加一个别名:alias arm-gcc='arm-linux-gnueabihf-gcc',敲起来快很多。
3.5 验证工具链是否安装成功
配置完环境变量,别急着写代码。先跑几个命令确认工具链能用。
第一步:检查版本
arm-linux-gnueabihf-gcc --version
如果看到类似 arm-linux-gnueabihf-gcc (Linaro GCC 7.5-2019.12) 7.5.0 的输出,说明安装成功。
第二步:编译一个简单程序
写个 hello.c:
#include <stdio.h>
int main() {
printf("Hello, 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 字样了吗?这说明编译出来的程序确实是给 ARM 用的。你在 x86 上直接运行它会报错,因为架构不同。
验证要点:用 file 命令确认输出文件是 ARM 架构,这是最直观的验证方式。
3.6 常见问题与避坑指南
- 命令找不到:检查 PATH 是否包含工具链路径。我曾经忘记
source ~/.bashrc,结果折腾了十分钟。 - 版本不匹配:编译内核时,工具链版本太新或太旧都可能出问题。建议用 Linaro 7.5 或 8.3 这种经过广泛验证的版本。
- 32位 vs 64位:如果你在 64 位系统上运行 32 位工具链,可能需要安装
lib32z1等兼容库。
我曾经踩过的坑:有一次我装完工具链,编译内核时一直报 arm-linux-gnueabihf-gcc: command not found。查了半天,发现是 PATH 写错了路径。嗯,从那以后我每次配置完都会用 which arm-linux-gnueabihf-gcc 确认一下。
3.7 本章知识体系
下面这张图帮你理清交叉编译环境搭建的完整流程:
到这步,你的交叉编译环境就搭好了。接下来就可以用它来编译内核和驱动了。记住,环境搭建是基础,基础不牢,后面会各种翻车。花点时间把这步做扎实,后面会顺畅很多。
公众号:蓝海资料掘金营,微信deep3321