
ArduPilot 源码构建完全指南从 Waf 配置到多机型固件编译【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot本指南以 ArduPilot 官方构建文档 BUILD.md 为主体完整讲解基于 Waf 构建系统的源码编译流程从克隆仓库、配置目标板卡、编译 ArduCopter / ArduPlane / ArduRover 等机型到上传固件、并行编译、Docker 构建与 program group 高级用法。读完本文你将能够独立完成任意受支持板卡与机型组合的固件构建并理解构建产物在build/board/下的组织方式与 Waf 命令背后的源码实现。一、获取源码与前置约定ArduPilot 是一个包含多个 git 子模块的大型工程克隆时必须带上--recurse-submodules参数否则后续构建会因为缺少 mavlink、ChibiOS、waf 等子模块而失败git clone --recurse-submodules https://github.com/ArduPilot/ardupilot.git cd ardupilot子模块依赖的管理逻辑可以在根 wscript 中找到configure阶段会加载git_submodule工具wscript构建阶段则把子模块同步任务作为独立的 group 先于动态源码生成执行。使用 Waf 时需遵守两条硬性约定始终在本地克隆的 ardupilot 根目录即你正在构建的那个分支所在目录调用waf不要在其他目录执行绝对不要用sudo运行waf这会导致权限与构建环境问题。关于 Waf 构建系统本身的通用设计可参考其官方手册Waf Book但 ArduPilot 的使用方式完全以本文所讲命令为准。二、Waf 构建系统概览从源码看构建骨架ArduPilot 的构建系统由根目录的 wscript入口脚本、Tools/ardupilotwaf/ArduPilot 定制的 Waf 工具集以及各机型目录下的wscript如 ArduCopter/wscript共同组成。waf的典型执行流程是configure命令解析--board等选项写入板卡环境配置wscriptbuild命令按主程序组program group收集目标、生成动态源码mavlink、DroneCAN、递归编译各 libraries 与机型代码wscript产物统一输出到build/board/主程序组/目录。从 Tools/ardupilotwaf/ardupilotwaf.py 的ap_programL363-L417与ap_stlib实现可以看到每个可执行程序都会被注册到一个或多个 program group例如 ArduCopter/wscript 中arducopter同时属于bin与copter组arducopter-heli同时属于bin与heli组这正是后面各种快捷命令能工作的基础。三、基本用法配置板卡并编译机型3.1 构建 ArduCopter以 Pixhawk2/Cube 为例./waf configure --board CubeBlack ./waf copterconfigure命令只在第一次或需要更改配置选项时执行一次最常见的变化就是通过--board切换目标板卡copter是 ArduPilot 注册的构建快捷命令等价于构建copterprogram group 内的全部程序编译完成后arducopter二进制出现在build/board-name/bin目录下例如build/CubeBlack/bin/arducopter。切换到另一块板卡并重新构建以 SkyViper GPS 无人机为例./waf configure --board skyviper-v2450 ./waf copter3.2 需要静态链接的特殊板卡部分板卡如 Parrot Bebop/Bebop2要求二进制以静态方式链接此时需在 configure 阶段加上--static./waf configure --board bebop --static ./waf copter--static选项定义在根 wscriptconfigure 时会将STATIC_LINKING写入构建环境wscriptTools/ardupilotwaf/static_linking.py 负责强制静态链接。四、板卡支持列出与选择目标板卡4.1 列出全部支持的板卡./waf list_boards该命令实现在 wscript直接打印boards.get_boards_names()的结果。4.2 板卡的动态发现机制ArduPilot 的板卡列表并非硬编码而是动态扫描得到的Tools/ardupilotwaf/boards.pyChibiOS 板卡扫描libraries/AP_HAL_ChibiOS/hwdef下所有包含hwdef.dat或hwdef-bl.dat的子目录Linux 板卡扫描libraries/AP_HAL_Linux/hwdefSITL 板卡扫描libraries/AP_HAL_SITL/hwdefESP32 板卡扫描libraries/AP_HAL_ESP32/hwdef并以目录名前缀esp32s3区分 MCU 类型。也就是说每增加一个新板卡只需在对应 HAL 的hwdef目录下新增一个含hwdef.dat的子目录无需改动构建脚本。4.3 常用板卡的配置命令速查./waf configure --board bebop --static # Bebop or Bebop2 ./waf configure --board edge # emlid edge ./waf configure --board fmuv3 # 3DR Pixhawk 2 boards ./waf configure --board navio2 # emlid navio2 ./waf configure --board Pixhawk1 # Pixhawk1 ./waf configure --board CubeBlack # Hex/ProfiCNC Cube Black (formerly known as Pixhawk 2.1) ./waf configure --board Pixracer # Pixracer ./waf configure --board skyviper-v2450 # SkyRockets SkyViper GPS drone using ChibiOS ./waf configure --board sitl # software-in-the-loop simulator ./waf configure --board sitl --debug # software-in-the-loop simulator with debug symbols注意configure对板卡名大小写不敏感若未精确匹配构建系统会进行不区分大小写的查找wscript并且当完全不指定--board时默认回退到sitlwscript。历史上被移除的板卡如 px4-v1/v2/v3/v4/v4pro由 Tools/ardupilotwaf/boards.py 单独维护不再参与构建。五、可构建的机型目标常用的机型构建目标如下./waf copter # All multirotor types ./waf heli # Helicopter types ./waf plane # Fixed wing airplanes including VTOL ./waf rover # Ground-based rovers and surface boats ./waf sub # ROV and other submarines ./waf antennatracker # Antenna trackers ./waf AP_Periph # AP Peripheral这些快捷命令在根 wscript 中统一注册vehicles列表antennatracker、blimp、copter、heli、plane、rover、sub加上bootloader、iofirmware、AP_Periph、replay都会被ardupilotwaf.build_command()注册为独立命令。AP_Periph的固件对应 Tools/AP_Periph 目录其可用的板卡列表可由./waf list_ap_periph_boards查看。六、清理构建与子模块同步./waf clean # 仅清理当前板卡的编译产物保留 configure 信息 ./waf distclean # 清理所有板卡的产物与 configure 信息官方明确建议通常没有必要做 clean。构建系统本身支持增量编译可把重编译时间降低数个数量级频繁 clean 反而会损失这一优势。跨分支开发例如在稳定版与 master 之间切换时若子模块无法同步可依次尝试./waf submodulesync通过Tools/gittools/submodule-sync.sh重新同步子模块实现在 wscript./waf submodule_force_clean删除modules/下除白名单COLCON_IGNORE、esp_idf之外的所有子模块目录后重新同步wscript适用于子模块状态严重错乱的场景。七、上传固件与安装7.1 直接上传到板卡构建命令支持--upload选项将编译好的二进制直接烧录/上传到连接的板卡Pixhawk 类板卡与 Linux 板卡均支持./waf --targets bin/arducopter --upload7.2 Linux 板卡通过 rsync 上传Linux 板卡需要在 configure 阶段先指定目标 IP 与路径之后再使用--upload./waf configure --board navio2 --rsync-dest root192.168.1.2:/ ./waf --target bin/arducopter --upload其底层原理wscript为先执行localinstall将产物安装到build/board/install临时目录再执行rsync 临时安装目录/ 目标地址。--rsync-dest既可以在 configure 阶段传入也可以在执行时传入见RsyncContext对RSYNC_DEST的检查逻辑构建系统还会在 configure 时自动探测rsync程序是否存在。7.3 安装到指定目录面向打包分发Linux 板卡还支持标准的install命令配合DESTDIR可将产物安装到任意目录供发行版打包.deb、.rpm等使用./waf copter DESTDIR/my/temporary/location ./waf install八、构建特定目标前面的copter等命令会构建该组下的全部二进制。若只想构建单个目标使用--targets# 列出所有可能的构建目标 ./waf list # Quad frame of ArduCopter仅 arducopter 主程序 ./waf --targets bin/arducopter # unit test of our math functions ./waf --targets tests/test_math--targets的取值是相对于build/board/的路径例如bin/arducopter、tests/test_math。底层通过_process_build_command与_select_programs_from_groupTools/ardupilotwaf/ardupilotwaf.py把组内程序逐一展开为具体目标。九、使用 clang 替代 gccLinux 平台默认使用 gccmacOS 默认使用 clang。要在 Linux 上用 clang 构建可在 configure 阶段通过环境变量指定编译器CXXclang CCclang ./waf configure --boardsitl注意你的环境中 clang 可执行文件的命名可能不同如clang-14请按实际名称调整。编译器探测与跨编译支持逻辑见 Tools/ardupilotwaf/toolchain.py。十、查看全部命令与选项./waf -h-h会列出 Waf 内置命令/选项以及 ArduPilot 新增的定制选项。ArduPilot 的定制选项相当丰富全部定义在根 wscript 的options()中常用者包括选项说明--debug配置为调试变体保留调试符号配合 gdb--debug-symbols/-g仅向构建添加调试符号--static强制静态链接--enable-benchmarks启用 benchmarks 程序组--disable-tests禁用测试的编译与执行--enable-scripting/--disable-scripting启用/禁用机载 Lua 脚本引擎--default-parameters file将默认参数文件嵌入固件--Werror/--disable-Werror开关-Werror--extra-hwdef file为自定义板卡附加额外的hwdef.dat内容--rsync-dest dest设置 Linux 板卡上传目标--no-autoconfig关闭自动重新配置--no-submodule-update不更新 git 子模块固定子模块版本时有用--coverage配置覆盖率编译标记--signed-fw/--private-key支持签名固件此外Tools/scripts/build_options.py中定义的构建选项如--enable-xxx/--disable-xxx会由add_build_options()自动注册进 configure 选项组wscript无需手工维护。十一、使用 Docker 构建仓库根目录提供了 Dockerfile适合在干净环境中构建、避免污染宿主环境# 构建 docker 镜像只需执行一次 docker build --rm -t ardupilot-dev . # 在容器内执行 waf 命令把当前目录挂载到 /ardupilot docker run --rm -it -v $PWD:/ardupilot ardupilot-dev ./waf configure --boardsitl docker run --rm -it -v $PWD:/ardupilot ardupilot-dev ./waf copter也可以直接进入容器内的 bash shell 交互执行本文档中的任意命令docker run --rm -it -v $PWD:/ardupilot ardupilot-dev十二、高级用法理解 program group 模型12.1 Waf 命令模型Waf 构建系统由一个个命令组成。configure命令负责收集本次构建的所有选项# Configure the Linux board ./waf configure --boardlinux随后发出build命令开始编译。build是默认命令直接调用waf即可也支持-j并行编译# Build programs from bin group ./waf # Waf also accepts -j option to parallelize the build. ./waf -j8默认情况下 waf 会自动使用所有处理器核心并行编译因此-j通常不需要——除非你使用 icecc需要更大数值或不想让构建占满整台机器的资源。12.2 主程序组Main groupsprogram group 用于表示一类程序可通过构建整个组来避免逐个指定。一个程序可以属于多个组但只能属于一个主组main group两个主组之间互不重叠共同对所有程序形成划分。主组不仅做逻辑分类还决定程序被构建到哪个目录。另外存在一个特殊组all包含全部程序。五个主组及其含义bin主二进制即 ArduPilot 的核心产品——各机型固件与 Antenna Trackertools辅助工具examples演示各库用法或测试其功能的示例程序benchmarks基准测试需要 configure 时加--enable-benchmarkstests单元测试用于保证改动不破坏系统逻辑。所有构建文件位于build/board/下每个主组对应一个同名子目录程序存放在build/board/主组名/。例如 Linux 构建下arduplane属于bin主组其路径为build/linux/bin/arduplane。主组与产物的映射关系由ap_program中的program_dir决定Tools/ardupilotwaf/ardupilotwaf.py目录由ap_create_program_dir自动创建。12.3 主产品组Main product groups主产品组对应 ArduPilot 的核心产品包含该产品下的所有程序。目前仅copter组包含多个程序每种机架类型一个即arducopter与arducopter-heli见 ArduCopter/wscriptantennatrackercopterplanerover12.4 使用--program-group构建组ArduPilot 为 waf 增加了--program-group选项接收组名作为参数可重复传入。若 build 命令既没有--targets也没有--program-group默认选择bin组见_select_programs_from_groupTools/ardupilotwaf/ardupilotwaf.py# Group bin is the default one ./waf # Build all vehicles and Antenna Tracker ./waf --program-group bin # Build all benchmarks and tests ./waf --program-group benchmarks --program-group tests12.5 组名作为命令的快捷方式为减少打字可以直接把组名当作 waf 命令使用# Build all vehicles and Antenna Tracker ./waf bin # Build all examples ./waf examples # Build arducopter binaries ./waf copter这些命令由根 wscript 的build_command()循环注册all、bin、tool、examples、tests、benchmarks。12.6 构建特定程序指定单个程序时传入其相对于build/board/的路径# Build arducopter for quad frame ./waf --targets bin/arducopter # Build vectors unit test ./waf --targets tests/test_vectors12.7 检查check 与 check-allcheck命令会构建全部程序并执行相关测试。所谓相关测试是指tests组中满足以下任一条件的测试程序自上次清理或克隆以来首次构建因代码或依赖变更而需要重新编译上次 check 中执行失败的测试。也就是说check只按需运行测试并非每次都全量跑。若希望强制执行全部测试使用--alltests选项或check-all快捷命令# Build everything and run relevant tests ./waf check # Build everything and run all tests ./waf check --alltests # Build everything and run all tests ./waf check-allcheck依赖 gtest 库缺少时会直接报错见 wscript测试结果汇总由test_summary输出Tools/ardupilotwaf/ardupilotwaf.py任一测试失败都会以bld.fatal终止。12.8 调试构建给configure传--debug会设置编译器标志、在二进制中保留调试信息从而可用gdb调试配合 SITL软件在环仿真排障时尤其有用./waf configure --board sitl --debug调试变体还会在 configure 输出中明确打印 Debug build: enabledwscript。12.9 构建系统包装器wrappers根目录的waf二进制实际上是指向真实 waf 的包装脚本——真正的 waf 维护在独立子模块中。你可以直接调用./modules/waf/waf-light或用别名免去./alias wafardupilot-directory/modules/waf/waf-light此外还有一个 Make 包装器Makefile.waf各机型目录下均有如 ArduCopter/Makefile.waf使用make -f Makefile.waf help可查看其用法说明。12.10 命令行帮助waf --help可查看 waf 内置命令与选项的说明以及 ArduPilot 新增选项的快速帮助。十三、构建常见注意事项始终从仓库根目录调用waf且不要用sudo不要滥用clean/distclean增量编译是性能的关键仅在确实需要时清理跨分支切换务必同步子模块优先submodulesync必要时使用submodule_force_clean首次 configure 的板卡默认值是sitl如果你本意是交叉编译真实硬件请显式传入--board产物位置遵循build/board/主组/规则查找固件、上传、打包时以此为基准如build/CubeBlack/bin/arducopter、build/linux/bin/arduplane。至此从源码克隆、板卡配置、机型编译、上传安装到 program group 深度定制你已经掌握了 ArduPilot Waf 构建系统的完整链路。深入理解构建系统实现细节的读者可以继续阅读根 wscript 与 Tools/ardupilotwaf/ 中的各个模块板卡抽象见 boards.py程序注册与命令展开见 ardupilotwaf.pyChibiOS 固件打包见 chibios.py。【免费下载链接】ardupilotArduPlane, ArduCopter, ArduRover, ArduSub source项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考