Skip to content

[build] Update to GCC15 - #1342

Merged
salkinium merged 8 commits into
modm-io:developfrom
salkinium:feat/gcc15
Oct 1, 2026
Merged

salkinium merged 8 commits into
modm-io:developfrom
salkinium:feat/gcc15

Conversation

@salkinium

@salkinium salkinium commented Mar 7, 2026 •

Copy link
Copy Markdown
Member

GCC15 was released a while ago, let's see what breaks. Depends on modm-ext/docker-modm-build#34 and modm-io/avr-libstdcpp#44.

The old avr-libstdcpp was a hand-patched GCC10 port, which avr-gcc 15 refuses to compile (-Wtemplate-body errors in stl_iterator.h). It is now generated from the actual libstdc++ sources, configured for avr-libc. modm only uses the header set for avr-gcc 14 and 15 and keeps its own runtime, so this is mostly a submodule update.

  • Update avr-libstdcpp to the generated GCC15 headers
  • Remove the throw helpers that are now inline in the headers, add the missing ones
  • Fail early with avr-gcc < 14
  • Include <math.h> in the AVR delay, it's not included transitively anymore
  • All AVR examples and test targets compile with avr-gcc 14 and 15
  • Fix the AVR unit tests and run them on an ATmega2560 board, turns out they were broken on hardware:
    • SAB slave action list is now in RAM, the FLASH_STORAGE one never compiled and the test read RAM as flash
    • Unittest counters are 32-bit, we overflowed to "Passed -30600 tests" lol
    • Skip the fiber guard contention test, AVR can't detect if it runs in an interrupt
    • Split mega-2560-pro_C into C and D, the combined image ran out of RAM for fiber stacks
  • osx-cross/homebrew-arm doesn't have v15 yet, lol! fixed, need to upgrade the macos CI
  • Something is wrong with modm::platform::detail::AdcChannel<modm::platform::detail::DataC4, (modm::platform::Peripheral)1> on Cortex-M fixed

We now have the entire C++ library up to C++26 on AVR, including the date stuff. Anything that needs the compiled libstdc++ (iostreams, locales, <format>) still won't link, obviously.

Flash and RAM of all AVR examples, both compiled with avr-gcc 14, since develop doesn't compile with 15 at all:

Example Flash RAM
arduino_uno/basic/blink 1220 → 1058 (−162) =
avr/display/dogm128/text 8072 → 7918 (−154) =
avr/display/dogm128/benchmark 9422 → 9270 (−152) =
avr/timer 2098 → 2026 (−72) =
8 other examples −22 to −38 =
6 display examples +10 =
28 other examples = =
Total −728 bytes =

The savings are mostly from <chrono> not pulling in a 64-bit multiplication for modm::delay() anymore. The +10 bytes are std::fill in MonochromeGraphicDisplay::clear() generating a slightly different loop, meh.

The avr-libstdcpp work was done with the help of Opus 5.5, but thoroughly reviewed and tested by me.

@chris-durand

Copy link
Copy Markdown
Member

I've fixed the linker error due to duplicate symbols. That was all that was needed to compile my STM32 modm code at work with gcc 15.3.

This CI image has gcc 15.2 which crashes trying to build CMSIS-DSP for Cortex-M:

scons: building terminated because of errors.during RTL pass: ce1
modm/ext/cmsis/dsp/FastMathFunctions/arm_atan2_q31.c: In function 'arm_atan2_q31':
modm/ext/cmsis/dsp/FastMathFunctions/arm_atan2_q31.c:225:1: internal compiler error: Segmentation fault
  225 | }
      | ^
0x1b8ae85 diagnostic_context::diagnostic_impl(rich_location*, diagnostic_metadata const*, diagnostic_option_id, char const*, __va_list_tag (*) [1], diagnostic_t)
	???:0
0x1b9ae9f internal_error(char const*, ...)
	???:0
0x929c10 copy_to_mode_reg(machine_mode, rtx_def*)
	???:0
0xbd3b86 maybe_legitimize_operands(insn_code, unsigned int, unsigned int, expand_operand*)
	???:0
0xbd0f19 maybe_gen_insn(insn_code, unsigned int, expand_operand*)
	???:0
0xbd3000 emit_conditional_move(rtx_def*, rtx_comparison, rtx_def*, rtx_def*, machine_mode, int)
	???:0
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
scons: *** [build/scons-release/modm/ext/cmsis/dsp/FastMathFunctions/arm_atan2_q31.o] Error 1
==========================================================================================

Once we update to 15.3 the issue will go away.

@chris-durand

Copy link
Copy Markdown
Member

Having to update libstdc++ for avr on every gcc release seems a bit unsustainable. A lot of internals change every time. It seems the best way forward would be to somehow build avr-gcc with libstdc++ and require that toolchain. It looks like some people have managed.

@salkinium
salkinium force-pushed the feat/gcc15 branch 4 times, most recently from 0bf353a to 274a244 Compare September 28, 2026 17:23
@salkinium
salkinium marked this pull request as ready for review September 28, 2026 18:03
@salkinium
salkinium force-pushed the feat/gcc15 branch 6 times, most recently from 13e4ec0 to 323d11c Compare September 29, 2026 19:24
The 2026-09-28 Docker images ship avr-gcc 15.3 and Arm GCC 15.3.
Windows downloads Arm GCC 15.3 from the modm-io/avr-gcc release, since
the runners are sometimes blocked by the Arm servers, and avr-gcc 15.2
from Zak Kemble. macOS installs the GCC 15 formulas from Homebrew, which
the hosted Makefile also uses now.
The delay functions use ceil() and fabs(), which was previously only
transitively included via the old avr-libstdcpp headers.
avr-libstdcpp now provides header sets for avr-gcc 8 to 15, generated from
the libstdc++ sources of the GCC releases and configured for avr-libc.
modm only uses the set for avr-gcc 14 and 15 and provides its own runtime,
so only its headers and library sources are copied.

The throw helpers for bad_optional_access, bad_variant_access and
bad_any_cast are defined inline in their headers, so they must not be
defined anymore. Add the missing helpers for out_of_range_fmt and
bad_array_new_length. Fail early with older avr-gcc versions.
Extensionless headers such as modm/ext/gcc/atomic are listed in the
dependency files. Since they keep their old mtime when copied, GNU make
applies its built-in `%: %.cpp` rule on incremental builds and tries to
compile modm/ext/gcc/atomic.cpp into the header path.
The SAB_ACTION() initializer uses a reinterpret_cast of a member function
pointer, which is not a constant expression, so the documented
FLASH_STORAGE action list fails to compile on AVR. The unittest worked
around this by keeping the list in RAM while still reading it through
modm::accessor::asFlash(), which reads from program memory on AVR and
never matched any command.

The slave now takes a plain const Action pointer instead.
int_fast16_t is 16-bit on AVR and overflowed when running more than
32767 tests, printing "Passed -30600 tests".
AVR cannot detect whether it runs inside an interrupt, so a contended
static initialization guard always asserts instead of yielding.
The combined C image did not run on hardware. The processing tests alone
already use over 80% of the 8kB RAM for fiber stacks, so they now run
separately in D.
@salkinium
salkinium merged commit 4fcec7b into modm-io:develop Oct 1, 2026
12 checks passed
@salkinium
salkinium deleted the feat/gcc15 branch October 1, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants