3. 源码获取与编译:克隆ArduPilot仓库、选择分支、配置编译参数、首次编译与常见错误处理
好,到了真正动手的环节了。前面我们把环境搭好了,现在要拿源码、选分支、然后编译。这一步卡住的人特别多,我见过不少新手在编译上折腾一整天。其实没那么玄乎,咱们一步步来。
3.1 克隆ArduPilot仓库
先找个干净的工作目录。我个人习惯在 ~/workspace 下干活,你也可以放别处,但路径里别带中文和空格。
cd ~/workspace
git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
这里有个坑——网络问题。GitHub 有时候慢得像蜗牛,尤其克隆这么大的仓库。我建议你提前挂好代理,或者用国内镜像。如果实在慢,可以只克隆最新一层:
git clone --depth=1 https://github.com/ArduPilot/ardupilot.git
但注意,--depth=1 会丢失历史记录,后面切换分支可能不方便。如果你只是做仿真,其实够用了。
3.2 选择分支:Copter-4.5 / Plane-4.5
仓库下好了,接下来选分支。ArduPilot 的分支命名很直观:Copter-4.5 对应四旋翼固件 4.5 版本,Plane-4.5 对应固定翼。咱们做仿真联调,我建议统一用 4.5 分支,稳定且文档齐全。
git checkout Copter-4.5
为什么要选分支?因为 master 分支是开发版,今天能编译通过,明天可能就挂了。我在项目里吃过这个亏——早上还能跑,下午 pull 了一下,编译直接报错,查了半天发现是某个依赖更新了。所以,做仿真、做产品,永远锁定稳定分支。
git branch -a 查看所有可用分支。如果你需要特定版本,比如 Copter-4.4,也能找到对应的 tag。
3.3 配置编译参数:--board Pixhawk1
分支选好了,接下来配置编译目标板。仿真联调我们一般用 SITL(Software In The Loop),但这里我让你先编译 Pixhawk1 的固件,目的是验证工具链是否正常。说白了,先跑通一个真机固件,再切到仿真模式,心里有底。
./waf configure --board Pixhawk1
这条命令会检查你的编译器、Python 环境、依赖库是否齐全。如果缺东西,它会报错并提示你安装。嗯,这里要注意:./waf 是 ArduPilot 的构建系统,不是系统自带的,它就在仓库根目录下。
配置成功后,你会看到类似这样的输出:
Configuring for board Pixhawk1
Checking for program 'arm-none-eabi-g++' : /usr/bin/arm-none-eabi-g++
Checking for program 'arm-none-eabi-gcc' : /usr/bin/arm-none-eabi-gcc
...
Configuration completed successfully.
如果卡在某个检查项,别慌。最常见的是 arm-none-eabi-g++ 没装,或者 Python 模块缺失。回头检查一下第二章的环境安装。
3.4 首次编译
配置通过后,开始编译。第一次编译会下载所有子模块和依赖,时间比较长,去泡杯咖啡吧。
./waf copter
这里 copter 是目标名称,对应你之前选的分支。如果你选的是 Plane 分支,就改成 ./waf plane。
编译过程中,你会看到大量输出,从 C++ 源文件到链接器,最后生成 .px4 或 .elf 文件。看到类似下面的信息,说明成功了:
Waf: Leaving directory `/home/user/workspace/ardupilot/build/Pixhawk1'
'build' finished successfully (2m34.567s)
build/Pixhawk1/bin/ 目录下会生成 arducopter.apj 或 arduplane.apj 文件。这就是我们要的固件。
3.5 常见错误处理
编译这东西,一次过是运气,报错才是常态。我整理了几个高频问题,你遇到了直接对照排查。
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
arm-none-eabi-g++: not found |
交叉编译器未安装或未加入 PATH | 安装 gcc-arm-none-eabi,或检查 ~/.bashrc 中的路径 |
Python module 'xxx' not found |
缺少 Python 依赖 | pip install -r requirements.txt 重新安装 |
git submodule update failed |
子模块下载失败,网络问题 | git submodule update --init --recursive 重试,或换网络 |
fatal error: 'cmath' file not found |
工具链版本过旧或路径冲突 | 更新 gcc-arm-none-eabi 到最新版 |
Waf: Error. Build failed 无具体信息 |
磁盘空间不足或权限问题 | df -h 检查空间,chmod 检查权限 |
我曾经遇到过一个特别隐蔽的问题:编译到 90% 突然报错,提示某个头文件找不到。查了半天,发现是之前用 --depth=1 克隆时,子模块没完整下载。解决办法是重新完整克隆,或者手动补全子模块。
3.6 本章知识体系
下面这张图把整个流程串起来了,你可以对照着检查自己走到哪一步了。
这张图从左到右是主线流程,每个节点都可能出现分支——比如配置失败就回到环境检查,编译失败就查错误表。别怕报错,每个错误都是学习机会。我第一次编译 ArduPilot 时,连续报了 7 个错,一个个查下来,反而把整个工具链摸透了。