Skip to content

Instantly share code, notes, and snippets.

@hasselmm
Last active June 12, 2025 23:43
Show Gist options
  • Save hasselmm/42fb278810ba33f48fdfb0e5cf3e1bcc to your computer and use it in GitHub Desktop.
Save hasselmm/42fb278810ba33f48fdfb0e5cf3e1bcc to your computer and use it in GitHub Desktop.
Try Build - Tries to build selected files of an Arduino Sketch

Try Arduino Build

Building Arduino sketches takes an imense amount of time. This is very annoying when fixing trivial issues like compile errors.

This tool tries to reduce your round-trip times by building only selected files of an Arduino Sketch.

Requirements

  • arduino-cli - Arduino's build tool
  • yq - a command line YAML parser

Demo

$ arduino-trybuild.sh Config.cpp WebUI.cpp
Reading build properties...
Using LIBRARIES from sketch.yaml: ArduinoJson ESP8266WiFi ESP8266HTTPClient ESP8266WebServer
Updating sketch sources...
'Property.h' -> '/home/mathias/.cache/arduino/sketches/213C467C5585CDE011EC1831BDC0F90C/sketch/Property.h'
Building 'WebUI.cpp'...
Building 'Config.cpp'...
$

Configuration

To make this all work that smoothly consider having an Arduino project file (called sketch.yaml) in your sketch:

default_fqbn: esp8266:esp8266:nodemcuv2:mmu=3232,baud=921600
libraries:
  - ArduinoJson
  - ESP8266WiFi
  - ESP8266HTTPClient
  - ESP8266WebServer

At least the default_fqbn can be created using arduino-cli board attach.

#!/bin/bash
# ---------------------------------------------------------------------
# Try Arduino Build - build selected files of a sketch
# ---------------------------------------------------------------------
# Copyright 2025 Mathias Hasselmann
# SPDX-License-Identifier: CC0-1.0
# ---------------------------------------------------------------------
# This function reports fatal errors and aborts.
# ---------------------------------------------------------------------
die() {
echo "$@" >&2
exit 1
}
# Check required dependencies
# ---------------------------------------------------------------------
which -s arduino-cli || die 'Could not find arduino-cli: https://github.com/arduino/arduino-cli'
which -s yq || die 'Could not find yq: https://jqlang.org/'
# Read and cache build settings from arduino-cli
# ---------------------------------------------------------------------
build_setting() {
key="$1"
echo "${BUILD_PROPERTIES}" | sed -ne "s/^${key//./\\.}=//p"
}
echo "Reading build properties..."
BUILD_PROPERTIES=$(arduino-cli compile --show-properties)
echo "Building for '$(build_setting build.fqbn)'..."
BUILD_PATH=$(build_setting build.path)/sketch/
COMPILE_CPP=$(build_setting recipe.cpp.o.pattern)
CORE_INCLUDES=$(build_setting build.core.path)
VARIANT_INCLUDES=$(build_setting build.variant.path)
PLATFORM_LIBRARY_PATH=$(build_setting build.core.platform.path)/libraries
ARDUINO_HOME="${ARDUINO_HOME:-$(arduino-cli config get directories.user)}"
USER_LIBRARY_PATH="${USER_LIBRARY_PATH:-${ARDUINO_HOME}/libraries}"
SKETCH_CONFIG="${SKETCH_CONFIG:-sketch.yaml}"
# Resolve require libraries
# ---------------------------------------------------------------------
if [ -n "${LIBRARIES}" ]
then
echo "Using LIBRARIES from environment variable: ${LIBRARIES}"
elif [ -r "${SKETCH_CONFIG}" ]
then
LIBRARIES=$(yq -r '.["libraries"] | join(" ")' < "${SKETCH_CONFIG}")
echo "Using LIBRARIES from "${SKETCH_CONFIG}": ${LIBRARIES}"
else
echo "Could not find any library list in environment in environment or ${SKETCH_CONFIG}."
fi
# Resolve include directives
# ---------------------------------------------------------------------
library_includes() {
separator=""
for libname in "$@"
do
found=no
for path in "${USER_LIBRARY_PATH}/${libname}/src" "${PLATFORM_LIBRARY_PATH}/${libname}/src"
do
if [ -d "${path}" ]
then
echo -n "${separator}-I '${path}'"
separator=" "
found=yes
break
fi
done
if [ "${found}" == "no" ]
then
echo "Library not found: ${libname}" >&2
exit 1
fi
done
}
INCLUDES="-I '${CORE_INCLUDES}' -I '${VARIANT_INCLUDES}' $(library_includes ${LIBRARIES})" || exit 1
# Compile the selected sources
# ---------------------------------------------------------------------
echo "Updating sketch sources..."
cp -uv *.cpp *.h "${BUILD_PATH}"
test -d src && cp -ruv src "${BUILD_PATH}"
for file in "$@"
do
echo "Building '${file}'..."
compile_cpp="${COMPILE_CPP//\{includes\}/${INCLUDES}}"
compile_cpp="${compile_cpp//\{source_file\}/${BUILD_PATH}${file}}"
compile_cpp="${compile_cpp//\{object_file\}/${BUILD_PATH}${file/%.cpp/.o}}"
compile_cpp="${compile_cpp//warnings\/none/warnings\/extra}"
eval "${compile_cpp}"
done
# vim: sta sw=4 et
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment