The prebuilt toolchain tarballs are produced by
f0rmiga/gcc-builds and pinned in this repository by
AVAILABLE_GCC_VERSIONS in toolchain/defs.bzl. Each GCC version maps to
one URL and SHA256 per target architecture:
AVAILABLE_GCC_VERSIONS = {
"16.2.0": {
"aarch64": {"url": "...", "sha256": "..."},
"armv7": {"url": "...", "sha256": "..."},
"x86_64": {"url": "...", "sha256": "..."},
},
}A gcc-builds release is tagged DDMMYYYY and does not necessarily rebuild every GCC version. Pin
each version to the newest release that publishes it, which means the entries in
AVAILABLE_GCC_VERSIONS routinely point at different release tags.
gh release list --repo f0rmiga/gcc-builds --limit 30
gh release view <tag> --repo f0rmiga/gcc-builds --json assets --jq '.assets[].name'Assets are named gcc-toolchain-<gcc_version>-<target_arch>.tar.xz. Assets carrying an extra
-host-aarch64 suffix are toolchains that run on aarch64 hosts; this repository keys
AVAILABLE_GCC_VERSIONS by target architecture only and consumes the x86_64-host builds, so the
-host-aarch64 variants are ignored. Filter them out when collecting assets.
The GitHub API exposes each asset's SHA256 in the digest field, so the tarballs do not have to be
downloaded:
gh api repos/f0rmiga/gcc-builds/releases/tags/<tag> \
--jq '.assets[] | select(.name | test("host") | not) | "\(.name) \(.digest)"'Strip the sha256: prefix from each value. To confirm a digest independently:
curl -sL -o /tmp/toolchain.tar.xz \
https://github.com/f0rmiga/gcc-builds/releases/download/<tag>/gcc-toolchain-<version>-<arch>.tar.xz
sha256sum /tmp/toolchain.tar.xzEdit AVAILABLE_GCC_VERSIONS in toolchain/defs.bzl. When a release adds a
new GCC version, add a new entry; bump DEFAULT_GCC_VERSION if that version becomes the default.
Leave versions that the newer releases do not publish pointing at their existing release tag.
Every entry becomes a selectable toolchain and a //toolchain:gcc_version_* config setting, so
adding or removing a version also means:
- adding it to the
gcc_versionsmatrix in .github/workflows/default.yaml; - checking whether the tarball ships
bin/ld.lld. GCC versions built without it cannot use thelinker-lldfeature, and//tests/lldmarks those versions incompatible so the test is skipped rather than failing.
AVAILABLE_GCC_VERSIONS is serialized into the gcc_versions attribute default, so
defs.md embeds every URL and hash. //docs:update_test fails until it is regenerated:
bazel run //docs:updateNew tarballs can change more than their contents, so exercise every architecture and feature:
bazel test //...
# Every selectable GCC version, which is what the CI matrix runs.
for gcc_version in 12.5.0 13.4.0 14.3.0 15.2.0 16.1.0 16.2.0; do
bazel test --//toolchain:gcc_version=${gcc_version} //...
done
# Cross-compilation, which the default test run does not cover.
for platform in aarch64_linux armv7_linux x86_64_linux; do
bazel build --platforms=//platforms:${platform} \
//examples/hello_world_c:hello_world_c \
//examples/hello_world_cpp:hello_world_cpp \
//examples/hello_world_fortran:hello_world_fortran
done
for sanitizer in asan lsan tsan ubsan; do
bazel test --config ${sanitizer} //tests/sanitizers:${sanitizer}_test
done
bazel test --config lld //tests/lld:lld_test
bazel coverage //examples/hello_world_cpp:hello_world_cpp_test //tests/coverage/...Commit with the message format the repository already uses, e.g.
feat: update gcc builds to 10/08/2026.
The tarball layout is an implicit contract between gcc-builds and this repository, and it has
changed before. The 08072026 release began prefixing the x86_64 binaries in bin/ with the
x86_64-linux- target triple; earlier releases shipped them unprefixed.
gcc_toolchain absorbs that difference: _detect_binary_prefix probes for
bin/<triple>-as after extraction and falls back to an empty prefix, so old and new layouts both
work. as is the probe because the unprefixed layout still ships a handful of prefixed aliases
(gcc, g++, c++, gfortran) but never a prefixed as. Passing binary_prefix explicitly to
gcc_declare_toolchain overrides detection.
A layout change usually surfaces as a missing input rather than a compile error:
missing input file '@@gcc_toolchain_x86_64//:bin/gcc'
To diagnose, list what the tarball actually contains and compare it against the paths
toolchain/defs.bzl expects — the bin/{binary_prefix}* tool paths and filegroups, the
lib/gcc/{include_prefix}{gcc_version} include directories, and the include/c++/{gcc_version}
tree:
tar -tJf /tmp/toolchain.tar.xz | grep -E '^\./bin/'
tar -tJf /tmp/toolchain.tar.xz | grep -E '^\./(lib|include)/'Detection only covers the binary prefix. If the include or library directories move, both
_gcc_toolchain_impl and _TOOLCHAIN_BUILD_FILE_CONTENT need updating.