Arduino, Big Builder, and Make

2024-Jan-05

Last night, I got Big Builder building Arduino sketches.

Big Builder is my Continuous Integration / Continuious Development (ci/cd) solution for forgejo/gitea. It’s nothing revolutionary, it’s just a container with a bunch of pre-installed software, and the gitea act_runner with a configuration to not try and use docker. This means my builds are pretty quick, and my network use is very low, since I already have the tools I need to build stuff, and don’t have to download mulitple OS images every time I do a build.

Automating embedded systems builds

Arduino, it turns out, has been including command-line build tools for a long time now. Since I’m using Debian’s Arduino package, I get the older, poorly-documented arduino-builder. But the newer arduino-cli has better documentation, that helped me understand how to use the older command.

Using arduino-builder lets me keep the source code structured in a way that makes sense to amateur developers: they can just load it up in the IDE and not worry about my automation. But it also lets me automate builds on my forgejo server, and use the command-line to build everything, the way I’ve been doing since the 80s.

Here’s what I wound up with, to build a Leonardo image:

mkdir -p build/cache
arduino-builder \
  -build-path $(pwd)/build/ \
  -build-cache $(pwd)/build/cache/ \
  -fqbn arduino:avr:leonardo \
  -hardware /usr/share/arduino/hardware/ \
  -tools /usr/share/arduino/tools/ \
  -compile MockBand.ino

This results in build/MockBand.ino.hex, which can then be given to avrdude to flash my board. Easy!


For the mockband project, I also needed to specify a custom USB VID/PID and a CPP definition. After reading a lot of forums posts and code, I discovered I could easily do this with arduino-builder, with the -prefs= flag. This allows you to override settings in boards.txt, which is apparently what Arduino uses to build a gcc flags list.

Here’s a trimmed-down version of what I implemented:

mkdir -p build/cache
arduino-builder \
  -build-path $(pwd)/build/ \
  -build-cache $(pwd)/build/cache/ \
  -fqbn arduino:avr:leonardo \
  -hardware /usr/share/arduino/hardware/ \
  -tools /usr/share/arduino/tools/ \
  -prefs="build.extra_flags=-DUSB_VID=0x1bad -DUSB_PID=0x0004 -DCDC_DISABLED" \
  -compile MockBand.ino

My final step was to write a Makefile to do all this. Since the build step is just one (long) command, and the -prefs could easily use per-target variables, make was an obvious tool. Adding a target to run avrdude was simple enough, too.

I no longer need the Arduino IDE at all, but the project still works with it!

The result was a Makefile which can compile, flash, and package all three variants of the build. It’s 43 lines long, including blank lines.