Skip to content

About

Subset of the C++ standard library for AVR targets

Topics

Resources

Stars

84 stars

Watchers

16 watching

Forks

Repository files navigation

avr-libstdcpp: libstdc++ for avr-gcc

CI

avr-gcc supports modern C++, but does not ship a C++ standard library. avr-libstdcpp provides the libstdc++ headers of GCC, adapted for avr-libc, for avr-gcc 8 to 15 and C++17 to C++26.

#include <algorithm>
#include <array>
#include <chrono>
#include <optional>
#include <string_view>
#include <variant>

using namespace std::chrono_literals;

constexpr std::array<uint16_t, 4> thresholds{100, 200, 400, 800};
constexpr auto level = std::ranges::lower_bound(thresholds, 300) - thresholds.begin();
static_assert(level == 2);

std::optional<std::chrono::milliseconds> timeout = 1500ms;
std::variant<int16_t, float, std::string_view> value = "hello";

Everything implemented in the headers is available: containers, strings, algorithms, ranges, optional, variant, function, smart pointers, <chrono>, <cmath>, <random>, <atomic>, coroutines and much more. I/O streams, locales and <format> require the compiled library, which is not provided. See the limitations for details.

Quick start

Add the include directory to the include path and compile the src directory with your application:

LIB=avr-libstdcpp
avr-g++ -std=c++23 -Os -mmcu=atmega328p -fno-exceptions -fno-rtti -fno-threadsafe-statics \
        -ffunction-sections -fdata-sections -Wl,--gc-sections \
        -I$LIB/include main.cpp $LIB/src/*.cc $LIB/runtime/*.cpp -o main.elf -lm

This works with avr-gcc 8 to 15: The headers and sources select the header set for your compiler version themselves (see compatibility). With Make, avr-libstdcpp.mk also provides the newest C++ standard supported by your compiler:

AVR_CXX := avr-g++
include avr-libstdcpp/avr-libstdcpp.mk
CXXFLAGS += -std=$(AVR_LIBSTDCPP_STD) -I$(AVR_LIBSTDCPP_INCLUDE)
SOURCES += $(AVR_LIBSTDCPP_SOURCES)

See getting started for the details, CMake, the required compiler flags and the runtime functions you may need to provide.

Documentation

  • Getting started: setup, compiler flags, runtime
  • Compatibility: supported compilers and why there are four header sets
  • Limitations: what works and what does not
  • Guide: using the standard library on tiny bare-metal systems
  • Generating: how the headers are generated from GCC
  • Testing: integration tests and CI

Examples

The examples run on an Arduino Uno and print via the serial port:

Example Shows
blink <chrono> durations, clocks and hh_mm_ss
interrupt_counter std::atomic shared between an interrupt and the main loop
sensor_filter median and moving average filters with <algorithm>, <numeric> and <cmath>
command_shell a serial command line with string_view, from_chars, map and function
state_machine a traffic light with std::variant states and std::visit
lookup_table a sine table computed at compile time with constexpr and std::array
ranges a data logger with C++20 ranges, span, concepts and <random>
chrono a custom high_resolution_clock driven by Timer0
cmath floating-point functions of <cmath>
numeric constexpr algorithms of <numeric>
vector std::vector with dynamic memory
cd examples/blink
make          # build with avr-g++
make sim      # run in simavr
make program  # flash via avrdude

The chrono, cmath, numeric and vector examples use their own Makefiles and C++17 by default.

Repository layout

Path Content
include, src Redirect every file to the header set of your avr-gcc version
gcc10, gcc12, gcc13, gcc15 The generated header sets, each with include and src
avr-libstdcpp.mk Paths and the newest C++ standard for Make
runtime Optional implementations of new, delete, the C++ ABI and atomics
tools The generator and the library sources
tests Integration tests running in simavr
examples Examples for the Arduino Uno
docs Documentation

Do not edit the header sets directly, they are regenerated by tools/generate.py.

History

avr-libstdcpp began in 2018 with an import of the libstdc++ headers of GCC 8, from which unsupported parts were removed by hand. A second import from GCC 10 in 2020 added many C++20 features. Since 2026, the headers are generated automatically from four GCC versions, which provides the complete library up to C++26 and makes supporting new GCC versions much easier.

Licensing

The generated headers and library sources in gcc*/ and the files in tools/src are part of GCC and licensed under the GNU General Public License Version 3 or higher with the GCC Runtime Library Exception, except for functexcept.cc and math.cc.

The examples, tests, runtime, scripts, functexcept.cc and math.cc are subject to the terms of the Mozilla Public License Version 2.0.

About

Subset of the C++ standard library for AVR targets

Topics

Resources

Stars

84 stars

Watchers

16 watching

Forks

Used by

Contributors

Languages