3. 环境准备

好,咱们正式开始动手了。这一章讲的是环境准备,说白了就是给你的开发机器“装上弹药”。我见过太多新手,甚至一些老手,在环境配置上栽跟头。你想想看,代码写得再漂亮,编译不过去,一切都是白搭。

我个人习惯,在开始一个新项目前,先把环境理得干干净净。这就像厨师做菜前先备料,料备好了,炒菜才快。咱们今天要搞定三件事:宿主机依赖、交叉编译工具链、还有版本控制工具。

3.1 宿主机依赖安装

宿主机,就是你用来开发的这台电脑。咱们做嵌入式,通常用的是 Ubuntu 或者 Debian 系的 Linux 发行版。为什么?因为包管理工具 apt 太方便了。

你需要安装一堆基础软件包。别嫌多,这些都是必需品。少了任何一个,编译到一半报错,你都得回来补装。

核心依赖包清单:

sudo apt-get update
sudo apt-get install -y \
    build-essential \
    cmake \
    autoconf \
    automake \
    libtool \
    pkg-config \
    bison \
    flex \
    texinfo \
    help2man \
    gawk \
    libncurses5-dev \
    libssl-dev \
    zlib1g-dev \
    libelf-dev \
    u-boot-tools \
    device-tree-compiler

这里我重点说一下 build-essential。它包含了 gcc、g++、make 这些最基础的编译工具。我曾经在一个新装的 Ubuntu 上直接跑编译脚本,结果报错说找不到 make。嗯,就是少了这个包。

还有 libncurses5-dev,这个是为了支持内核的 menuconfig 图形化配置界面。如果你打算自己裁剪内核,这个必须装。

小提示: 我个人习惯把这些依赖写成一个 shell 脚本,比如 setup_host.sh,放在 SDK 的根目录下。这样新同事来了,或者换了一台机器,直接跑一遍脚本就行,省得一个个敲命令。

3.2 交叉编译工具链配置

交叉编译,是嵌入式开发的灵魂。你的宿主机是 x86 架构,但目标板可能是 ARM、RISC-V 或者 MIPS。你得用一套特殊的编译器,在 x86 上生成目标架构的机器码。

工具链的获取方式,我见过三种:

  1. 芯片厂商提供:比如 ARM 的 gcc-arm-none-eabi,或者 NXP、TI 官方提供的工具链。这是最省心的方式。
  2. 自己用 crosstool-NG 编译:适合有特殊定制需求的场景。我早期做项目时,为了优化浮点性能,自己编译过一版工具链,那叫一个折腾。
  3. 使用 Linaro 或 Bootlin 的预编译工具链:社区维护,更新快,兼容性好。

不管哪种方式,配置的核心就是设置环境变量。我建议你把它写到 ~/.bashrc 或者 SDK 的 envsetup.sh 脚本里。

典型的工具链配置示例:

# 假设工具链安装在 /opt/toolchains 目录下
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
export PATH=/opt/toolchains/gcc-arm-10.3-2021.07-x86_64-arm-linux-gnueabihf/bin:$PATH

# 验证是否配置成功
arm-linux-gnueabihf-gcc --version

这里有个坑,我必须要说。我曾经遇到过 CROSS_COMPILE 变量末尾忘记加短横线 - 的情况。结果编译内核时,系统找不到对应的编译器,报了一堆莫名其妙的错误。你想想看,就少了一个字符,排查了整整两个小时。

避坑指南: 我曾经在同时维护多个项目时,把不同架构的工具链路径搞混了。编译 ARM 的代码,结果 PATH 里指向的是 x86 的交叉编译器。最后链接阶段报错,说找不到某些库。从那以后,我每次编译前都会执行 echo $CROSS_COMPILE 确认一下当前环境。

3.3 版本控制工具(Git/Repo)设置

做 SDK 发布,版本控制是命根子。没有它,你根本没法追溯代码变更,也没法协同开发。

Git 是基础,这个不用多说。但咱们做嵌入式,一个 SDK 往往包含几十个 Git 仓库:内核、uboot、文件系统、各个驱动模块、应用层代码。一个个去 git clone 会疯掉的。

这时候,Google 的 Repo 工具就派上用场了。它本质上是一个对 Git 的封装,通过一个 manifest.xml 文件,管理多个 Git 仓库的版本和分支。

Repo 的安装和初始化:

# 安装 Repo
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=~/bin:$PATH

# 初始化一个 SDK 工作区
mkdir my_sdk
cd my_sdk
repo init -u https://your-server.com/manifest.git -b release-v1.0
repo sync

我个人习惯,在 manifest.xml 里明确指定每个仓库的 revision 为具体的 commit ID,而不是分支名。为什么?因为分支名是浮动的,今天拉下来的代码和明天拉下来的可能不一样。用 commit ID 才能保证构建的可复现性。

Git 的配置也很关键。尤其是 user.name 和 user.email,这直接关系到代码提交记录的准确性。

我的 Git 配置建议:

git config --global user.name "Your Name"
git config --global user.email "your.email@company.com"
git config --global core.editor "vim"
git config --global merge.tool "vimdiff"
git config --global color.ui true

# 设置别名,提高效率
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

嗯,这里要注意。如果你在公司内部使用 Git,建议把 user.email 设置成公司邮箱。这样代码审查时,一眼就能看出是谁提交的。我曾经见过有人用个人邮箱提交代码,结果离职后,那行代码出了问题,想找人问问都找不到。

3.4 本章知识体系总览

为了让你更直观地理解这三部分的关系,我画了一张图。你可以看到,宿主机依赖是地基,交叉编译工具链是桥梁,版本控制工具是管理中枢。三者缺一不可。

环境准备:三大核心模块 宿主机依赖 build-essential cmake / autoconf libncurses5-dev libssl-dev device-tree-compiler 基础编译环境 交叉编译工具链 CROSS_COMPILE ARCH=arm PATH 配置 gcc / g++ / ld crosstool-NG 目标架构代码生成 版本控制工具 Git 基础配置 Repo 工具安装 manifest.xml repo init / sync commit ID 锁定 多仓库协同管理 三者协同工作,构成 SDK 构建的基础环境

好了,环境准备这部分就讲到这里。你按照上面的步骤,把宿主机依赖装好,交叉编译工具链配好,Git 和 Repo 设置好,就可以开始下一步了。记住,环境配置一次到位,后面能省下大把的排查时间。

总结一下本章要点:

  • 宿主机依赖:用 apt 批量安装,写脚本固化流程
  • 交叉编译工具链:设置 CROSS_COMPILE、ARCH、PATH 三个核心变量
  • 版本控制:Git 配置用户信息,Repo 管理多仓库,manifest 锁定 commit ID

可可精品资料库