2. 开发环境搭建

好,咱们正式开始动手了。

这一章,说白了就是给你的电脑“武装”起来。我见过太多新手,一上来就急着写代码,结果编译报错半天,最后发现是环境没配好。嗯,磨刀不误砍柴工,咱们先把刀磨利索。

2.1 为什么选 Ubuntu/Debian?

你可能要问:为什么非得用 Linux?Windows 不行吗?

我个人习惯用 Ubuntu LTS 版本。原因很简单:社区活跃,遇到问题一搜就有答案。Debian 更稳定,但软件包稍旧。对于嵌入式开发,这两者都是主流选择。

我在项目中遇到过一位同事,用 CentOS 折腾了三天装工具链,最后换 Ubuntu 十分钟搞定。不是说 CentOS 不好,而是嵌入式社区的资源大多围绕 Ubuntu/Debian 生态。

我的建议:新手直接用 Ubuntu 22.04 LTS 或 Debian 12。别追新,稳定第一。

2.2 基础环境配置

拿到一台新装的 Ubuntu,第一件事是什么?不是装开发工具,而是先让系统能上网、能更新。

# 更新软件源
sudo apt update
sudo apt upgrade -y

# 安装基础开发工具
sudo apt install -y build-essential
sudo apt install -y git
sudo apt install -y vim
sudo apt install -y curl wget

这里有个坑:build-essential 这个包会帮你装好 gcc、g++、make 等核心工具。但注意,它装的是 本地 的 gcc,也就是给 x86 架构用的。咱们后面还要装交叉编译工具链。

注意:千万别用 sudo apt install gcc 单独装,依赖容易乱。直接装 build-essential 最省心。

2.3 必要工具链详解

2.3.1 gcc:编译器的灵魂

gcc 是 GNU Compiler Collection 的缩写。它能把 C 代码变成机器码。你写个 hello.c,gcc 一跑,就出来个可执行文件。

# 验证 gcc 是否装好
gcc --version

# 写个简单的测试
echo '#include <stdio.h>' > test.c
echo 'int main() { printf("Hello, Embedded!\n"); return 0; }' >> test.c
gcc -o test test.c
./test

输出 Hello, Embedded! 就说明本地环境没问题。

2.3.2 make:自动化构建的管家

你想想看,一个项目几十个源文件,每次改一个文件都要重新编译全部?那太傻了。make 就是干这个的——它只编译你改过的文件。

# 验证 make
make --version

# 写个简单的 Makefile
echo 'all: test' > Makefile
echo 'test: test.c' >> Makefile
echo '	gcc -o test test.c' >> Makefile
make

我个人习惯用 make -j4 来并行编译,能快不少。但注意,别把 CPU 跑满,留一个核给系统用。

2.3.3 git:版本控制的基石

没有 git,你都不敢改代码。我见过有人用 main.c.bak、main.c.bak2 这种命名方式……嗯,那是灾难。

# 配置 git 基本信息
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# 验证
git --version
小技巧:建议配置 SSH 密钥,后面拉取 SDK 源码会方便很多。

2.4 交叉编译工具链:嵌入式开发的核心

好,重点来了。

为什么需要交叉编译?因为你的开发电脑是 x86 架构,而目标板(比如 ARM 开发板)是 ARM 架构。x86 的 gcc 编译出来的程序,ARM 板跑不了。

交叉编译工具链,说白了就是一套能在 x86 上运行、但生成 ARM 代码的编译器。

核心概念:
  • 宿主机(Host):你的 Ubuntu 电脑,x86 架构
  • 目标机(Target):嵌入式开发板,比如 ARM、RISC-V
  • 交叉编译器:在宿主机上运行,生成目标机代码

2.4.1 常见的交叉编译工具链命名

你可能会看到类似这样的名字:

arm-linux-gnueabihf-gcc
aarch64-linux-gnu-gcc
riscv64-linux-gnu-gcc

命名规则其实很简单:

部分 含义 示例
架构 目标 CPU 架构 arm, aarch64, riscv64
操作系统 目标系统类型 linux, none(裸机)
库类型 C 库实现 gnueabi, gnueabihf
后缀 浮点运算方式 hf(硬浮点), sf(软浮点)

我曾经在项目中踩过一个坑:用 arm-linux-gnueabi 编译的程序,放到 arm-linux-gnueabihf 的系统上跑,浮点运算直接崩溃。后来才明白,hf 表示硬浮点,eabi 是软浮点,两者不兼容。

2.4.2 安装交叉编译工具链

以 ARM 为例,Ubuntu 上可以直接用 apt 安装:

# 安装 ARM 交叉编译工具链
sudo apt install -y gcc-arm-linux-gnueabihf
sudo apt install -y g++-arm-linux-gnueabihf

# 验证
arm-linux-gnueabihf-gcc --version

如果你用的是厂商提供的 SDK,通常会自带工具链。比如 NXP 的 SDK 里就有 gcc-arm-none-eabi 系列。

重要提醒:不要用 sudo 安装非官方源里的工具链。我见过有人从百度网盘下载了个“优化版”工具链,结果编译出来的程序有内存泄漏。老老实实用官方源或芯片厂商提供的版本。

2.5 验证环境:写个交叉编译的例子

光说不练假把式。咱们写个简单的程序,用交叉编译器编译,看看能不能跑在目标板上。

// hello_arm.c
#include <stdio.h>

int main() {
    printf("Hello from ARM!\n");
    return 0;
}
# 用交叉编译器编译
arm-linux-gnueabihf-gcc -o hello_arm hello_arm.c

# 查看生成的文件类型
file hello_arm

输出应该类似:

hello_arm: 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 架构的可执行文件。你在 x86 电脑上跑不了它,会报 Exec format error。把它传到 ARM 开发板上,就能正常运行。

2.6 本章知识体系

为了让你更直观地理解整个环境搭建的逻辑,我画了张图:

嵌入式Linux开发环境搭建知识体系 宿主机(Ubuntu/Debian x86) 系统更新 & 基础包 build-essential (gcc/make) git 版本控制 交叉编译工具链 arm-linux-gnueabihf-gcc aarch64-linux-gnu-gcc riscv64-linux-gnu-gcc 目标机(ARM/RISC-V 开发板) 注:宿主机上编译,目标机上运行

这张图把整个流程串起来了。你从宿主机开始,装好基础工具,再装上交叉编译工具链,最后编译出来的程序就能在目标板上跑了。说白了,就是“在 x86 上造 ARM 的轮子”。

2.7 避坑指南

最后,分享几个我亲身踩过的坑:

  • 路径问题:交叉编译工具链的路径一定要加到 PATH 环境变量里。我曾经忘了加,结果系统调用了本地 gcc,编译出来的东西在 ARM 板上跑不了,排查了半天。
  • 库依赖:交叉编译时,链接的库也必须是交叉编译版本。别想着偷懒用本地库,会出大问题。
  • 权限问题:别用 root 用户做开发。我见过有人用 sudo make,结果生成的文件 root 所有,后面改代码还得 sudo,麻烦得很。
我的习惯:每次配好环境,我都会写个简单的测试程序,分别用本地 gcc 和交叉编译器编译,确认都能正常工作。这一步花不了两分钟,但能省下后面几小时的排查时间。

好,环境搭好了,工具链也装上了。接下来,你就可以开始真正接触 SDK 的结构了。