Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Ardupilot/ardupilot/llms.txt

Use this file to discover all available pages before exploring further.

ArduPilot uses Waf as its build system. A thin wrapper script at the repository root (./waf) delegates to the real Waf binary maintained as a Git submodule in modules/waf/. All build commands must be run from the repository root — never from a subdirectory — and must never be run as root. Configuration is performed once per target board; subsequent builds skip configuration and only recompile changed files, making incremental builds fast.
Do not run waf with sudo. This causes permission and environment problems. Always call ./waf as a regular user.

Listing available boards

Before configuring, you can see every supported board by running:
./waf list_boards
Commonly used board configurations are shown below. The --board name passed to configure must exactly match one of the names returned by list_boards.

Configuring and building

The configure step records your chosen board and any extra options. You only need to re-run it when switching boards or changing a configuration flag. All subsequent ./waf <target> calls use the saved configuration.
./waf configure --board CubeBlack
./waf copter
The compiled binary is written to build/<board-name>/bin/. For example, after building for CubeBlack, the ArduCopter binary appears at build/CubeBlack/bin/arducopter.

Vehicle build targets

Each vehicle type is a named group in Waf. Building a group compiles all binaries that belong to it:
./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 firmware

Program groups

Waf organizes all build targets into program groups. The default group built when you run ./waf with no arguments is bin:
GroupContents
binMain vehicle binaries — ArduPilot’s primary products
toolsSupporting tools
examplesLibrary usage examples and standalone tests
testsC++ unit tests (GTest-based)
You can build any group by name:
# Build all vehicles and tools (the default)
./waf bin

# Build all examples
./waf examples

# Build and run relevant unit tests
./waf check

Building specific targets

To build a single binary instead of an entire group, use --targets with the path relative to build/<board>/:
# Build only the quad-frame ArduCopter binary
./waf --targets bin/arducopter

# Build only the math unit test
./waf --targets tests/test_math
To see every possible target:
./waf list

Uploading to hardware

Build commands accept a --upload flag that flashes the compiled binary to a connected board over USB. This is supported for Pixhawk-family boards and Linux-based boards:
./waf --targets bin/arducopter --upload
For Linux boards accessed over a network, configure the destination address at configure time and then upload:
./waf configure --board navio2 --rsync-dest root@192.168.1.2:/
./waf --targets bin/arducopter --upload
Under the hood, --upload on Linux boards uses rsync to copy the binary to the configured destination.

Cleaning the build

Cleaning is rarely necessary. Waf performs incremental builds by default, recompiling only the files that changed. This reduces build time by orders of magnitude compared to a full rebuild. Only clean when you suspect stale build artifacts are causing problems.
Two levels of cleaning are available:
# Remove compiled objects for the current board only (keeps configure)
./waf clean

# Remove all build artifacts and saved configure information for all boards
./waf distclean
If Git submodules fall out of sync (common when switching between release branches and master), use submodulesync:
./waf submodulesync

Docker builds

A Docker environment is provided for building in a clean, isolated environment without modifying the host system. Build the image once:
docker build --rm -t ardupilot-dev .
Then prefix any Waf command with docker run:
docker run --rm -it -v $PWD:/ardupilot ardupilot-dev ./waf configure --board sitl
docker run --rm -it -v $PWD:/ardupilot ardupilot-dev ./waf copter
To open an interactive shell inside the container:
docker run --rm -it -v $PWD:/ardupilot ardupilot-dev

Advanced options

# Parallelize with a specific number of jobs
./waf -j8

# Build with clang instead of gcc
CXX=clang++ CC=clang ./waf configure --board sitl

# Show all available commands and options
./waf -h

Build docs developers (and LLMs) love