Skip to main content
πŸŽ“ Claude Code Masterclass Learn AI-assisted development on Udemy β€” plus the companion book on Leanpub & Amazon. Start Learning
RISC-V community members and developers at RISC-V Summit Europe 2026
RISC-V

Build a RISC-V Toolchain: GCC and LLVM

How to build or install a RISC-V cross-compiler with GCC and LLVM/Clang β€” newlib vs glibc, multilib, and compiling your first RV64 binary from scratch.

LB
Luca Berton
Β· 2 min read

To build software for RISC-V you need a cross-compiler β€” a toolchain that runs on your x86 or ARM machine but emits RISC-V code. The good news in 2026 is that this is mostly a solved problem. This guide covers the fast path (install a prebuilt toolchain) and the full path (build one from source for a custom ISA configuration).

Developers and community members at RISC-V Summit Europe 2026

Fast Path: Install a Prebuilt Toolchain

For most work, your distro’s package is all you need.

Debian / Ubuntu (Linux glibc target):

sudo apt update
sudo apt install -y gcc-riscv64-linux-gnu g++-riscv64-linux-gnu
riscv64-linux-gnu-gcc --version

Bare-metal / embedded (newlib target):

sudo apt install -y gcc-riscv64-unknown-elf   # package name varies by distro

Fedora:

sudo dnf install -y gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu

LLVM/Clang (one Clang targets every architecture):

sudo apt install -y clang lld
clang --target=riscv64-linux-gnu --version

Compile and run a quick test (with QEMU user mode):

echo 'int main(){return 42;}' > t.c
riscv64-linux-gnu-gcc -static t.c -o t
qemu-riscv64 ./t; echo $?   # 42

Understanding the Toolchain Triple

The prefix encodes a target triple: riscv64-linux-gnu = 64-bit RISC-V, Linux OS, GNU (glibc) C library. The bare-metal variant riscv64-unknown-elf means β€œno OS, ELF output, newlib.” Picking the right one is the single most common beginner mistake:

  • Linux applications β†’ riscv64-linux-gnu (glibc)
  • Microcontrollers / firmware / bootloaders β†’ riscv64-unknown-elf (newlib)

Full Path: Build From Source

Build from source when you need a specific -march (e.g. enabling vector or crypto), a multilib toolchain, or the latest compiler. The official riscv-gnu-toolchain repo automates everything.

# Dependencies (Debian/Ubuntu)
sudo apt install -y autoconf automake autotools-dev curl python3 \
  libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex \
  texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git

git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain

Configure for Your Target

Pick the ABI and ISA you want. For a Linux RV64GC glibc toolchain:

./configure --prefix=/opt/riscv --with-arch=rv64gc --with-abi=lp64d
make linux -j$(nproc)        # builds the glibc/Linux toolchain

For a bare-metal newlib toolchain (e.g. for an embedded RV32IMC core):

./configure --prefix=/opt/riscv32 --with-arch=rv32imc --with-abi=ilp32
make -j$(nproc)              # default target builds newlib

Then add it to your PATH:

export PATH=/opt/riscv/bin:$PATH
riscv64-unknown-linux-gnu-gcc --version

Building from source takes a while (it compiles binutils, GCC, and the C library). Use -j$(nproc) and be patient.

Key Configure Flags

  • --with-arch β€” the ISA string, e.g. rv64gcv to enable vectors.
  • --with-abi β€” lp64d (64-bit, hardware double) or ilp32 (32-bit). The ABI must be compatible with the arch.
  • --enable-multilib β€” build libraries for multiple arch/ABI combos in one toolchain.
  • make linux vs make β€” glibc/Linux vs newlib/bare-metal.

Matching -march to Your Target

The -march you compile with must be a subset of what your target hardware (or QEMU CPU) supports, or the binary will hit an illegal instruction. Examples:

# General Linux SBC
riscv64-linux-gnu-gcc -march=rv64gc -mabi=lp64d app.c -o app

# Vector-capable chip (SpacemiT K1, QEMU -cpu rv64,v=true)
riscv64-linux-gnu-gcc -march=rv64gcv -mabi=lp64d app.c -o app

# Tiny embedded MCU
riscv64-unknown-elf-gcc -march=rv32imc -mabi=ilp32 firmware.c -o fw.elf

Check what a target supports via /proc/cpuinfo on the device, or -cpu help in QEMU.

LLVM for RISC-V

Clang shares the GNU sysroot, so you can mix and match. To build vector code with Clang:

clang --target=riscv64-linux-gnu -march=rv64gcv -O3 \
  --sysroot=/usr/riscv64-linux-gnu -fuse-ld=lld app.c -o app

LLVM’s RISC-V backend is mature in 2026, including auto-vectorization for RVV β€” useful if you want a single compiler across all your target architectures.

Verifying Your Build

riscv64-linux-gnu-gcc -march=rv64gc hello.c -o hello
file hello                    # ELF 64-bit LSB ... UCB RISC-V
riscv64-linux-gnu-readelf -A hello | grep arch   # confirms ISA attributes
qemu-riscv64 -L /usr/riscv64-linux-gnu ./hello    # run dynamic binary

The readelf -A step is worth knowing: it prints the recorded ISA attributes so you can confirm the binary really targets what you intended.

The Bottom Line

For everyday RISC-V development, install your distro’s gcc-riscv64-linux-gnu (or Clang) and you are done. Build from source only when you need a custom -march, a bare-metal newlib toolchain, or cutting-edge compiler features β€” and when you do, riscv-gnu-toolchain makes it a one-command affair. Either way, pair it with QEMU to test before you touch hardware.


Part of my RISC-V series. Next up: RISC-V Vector Programming and RISC-V Profiles and RVA23.

Frequently Asked Questions

Do I need to build a RISC-V toolchain from source?

Usually not. Most Linux distributions ship a prebuilt RISC-V cross-compiler (for example gcc-riscv64-linux-gnu on Debian/Ubuntu). You only need to build from source when you want a specific ISA string, a bare-metal newlib toolchain, or bleeding-edge compiler features.

What is the difference between the newlib and glibc RISC-V toolchains?

The newlib toolchain (riscv64-unknown-elf) targets bare-metal and embedded systems with no operating system. The glibc/Linux toolchain (riscv64-unknown-linux-gnu) targets full Linux user space and links against glibc. Choose newlib for microcontrollers and firmware, glibc for Linux applications.

Can I use LLVM/Clang for RISC-V instead of GCC?

Yes. Modern Clang has production-quality RISC-V support, including the vector extension. You select the target with --target=riscv64-linux-gnu and -march, and it can share a GCC sysroot for headers and libraries.

Free 30-min AI & Cloud consultation

Book Now