Toolchains#

Cross-compilers and build systems for chips the operator’s laptop cannot natively execute. An embedded toolchain is a target-specific gcc or clang, a target-specific C library (newlib, picolibc, or the vendor’s), the binutils that link and inspect the result, and the build system that wires them together. The operator picks one toolchain per target architecture and standardises around it; mixing them inside one project is a path to days lost to subtle linker errors.

Cross-GCC#

The default for nearly every embedded target. One gcc binary per target architecture, named after the target triple.

Toolchain

Target

Source

arm-none-eabi-gcc

ARM Cortex-M (M0/M0+/M3/M4/M7/M33), bare-metal

Arm GNU toolchain (Linaro); install via vendor package manager or download tarball from Arm.

arm-linux-gnueabihf-gcc

ARM Cortex-A with hard-float, Linux userspace

Distro packages on Debian / Ubuntu.

aarch64-none-elf-gcc

ARM 64-bit bare-metal

Arm GNU toolchain.

aarch64-linux-gnu-gcc

ARM 64-bit Linux userspace

Distro packages.

avr-gcc

AVR 8-bit (ATmega, ATtiny)

avr-libc + binutils-avr + gcc-avr from distro.

xtensa-esp-elf-gcc

Xtensa LX6 / LX7 (ESP32, ESP32-S3)

ESP-IDF installer or crosstool-NG.

riscv-none-elf-gcc

RISC-V (RV32I, RV32IMC, RV64GC) bare-metal

SiFive freedom-tools or xPack RISC-V toolchain.

msp430-gcc

TI MSP430

TI’s GCC distribution.

LLVM#

Clang can target every architecture above through a single binary plus a per-target sysroot. The trade-off is per-target setup work (linker scripts, startup code, libc); GCC ships these for the common embedded targets.

  • clang --target=thumbv7em-none-eabi -mcpu=cortex-m4

  • ld.lld as the linker. Avoid mixing GNU ld and LLD in one project.

  • llvm-objdump, llvm-nm, llvm-size as the binutils equivalents.

The operator usually only reaches for LLVM when targeting a non-mainline architecture (custom RISC-V core), running sanitisers in firmware (-fsanitize=undefined), or building the same code for host tests and embedded with one toolchain.

Libc#

Embedded libc choices differ from desktop in size and what they omit.

Libc

Size

Note

newlib

Medium

The default for arm-none-eabi-gcc. Full-featured; newlib-nano is the trimmed variant for tight flash.

picolibc

Small

A modern, MIT-licensed alternative designed for embedded from the start. Default in some Zephyr builds.

musl

Medium

For embedded Linux userspace; smaller than glibc, static-linking-friendly.

Vendor libc

Varies

ESP-IDF carries its own; STM32Cube uses newlib-nano.

Build systems#

Build system

Note

Make

The classic. Most embedded projects (Linux kernel, ESP-IDF legacy) still use it.

CMake

The current default for Zephyr, ESP-IDF, mbed, and the Pico SDK. Pair with Ninja for fast incremental builds.

Meson

Niche in embedded but growing; clean syntax.

PlatformIO

Wraps GCC / Clang and many vendor frameworks under one CLI; runs cross-platform with library and board package management.

Arduino IDE / arduino-cli

The hobby standard. Builds Arduino sketches into native firmware.

References#