riscv-gnu-toolchain: Building a RISC-V Cross-Compiler from Source
GNU toolchain for RISC-V, including GCC
At a glance
- What is it?
- The riscv-collab/riscv-gnu-toolchain repository builds GCC-based cross-compilers for bare-metal and Linux RISC-V targets. It is a source build, not a binary download, and the README is explicit about the disk cost.
- Who is it for?
- Adopt it if you need a GCC cross-compiler for a specific RISC-V arch, ABI or C library combination that no prebuilt package ships, and you have roughly 8 GiB of scratch space plus a machine you can leave compiling. Do not adopt it if you only need to compile a quick hello-world for a stock RV64GC Linux target; a distribution package or the AUR riscv-gnu-toolchain-bin build will get you there in minutes instead of hours.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 34 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What riscv-gnu-toolchain actually produces
This is the RISC-V C and C++ cross-compiler, assembled from binutils, GCC, GDB and a C library into one install prefix. It is not a single binary you download. The repository is a build harness: it fetches upstream sources, patches them, and installs a matching set of tools under one --prefix.
The output you get depends on which libc you ask for. Bare-metal targets (Newlib or Picolibc) produce tools prefixed riscv64-unknown-elf-. Linux targets produce riscv64-unknown-linux-gnu-, riscv64-unknown-linux-musl- or riscv64-unknown-linux-uclibc- depending on the C library. The prefix is not cosmetic: it is how you keep a bare-metal compiler and a Linux compiler installed side by side without them colliding.
The audience is embedded developers bringing up silicon, kernel and bootloader people, and anyone whose target arch or ABI is not covered by the prebuilt packages their distribution ships. If you are writing ordinary userspace code for a board that already boots Linux, you are probably not the intended user.
How the build fetches and patches upstream sources
The repository uses git submodules, and the top-level tree shows why: binutils, gcc, gdb, glibc, newlib, picolibc, musl, uclibc-ng, linux-headers, qemu, spike and pk all sit as directories alongside configure and Makefile.in. The README states that submodules fetch automatically on demand, so --recursive and git submodule update --init --recursive are not needed.
The configure script is generated from configure.ac and is not the upstream GCC configure. It is a wrapper that records your choices (prefix, arch, abi, libc, languages, multilib, endianness) and then drives the per-component builds in the right order, because binutils has to exist before GCC can be configured against it, and the C library has to exist before the compiler can be tested against it.
Upstream tarballs are cached in $(DISTDIR), which defaults to /var/cache/distfiles. If a cached copy is present it is reused; otherwise the build downloads roughly 200 MiB. That cache is the difference between a rebuild that starts compiling immediately and one that spends its first minutes on the network.
Installing riscv-gnu-toolchain on Ubuntu
Start with the dependency list. The README gives a single apt-get line for Ubuntu that covers autoconf, automake, the MPC/MPFR/GMP development libraries, gawk, bison, flex, texinfo, gperf, zlib, expat, meson, ninja, cmake, expect, device-tree-compiler, libslirp-dev and libzstd-dev. Skipping any of them tends to surface as a configure error rather than a clear missing-package message.
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip python3-tomli libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev meson ninja-build git cmake libglib2.0-dev expect device-tree-compiler libslirp-dev libzstd-dev libncurses-devClone the repository. The README warns that this takes around 6.65 GB of disk and download size, which is a warning about the checkout plus submodule content, not the finished toolchain.
git clone https://github.com/riscv/riscv-gnu-toolchainPick a writable install prefix and add its bin directory to PATH. Then configure. The example below builds a 32-bit RV32GC toolchain with the ilp32d ABI; drop the two --with- flags to get the default RV64GC.
./configure --prefix=/opt/riscv --with-arch=rv32gc --with-abi=ilp32dNow choose the C library. The README's table maps make targets to libc: plain make for Newlib, make picolibc, make linux for glibc, make musl, make uclibc. A plain make builds Newlib, which is the default target.
make linuxAfter a successful build, riscv64-unknown-linux-gnu-gcc and its relatives are on your PATH. The README notes the whole process needs about 8 GiB of disk space to complete, on top of the clone.
Multilib, arch and ABI choices that constrain you later
The build defaults to targeting RV64GC even when the build machine is 32-bit, so a 32-bit host does not give you a 32-bit target by accident. You have to ask for it with --with-arch and --with-abi. Supported architectures are rv32i or rv64i plus standard extensions: a for atomics, m for multiplication and division, f for float, d for double, or g for the MAFD combination. Supported ABIs are ilp32, ilp32d, ilp32f, lp64, lp64f and lp64d, with the README flagging ilp32f as niche use only.
--enable-multilib builds runtime libraries for both 32-bit and 64-bit, and the resulting compiler can target both, supporting the common -march and -mabi options. You can inspect what it actually produced with --print-multi-lib. This is the option to reach for if one toolchain has to serve several boards.
Here is the sharp edge. Multilib is only available for Newlib and Linux/glibc. The musl, uClibc and Picolibc toolchains build a single variant, and configuring them with --enable-multilib is rejected outright. Worse for anyone skimming the Makefile, running make musl in a tree that was configured for multilib still yields a single variant. If your plan depends on one musl compiler covering both rv32 and rv64, that plan does not survive contact with the build system.
Two smaller knobs worth knowing before you configure: --enable-default-pie controls the default PIE enablement for GCC on Linux toolchains and is disabled by default, and --with-languages= limits which languages are built, for example c,c++,fortran. The README notes --with-languages only takes effect for the GNU toolchain. --enable-strip controls stripping of host binaries and is also off by default.
macOS builds need a case-sensitive volume and a pre-flight check
The macOS path is genuinely more fragile, and the README says so rather than pretending otherwise: builds are highly specific to OS versions and the versions of the developer tools installed. The recommended move is to run make check-binutils first, which surfaces frequent build errors without committing to a full build. If it errors, the README points at macos-build.md for common errors and their solutions.
Dependencies come from Homebrew, and the README notes that on macOS you should use gmake rather than make so the newly installed version is the one that runs. The glibc build additionally requires a case-sensitive file system, created and mounted as a disk image, with a mount point that contains no spaces. Newlib and GCC itself do not need that.
brew install python3 gawk gnu-sed make gmp mpfr libmpc isl zlib expat texinfo flock libslirp ncurses meson ninja cmake bison m4 wgetThe README's macOS ARM example sources macos.zsh to set PATH so the build scripts find the Homebrew tools, then configures with an explicit arch including the zifencei extension. It also raises the open file limit, which is not optional in practice.
ulimit -n 65536
./configure --prefix=/Volumes/case-sensitive/opt/riscv --with-arch=rv64gc_zifencei --with-abi=lp64d --enable-linux --disable-gdbWhere this toolchain is the wrong choice
The obvious failure mode is treating a source build as a download. There is no prebuilt binary in this repository. If what you want is a compiler in the next ten minutes on Windows, this is not the project for you; the README documents Linux dependency lines, a Homebrew line for macOS, and an AUR package for Arch, and says nothing about a native Windows build path.
The second failure mode is a reused prefix. The README is direct: builds work best installing into an empty directory, and building a hard-float toolchain and then a soft-float toolchain into the same --prefix can leave the build scripts confused and exiting with a linker error. Treat --prefix as single-use, or at least as single-configuration.
The third is disk. Two numbers appear in the README and they are not the same number: the clone is around 6.65 GB, and the process needs about 8 GiB to complete. Budget for the larger figure on the same volume as the build tree, not just the install prefix.
Finally, multilib expectations. If your workflow assumes one compiler that switches between musl and glibc, or between 32-bit and 64-bit musl, the documented constraints rule that out. You will be maintaining two install prefixes.
How it compares with LLVM and with distro packages
The repository ships an llvm directory alongside gcc, which is the honest signal that GCC is not the only RISC-V compiler in play. The difference in approach is architectural rather than a matter of taste. GCC here is built as a cross-compiler with a C library baked in at configure time: you pick Newlib, Picolibc, glibc, musl or uClibc, and the resulting toolchain is tied to that choice. LLVM's RISC-V backend is typically consumed as a host-native clang that takes --target=riscv64-unknown-elf at invocation, so one installed clang can emit for several targets and you supply a sysroot separately. If you need to switch targets per build without reinstalling a compiler, that model fits better. If you need the GNU assembler, linker, GDB and libstdc++ to match a specific libc exactly, this repository is the path.
The other comparison is against distribution packages and the AUR. The README links riscv-gnu-toolchain-bin on the AUR, which is a binary package rather than a source build. The trade-off is control versus time: a distro or AUR package gives you whatever arch, ABI and libc its maintainer chose, and a source build gives you the exact configuration at the cost of the clone, the dependencies and the compile. Choose the source build when you need a configuration nobody packages, such as rv32gc with ilp32d and uClibc.
Licence, maintenance and what upgrading costs
The repository's licence metadata is reported as NOASSERTION, and the top-level tree contains a LICENSE file. That is worth reading directly rather than assuming, because a toolchain is an aggregation: GCC, binutils, GDB, glibc, newlib, musl and the rest each carry their own terms, and they are not identical. The GPL components have source-distribution obligations that follow the binaries you ship, and glibc's LGPL interacts with static versus dynamic linking differently from the rest. This is a description of the structure, not legal advice; if you redistribute a built toolchain, read the LICENSE file and the per-component licences.
On maintenance, the release list shows nightly builds, with 2026.08.27, 2026.08.25 and 2026.08.24 tagged as Nightly. The last push was on 2026-08-27. Nightly tags mean the tree moves continuously, which is convenient for tracking upstream and inconvenient for reproducibility: if you need a fixed compiler for a product, pin a commit rather than tracking master.
Upgrade cost is dominated by rebuild time, not by migration effort. A new checkout means re-running configure with the same flags, re-downloading or reusing the $(DISTDIR) cache, and recompiling binutils, GCC and the C library. Keep your configure invocation in a script next to the build tree, because reconstructing which libc, arch and ABI combination produced an installed prefix from the binaries alone is unpleasant. The $(DISTDIR) cache is the one piece of state worth preserving across upgrades.
Editorial conclusion
Adopt it if you need a GCC cross-compiler for a specific RISC-V arch, ABI or C library combination that no prebuilt package ships, and you have roughly 8 GiB of scratch space plus a machine you can leave compiling. Do not adopt it if you only need to compile a quick hello-world for a stock RV64GC Linux target; a distribution package or the AUR riscv-gnu-toolchain-bin build will get you there in minutes instead of hours. Before starting a full build, confirm three things: that your --prefix directory is writable and empty, that you have chosen the right libc target (make linux versus plain make), and on macOS that make check-binutils passes, since the README points to macos-build.md precisely because those failures are common.
Frequently asked questions
How do I install the RISC-V GNU toolchain?
Clone the repository (around 6.65 GB of disk and download), install the prerequisites for your platform, then run ./configure --prefix=/opt/riscv followed by a make target such as make linux for glibc or a plain make for Newlib. Add the prefix's bin directory to PATH afterwards. The README warns that submodules fetch automatically, so --recursive is not needed.
What is the RISC-V GNU toolchain?
It is the RISC-V C and C++ cross-compiler, which the README describes as able to build either a bare-metal ELF toolchain using Newlib or Picolibc, or a Linux-ELF toolchain using glibc, musl or uClibc. The repository assembles binutils, GCC, GDB and a C library under a single install prefix.
how to install riscv gnu toolchain
The steps are: install the platform dependencies, clone the repository, run ./configure with your prefix and any arch or ABI flags, then run the make target for the C library you want (make, make picolibc, make linux, make musl or make uclibc). The README states the full process needs about 8 GiB of disk space.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/riscv-collab-riscv-gnu-toolchain)