第3章:交叉编译环境配置

好,咱们接着往下走。上一章我们把开发板跑起来了,这一章要解决一个核心问题——怎么在PC上给ARM开发板编译程序。

你想想看,你的PC是x86架构,开发板是ARM架构。直接在PC上gcc编译出来的程序,ARM板子根本跑不了。怎么办?这就需要交叉编译链了。

3.1 什么是交叉编译链

说白了,交叉编译链就是一套能在PC上生成ARM可执行文件的工具集。它包括编译器、链接器、库文件等等。

我刚开始做嵌入式那会儿,对这东西也是一头雾水。后来自己动手配了一次,发现其实没那么玄乎。就是一套工具,装好了设好路径,就能用。

常见的交叉编译链有几种:

  • arm-linux-gnueabihf-gcc —— 针对ARM Cortex-A系列,支持硬浮点
  • arm-linux-gnueabi-gcc —— 针对ARM,软浮点
  • aarch64-linux-gnu-gcc —— 针对ARM 64位架构

咱们课程用的是Cortex-A7,32位,支持硬浮点。所以我选 arm-linux-gnueabihf-gcc

小提示: 怎么确认你的开发板架构?跑一下 uname -a 或者 cat /proc/cpuinfo。我习惯先看这个,免得选错工具链。

3.2 安装交叉编译链

安装方式有两种:要么从Linaro官网下载预编译包,要么用包管理器直接装。我推荐前者,版本可控。

具体步骤:

  1. 下载工具链:gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
  2. 解压到指定目录,比如 /opt/toolchains/
  3. 设置环境变量

解压命令很简单:

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/

解压完,你会看到 /opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf 这个目录。里面有个 bin 文件夹,编译器就在那。

注意: 我曾经遇到过解压后权限不对,导致编译报错。建议解压后检查一下目录权限:ls -l /opt/toolchains/。如果权限不对,用 sudo chown -R $USER:$USER /opt/toolchains/ 改一下。

3.3 环境变量设置

装好了,怎么让系统找到它?需要把 bin 目录加到 PATH 环境变量里。

我个人习惯把配置写在 ~/.bashrc 里,这样每次打开终端自动生效:

echo 'export PATH=$PATH:/opt/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin' >> ~/.bashrc
source ~/.bashrc

验证一下:

arm-linux-gnueabihf-gcc --version

如果看到版本信息,说明配置成功了。

嗯,这里要注意一点。有些同学喜欢把工具链路径写死,比如 export PATH=/opt/.../bin:$PATH。我个人不建议这样,万一你以后装多个版本,容易冲突。用 $PATH: 追加的方式更灵活。

3.4 测试编译第一个程序

环境配好了,咱们写个Hello World试试。

新建一个文件 hello.c

#include <stdio.h>

int main()
{
    printf("Hello, Embedded World!\n");
    return 0;
}

用交叉编译链编译:

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

编译完,用 file 命令看看生成的文件:

file hello

你会看到类似这样的输出:

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

看到 ARM 字样了吧?说明这确实是ARM架构的可执行文件。

把它传到开发板上跑一下:

scp hello root@192.168.1.100:/root/
ssh root@192.168.1.100
./hello

如果看到 Hello, Embedded World! 打印出来,恭喜你,交叉编译环境配置成功了!

核心要点:
  • 交叉编译链是嵌入式开发的基石
  • 安装后一定要设置PATH环境变量
  • file 命令验证编译结果
  • 在开发板上实际运行测试

3.5 常见问题与避坑

我这些年遇到过不少新手栽跟头的地方,列几个典型的:

问题 原因 解决方法
编译报错:找不到头文件 工具链路径没配好 检查 PATH 是否包含 bin 目录
编译通过,开发板跑不了 架构不匹配(比如选了64位工具链) file 确认架构,重新选工具链
提示 No such file or directory 动态库链接问题 试试静态编译:-static 参数
权限不足无法执行 文件没有可执行权限 chmod +x hello

我曾经遇到过最坑的一次——编译链版本太新,开发板上的glibc版本太老,结果程序跑起来就段错误。后来我学乖了,工具链版本尽量和开发板系统匹配。一般用Linaro 7.5.0或者4.9版本,兼容性比较好。

3.6 小结

这一章我们做了三件事:安装交叉编译链、设置环境变量、编译并运行第一个ARM程序。看起来简单,但这是嵌入式开发的第一步,也是最重要的一步。

下一章,我们会搭建完整的驱动开发工程模板。到时候你会发现,今天配好的交叉编译链,就是整个工程的基石。

好,先到这里。去动手试试吧,有问题随时回来翻翻这一章。