diff --git a/MODULE.bazel b/MODULE.bazel
index 098a09e..45c8781 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -33,6 +33,17 @@ gcc_toolchains = use_extension("//toolchain:module_extensions.bzl", "gcc_toolcha
]
]
+# An aarch64-HOSTED toolchain, for //tests/host_arch. Deliberately not registered: its
+# binaries are ARM, so it cannot execute on an x86_64 CI machine -- the test only inspects
+# the fetched archive.
+gcc_toolchains.toolchain(
+ name = "gcc_toolchain_aarch64_host",
+ gcc_version = "14.3.0",
+ host_arch = "aarch64",
+ target_arch = "aarch64",
+)
+use_repo(gcc_toolchains, "gcc_toolchain_aarch64_host")
+
# Dev Dependencies (for examples/)
# ===============================
bazel_dep(name = "rules_foreign_cc", version = "0.15.1", dev_dependency = True)
diff --git a/README.md b/README.md
index 2963432..93fd2f1 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,8 @@ performance and portability. You can find the comprehensive documentation under
## Features
-- **Multi-architecture**: Support for x86_64, aarch64, and armv7 Linux targets.
+- **Multi-architecture**: Support for x86_64, aarch64, and armv7 Linux targets,
+ hosted on x86_64 or aarch64.
- **Hermetic**: Fully self-contained with no system dependencies.
- **Optimized**: Reduced toolchain sizes and improved build performance.
- **Fortran Support**: Complete Fortran compilation, including OpenMP support.
@@ -42,7 +43,7 @@ The toolchain has been optimized to reduce size and improve build performance th
* **First-party Code**: Your repository contains C/C++/Fortran code.
* **Sanitizer Testing**: Need to run sanitizers (asan, lsan, tsan, ubsan) on your code.
-* **Cross-compilation**: Build for Linux armv7 or aarch64 from x86_64.
+* **Cross-compilation**: Build for Linux armv7, aarch64 or x86_64 from x86_64 or aarch64.
* **Portability**: Create binaries compatible with any Linux distribution.
* **Reproducibility**: Ensure consistent builds across development and CI environments.
* **Remote Execution**: Use with Bazel RBE for distributed builds.
diff --git a/WORKSPACE b/WORKSPACE
index d0f983c..2deed06 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -41,7 +41,7 @@ load("@bazel_lib//lib:repositories.bzl", "bazel_lib_dependencies")
bazel_lib_dependencies()
-load("//toolchain:defs.bzl", "ARCHS", "gcc_register_toolchain")
+load("//toolchain:defs.bzl", "ARCHS", "gcc_declare_toolchain", "gcc_register_toolchain")
gcc_register_toolchain(
name = "gcc_toolchain_aarch64",
@@ -58,6 +58,16 @@ gcc_register_toolchain(
target_arch = ARCHS.x86_64,
)
+# An aarch64-HOSTED toolchain, for //tests/host_arch. DECLARED, not registered: its
+# binaries are ARM, so it cannot execute on an x86_64 CI machine -- the test only inspects
+# the fetched archive.
+gcc_declare_toolchain(
+ name = "gcc_toolchain_aarch64_host",
+ gcc_version = "14.3.0",
+ host_arch = ARCHS.aarch64,
+ target_arch = ARCHS.aarch64,
+)
+
load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
rules_foreign_cc_dependencies()
diff --git a/docs/README.md b/docs/README.md
index c674d46..d617907 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -87,6 +87,39 @@ copts = select({
Note that these settings only match when the flag is set explicitly, so a `select()` over them
needs a `//conditions:default` branch to cover the unset case.
+## Choosing the host architecture
+
+`target_arch` names the architecture a toolchain produces code FOR. `host_arch` names the one its
+binaries RUN on, and defaults to whatever architecture Bazel itself is running on, so building
+natively on either x86_64 or aarch64 needs no configuration at all:
+
+```bazel
+# On an x86_64 machine this is an x86_64-hosted cross toolchain; on an aarch64 machine it is a
+# native one. Either way it targets aarch64.
+gcc_toolchains.toolchain(
+ name = "gcc_toolchain_aarch64",
+ target_arch = "aarch64",
+)
+```
+
+It drives `exec_compatible_with` on the generated `toolchain()`, so toolchain resolution picks the
+toolchain whose binaries the execution platform can actually run.
+
+Set it explicitly only to fetch a toolchain for a host you are not on — for example to declare an
+aarch64-hosted toolchain from x86_64:
+
+```bazel
+gcc_toolchains.toolchain(
+ name = "gcc_toolchain_aarch64_host",
+ host_arch = "aarch64",
+ target_arch = "aarch64",
+)
+```
+
+gcc-builds publishes aarch64-hosted archives from the `08072026` release on, which covers GCC
+14.3.0 and newer. Asking for a version with no build for that host fails at fetch time, naming the
+hosts it does have. `armv7` is a target only.
+
## Language Support
### Pure C
diff --git a/docs/defs.md b/docs/defs.md
index 5cbb763..9042e1c 100644
--- a/docs/defs.md
+++ b/docs/defs.md
@@ -10,7 +10,7 @@ This module provides the definitions for registering a GCC toolchain for C and C
gcc_toolchain(name, binary_prefix, enable_fortran, extra_asmflags, extra_cflags, extra_cxxflags,
extra_fflags, extra_ldflags, fincludes, gcc_toolchain_workspace_name, gcc_version,
- gcc_versions, includes, repo_mapping, supports_param_files, target_arch)
+ gcc_versions, host_arch, includes, repo_mapping, supports_param_files, target_arch)
@@ -31,7 +31,8 @@ gcc_toolchain(name, fincludes | Extra includes for compiling Fortran, if enabled. %workspace% is rendered to the toolchain root path. | List of strings | optional | [] |
| gcc_toolchain_workspace_name | The name given to the gcc-toolchain repository, if the default was not used. | String | optional | "gcc_toolchain" |
| gcc_version | The version of GCC. | String | optional | "16.2.0" |
-| gcc_versions | A JSON dictionary of GCC versions to their download URLs and SHA256 hashes. The structure is {<gcc_version>: {<target_arch>: {url: <url>, sha256: <sha256>}}}. | String | optional | "{"12.5.0":{"aarch64":{"sha256":"7b0e25133a98d44b648a925ba11f64a3adc470e87668af80ce2c3af389ebe9be","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-aarch64.tar.xz"},"armv7":{"sha256":"a0ef76c8cc517b3d76dd2f09b1a371975b2ff1082e2f9372ed79af01b9292934","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-armv7.tar.xz"},"x86_64":{"sha256":"51076e175839b434bb2dc0006c0096916df585e8c44666d35b0e3ce821d535db","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-x86_64.tar.xz"}},"13.4.0":{"aarch64":{"sha256":"770cf6bf62bdf78763de526d3a9f5cae4c19f1a3aca0ef8f18b05f1a46d1ffaf","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-aarch64.tar.xz"},"armv7":{"sha256":"1b2739b5003c5a3f0ab7c4cc7fb95cc99c0e933982512de7255c2bd9ced757ad","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-armv7.tar.xz"},"x86_64":{"sha256":"d96071c1b98499afd7b7b56ebd69ad414020edf66e982004acffe7df8aaf7e02","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-x86_64.tar.xz"}},"14.3.0":{"aarch64":{"sha256":"b5a73bc840938c8dbb49e2f15b8b8d63e5c33beae0be2aa9a7c52b593522cdcd","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-aarch64.tar.xz"},"armv7":{"sha256":"376684c062a23e84b619a717fa4c7bba336211c8b48169f76eb5aa6ed4da6bb8","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-armv7.tar.xz"},"x86_64":{"sha256":"d155a38e4acff9588df466f0edc98c1a2c54d09bc0162805ba38908cfd7a1d28","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-x86_64.tar.xz"}},"15.2.0":{"aarch64":{"sha256":"f38696590786e7c99d3bb5b8ce9ed66be6224d505fa45dcae0b2a6ec07eb0570","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-aarch64.tar.xz"},"armv7":{"sha256":"8ecb5b35aa25efe78772701c70ed27eda727264303d03cffc372a6f24f18be90","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-armv7.tar.xz"},"x86_64":{"sha256":"f31edf791877935258dcc864afbfb7c9f9238be9f7d9da0ee57f5bc121074457","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-x86_64.tar.xz"}},"16.1.0":{"aarch64":{"sha256":"4331e513156a699c1015fb94021497306f0a896520efbad8b3e16418eb683468","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-aarch64.tar.xz"},"armv7":{"sha256":"8d42c1fd130ccb170fe8d5d17148ae2d3f97134ac0009fdcac87550fec6a6289","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-armv7.tar.xz"},"x86_64":{"sha256":"cfd8ca5bc365c1c838825ed6e44c7b2c309aada25791f76ef73b1aec819e362e","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-x86_64.tar.xz"}},"16.2.0":{"aarch64":{"sha256":"6407b35116f21c59e98ab5ad68ddd8ff5f3e0469723a5d465ec08ed615b11a55","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-aarch64.tar.xz"},"armv7":{"sha256":"515da8a22fa560002d3d149ad701acb725502c70f7bf8d4905f90b0830d38238","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-armv7.tar.xz"},"x86_64":{"sha256":"54af34c821e59b03ded8f82d3a1104426ec4baaf3b226233e1fd76ad5dcb78cf","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-x86_64.tar.xz"}}}" |
+| gcc_versions | A JSON dictionary of GCC versions to their download URLs and SHA256 hashes. The structure is {<gcc_version>: {<target_arch>: {<host_arch>: {url: <url>, sha256: <sha256>}}}}. A {url, sha256} directly under <target_arch> is also accepted and means an x86_64-hosted build. | String | optional | "{"12.5.0":{"aarch64":{"x86_64":{"sha256":"7b0e25133a98d44b648a925ba11f64a3adc470e87668af80ce2c3af389ebe9be","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-aarch64.tar.xz"}},"armv7":{"x86_64":{"sha256":"a0ef76c8cc517b3d76dd2f09b1a371975b2ff1082e2f9372ed79af01b9292934","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-armv7.tar.xz"}},"x86_64":{"x86_64":{"sha256":"51076e175839b434bb2dc0006c0096916df585e8c44666d35b0e3ce821d535db","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-x86_64.tar.xz"}}},"13.4.0":{"aarch64":{"x86_64":{"sha256":"770cf6bf62bdf78763de526d3a9f5cae4c19f1a3aca0ef8f18b05f1a46d1ffaf","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-aarch64.tar.xz"}},"armv7":{"x86_64":{"sha256":"1b2739b5003c5a3f0ab7c4cc7fb95cc99c0e933982512de7255c2bd9ced757ad","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-armv7.tar.xz"}},"x86_64":{"x86_64":{"sha256":"d96071c1b98499afd7b7b56ebd69ad414020edf66e982004acffe7df8aaf7e02","url":"https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-x86_64.tar.xz"}}},"14.3.0":{"aarch64":{"aarch64":{"sha256":"def0f33e644f8586f6ca39754951eebe2189b92823bdaf6d4c4ba42fdad6c598","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-aarch64-host-aarch64.tar.xz"},"x86_64":{"sha256":"b5a73bc840938c8dbb49e2f15b8b8d63e5c33beae0be2aa9a7c52b593522cdcd","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-aarch64.tar.xz"}},"armv7":{"aarch64":{"sha256":"ff3e11e2b222fb42146f1254c6a089234e8cd8e384128de56afc781af13d72d9","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-armv7-host-aarch64.tar.xz"},"x86_64":{"sha256":"376684c062a23e84b619a717fa4c7bba336211c8b48169f76eb5aa6ed4da6bb8","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-armv7.tar.xz"}},"x86_64":{"aarch64":{"sha256":"716ed801e7f2cb35cf25614ffe8e8293934587198e919bcb8c55016c862628f1","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-x86_64-host-aarch64.tar.xz"},"x86_64":{"sha256":"d155a38e4acff9588df466f0edc98c1a2c54d09bc0162805ba38908cfd7a1d28","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-x86_64.tar.xz"}}},"15.2.0":{"aarch64":{"aarch64":{"sha256":"963b612339998a2dc68aea42ac0928933c0aa4ae18be22f365ec83c86e685b52","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-aarch64-host-aarch64.tar.xz"},"x86_64":{"sha256":"f38696590786e7c99d3bb5b8ce9ed66be6224d505fa45dcae0b2a6ec07eb0570","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-aarch64.tar.xz"}},"armv7":{"aarch64":{"sha256":"24a3c48b46cd3d0b80f6a780cdc87e4327e06e7a6ba3b08de9045dda010e6721","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-armv7-host-aarch64.tar.xz"},"x86_64":{"sha256":"8ecb5b35aa25efe78772701c70ed27eda727264303d03cffc372a6f24f18be90","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-armv7.tar.xz"}},"x86_64":{"aarch64":{"sha256":"5096ac470ff1023ac337b1fee847d941946401142121f1f094600b854e2569d6","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-x86_64-host-aarch64.tar.xz"},"x86_64":{"sha256":"f31edf791877935258dcc864afbfb7c9f9238be9f7d9da0ee57f5bc121074457","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-x86_64.tar.xz"}}},"16.1.0":{"aarch64":{"aarch64":{"sha256":"4492c3160e07f5a931112a1646413b5a0ccaefff1d6ae5dc58d361cb7840d394","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-aarch64-host-aarch64.tar.xz"},"x86_64":{"sha256":"4331e513156a699c1015fb94021497306f0a896520efbad8b3e16418eb683468","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-aarch64.tar.xz"}},"armv7":{"aarch64":{"sha256":"0f51857564e065113dbec6b106241ec6437b9cba7bb5dedc54ada0fd6ab73e80","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-armv7-host-aarch64.tar.xz"},"x86_64":{"sha256":"8d42c1fd130ccb170fe8d5d17148ae2d3f97134ac0009fdcac87550fec6a6289","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-armv7.tar.xz"}},"x86_64":{"aarch64":{"sha256":"7b10a4d5e89d043044e7d7850e0693740bb4643ef231499d1c887759ed7b8615","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-x86_64-host-aarch64.tar.xz"},"x86_64":{"sha256":"cfd8ca5bc365c1c838825ed6e44c7b2c309aada25791f76ef73b1aec819e362e","url":"https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-x86_64.tar.xz"}}},"16.2.0":{"aarch64":{"aarch64":{"sha256":"82a482d269cf75334cb969ef93593655f7e726e855043214e38b3672b10f97de","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-aarch64-host-aarch64.tar.xz"},"x86_64":{"sha256":"6407b35116f21c59e98ab5ad68ddd8ff5f3e0469723a5d465ec08ed615b11a55","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-aarch64.tar.xz"}},"armv7":{"aarch64":{"sha256":"cb97908d9d375a9e7502898a7277832aa63ca696ffc1088411f0eac921d5d54d","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-armv7-host-aarch64.tar.xz"},"x86_64":{"sha256":"515da8a22fa560002d3d149ad701acb725502c70f7bf8d4905f90b0830d38238","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-armv7.tar.xz"}},"x86_64":{"aarch64":{"sha256":"600c8d1a6e70eb0b259a01eef3fd4429a43d3cfebe4c6e01659bc6fcf5556415","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-x86_64-host-aarch64.tar.xz"},"x86_64":{"sha256":"54af34c821e59b03ded8f82d3a1104426ec4baaf3b226233e1fd76ad5dcb78cf","url":"https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-x86_64.tar.xz"}}}}" |
+| host_arch | The architecture the toolchain binaries RUN on. E.g. aarch64. Defaults to the architecture Bazel is running on, so a native build needs no configuration; set it only to fetch a toolchain for a different host. | String | optional | "" |
| includes | Extra includes for compiling C and C++. %workspace% is rendered to the toolchain root path. See https://github.com/bazelbuild/bazel/blob/a48e246e/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderHelper.java#L234-L254. | List of strings | optional | [] |
| repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.<p>For example, an entry "@foo": "@bar" declares that, for any time this repository depends on @foo (such as a dependency on @foo//some:target, it should actually resolve that dependency within globally-declared @bar (@bar//some:target). | Dictionary: String -> String | required | |
| supports_param_files | Set supports_param_files = 1 on the generated cc_toolchain, which lets Bazel pass linker arguments via an @params file. Enable this when link command lines for large targets overflow ARG_MAX (e.g. collect2: posix_spawn: Argument list too long). Off by default to preserve historical behavior. | Boolean | optional | False |
@@ -63,7 +64,7 @@ e.g. if you are consuming this repository as a Bzlmod dependency.
| :------------- | :------------- | :------------- |
| name | The name of the hub repository holding the toolchain declarations. | none |
| target_arch | The target architecture of the toolchain. | none |
-| kwargs | The extra arguments passed to gcc_toolchain. See gcc_toolchain for more info. The attributes of the toolchain declarations themselves are also accepted here, since they apply to the hub rather than to gcc_toolchain:
target_compatible_with: constraint_values passed to target_compatible_with of the toolchain. {target_arch} is rendered to the target_arch argument value. Defaults to ["@platforms//os:linux", "@platforms//cpu:{target_arch}"].
extra_target_compatible_with: Additional constraint_values appended to target_compatible_with of the toolchain, on top of the values from the target_compatible_with argument (including its defaults). Unlike target_compatible_with, {target_arch} is not rendered.
target_settings: Additional config_settings passed to target_settings of the toolchain, on top of the GCC version selection. {target_arch} is rendered to the target_arch argument value. | none |
+| kwargs | The extra arguments passed to gcc_toolchain. See gcc_toolchain for more info. The attributes of the toolchain declarations themselves are also accepted here, since they apply to the hub rather than to gcc_toolchain:
exec_compatible_with: constraint_values passed to exec_compatible_with of the toolchain. {host_arch} is rendered to the host_arch argument value. Defaults to ["@platforms//os:linux", "@platforms//cpu:{host_arch}"].
target_compatible_with: constraint_values passed to target_compatible_with of the toolchain. {target_arch} is rendered to the target_arch argument value. Defaults to ["@platforms//os:linux", "@platforms//cpu:{target_arch}"].
extra_target_compatible_with: Additional constraint_values appended to target_compatible_with of the toolchain, on top of the values from the target_compatible_with argument (including its defaults). Unlike target_compatible_with, {target_arch} is not rendered.
target_settings: Additional config_settings passed to target_settings of the toolchain, on top of the GCC version selection. {target_arch} is rendered to the target_arch argument value. | none |
diff --git a/docs/updating-gcc-builds.md b/docs/updating-gcc-builds.md
index 402aee6..69fd2fe 100644
--- a/docs/updating-gcc-builds.md
+++ b/docs/updating-gcc-builds.md
@@ -3,18 +3,25 @@
The prebuilt toolchain tarballs are produced by
[f0rmiga/gcc-builds](https://github.com/f0rmiga/gcc-builds) and pinned in this repository by
`AVAILABLE_GCC_VERSIONS` in [toolchain/defs.bzl](../toolchain/defs.bzl). Each GCC version maps to
-one URL and SHA256 per target architecture:
+one URL and SHA256 per target architecture and host architecture:
```starlark
AVAILABLE_GCC_VERSIONS = {
"16.2.0": {
- "aarch64": {"url": "...", "sha256": "..."},
- "armv7": {"url": "...", "sha256": "..."},
- "x86_64": {"url": "...", "sha256": "..."},
+ "aarch64": {
+ "aarch64": {"url": "...", "sha256": "..."},
+ "x86_64": {"url": "...", "sha256": "..."},
+ },
+ "armv7": {...},
+ "x86_64": {...},
},
}
```
+The outer architecture is the **target**, the inner one is the **host** the binaries run on. A
+version needs no entry for a host it has no build for; asking for one fails with a message listing
+the hosts it does have.
+
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.
@@ -26,10 +33,10 @@ gh release list --repo f0rmiga/gcc-builds --limit 30
gh release view --repo f0rmiga/gcc-builds --json assets --jq '.assets[].name'
```
-Assets are named `gcc-toolchain--.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.
+Assets are named `gcc-toolchain--.tar.xz` for an x86_64-hosted build, and
+`gcc-toolchain---host-aarch64.tar.xz` for an aarch64-hosted one. Both go
+into `AVAILABLE_GCC_VERSIONS`, under the matching host key. Releases before `08072026` publish no
+`-host-aarch64` assets at all, so the versions pinned to them have an `x86_64` host entry only.
## 2. Collect the SHA256 hashes
@@ -38,7 +45,7 @@ downloaded:
```shell
gh api repos/f0rmiga/gcc-builds/releases/tags/ \
- --jq '.assets[] | select(.name | test("host") | not) | "\(.name) \(.digest)"'
+ --jq '.assets[] | "\(.name) \(.digest)"'
```
Strip the `sha256:` prefix from each value. To confirm a digest independently:
@@ -62,7 +69,9 @@ adding or removing a version also means:
[.github/workflows/default.yaml](../.github/workflows/default.yaml);
- checking whether the tarball ships `bin/ld.lld`. GCC versions built without it cannot use the
`linker-lld` feature, and `//tests/lld` marks those versions incompatible so the test is skipped
- rather than failing.
+ rather than failing;
+- checking whether it has an aarch64-hosted build. `//tests/host_arch` marks the versions that do
+ not incompatible, the same way.
## 4. Regenerate the docs
@@ -132,5 +141,12 @@ tar -tJf /tmp/toolchain.tar.xz | grep -E '^\./bin/'
tar -tJf /tmp/toolchain.tar.xz | grep -E '^\./(lib|include)/'
```
+Note that where the C++ headers live depends on whether the build is **native**, not on the
+architecture. A build whose host and target match lays libstdc++ out flat under
+`include/c++/`, while a cross build nests it under the target triple. So the
+x86_64-hosted x86_64 and aarch64-hosted aarch64 tarballs are both flat, and the x86_64-hosted
+aarch64 and aarch64-hosted x86_64 ones are both nested. Getting this wrong is quiet: a nonexistent
+`-isystem` directory is ignored, and only surfaces later as a missing `` naming no path.
+
Detection only covers the binary prefix. If the include or library directories move, both
`_gcc_toolchain_impl` and `_TOOLCHAIN_BUILD_FILE_CONTENT` need updating.
diff --git a/tests/host_arch/BUILD.bazel b/tests/host_arch/BUILD.bazel
new file mode 100644
index 0000000..55aae22
--- /dev/null
+++ b/tests/host_arch/BUILD.bazel
@@ -0,0 +1,42 @@
+# Copyright (c) Thulio Ferraz Assis 2026
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@rules_shell//shell:sh_test.bzl", "sh_test")
+
+# The aarch64-hosted toolchain, declared (not registered) as @gcc_toolchain_aarch64_host.
+# Its binaries are ARM, so they cannot be RUN on an x86_64 CI machine; this inspects the
+# fetched archive instead, which works on any host.
+#
+# `include` carries the builtin header tree, so requiring it as data also proves the layout
+# the toolchain declares is the layout the archive actually has -- a nonexistent -isystem
+# path is otherwise ignored silently, surfacing much later as a missing .
+#
+# gcc-builds only publishes -host-aarch64 archives from the 08072026 release on, so the
+# versions pinned to older releases have no aarch64-hosted build to inspect and the test is
+# skipped for them, as in //tests/lld. Being incompatible keeps the target unanalyzed, so
+# the archive that does not exist is never fetched.
+sh_test(
+ name = "host_arch_test",
+ srcs = ["host_arch_test.sh"],
+ data = [
+ "@gcc_toolchain_aarch64_host//:gcc",
+ "@gcc_toolchain_aarch64_host//:include",
+ ],
+ env = {"GCC_FILES": "$(locations @gcc_toolchain_aarch64_host//:gcc)"},
+ target_compatible_with = select({
+ "//toolchain:gcc_version_12_5_0": ["@platforms//:incompatible"],
+ "//toolchain:gcc_version_13_4_0": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ }),
+)
diff --git a/tests/host_arch/host_arch_test.sh b/tests/host_arch/host_arch_test.sh
new file mode 100755
index 0000000..bf12884
--- /dev/null
+++ b/tests/host_arch/host_arch_test.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+# Copyright (c) Thulio Ferraz Assis 2026
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# An aarch64-hosted toolchain must ship ARM binaries. Verified by inspecting the archive
+# rather than running it, so this test works on any host.
+
+set -euo pipefail
+
+gcc=""
+for f in ${GCC_FILES}; do
+ if [[ "${f}" == *-gcc ]]; then
+ gcc="${f}"
+ break
+ fi
+done
+
+if [[ -z "${gcc}" ]]; then
+ echo >&2 "FAIL: no *-gcc among the toolchain's compiler files: ${GCC_FILES}"
+ exit 1
+fi
+
+# ELF e_machine, at offset 18, little-endian: 0x00b7 is EM_AARCH64, 0x003e is x86-64. An
+# x86_64-hosted build here would mean the toolchain cannot run on an aarch64 machine at
+# all, which is the bug the host_arch attribute exists to fix.
+readonly machine="$(od -An -tx1 -j18 -N2 "${gcc}" | tr -d ' \n')"
+if [[ "${machine}" != "b700" ]]; then
+ echo >&2 "FAIL: ${gcc} has e_machine 0x${machine}, want 0xb7 (EM_AARCH64)."
+ exit 1
+fi
+
+echo "PASS: the aarch64-hosted toolchain ships ARM binaries."
diff --git a/toolchain/defs.bzl b/toolchain/defs.bzl
index f96cc79..9cf91ae 100644
--- a/toolchain/defs.bzl
+++ b/toolchain/defs.bzl
@@ -31,6 +31,14 @@ _TRIPLE_BINARY_PREFIXES = {
"x86_64": "x86_64-linux-",
}
+# Bazel spells the host CPU the way Go does ("amd64"), while target_arch and the
+# @platforms//cpu constraints use the GNU name ("x86_64"). Only these two architectures can
+# HOST a toolchain; armv7 is a target only.
+_BAZEL_HOST_ARCHS = {
+ "aarch64": "aarch64",
+ "amd64": "x86_64",
+}
+
def _detect_binary_prefix(rctx, target_arch):
"""Resolves the prefix that `bin/` binaries carry in the extracted toolchain.
@@ -50,10 +58,63 @@ def _detect_binary_prefix(rctx, target_arch):
return triple_prefix
return ""
+def _resolve_host_arch(rctx):
+ """Resolves the architecture the toolchain binaries run on.
+
+ Args:
+ rctx: The repository context.
+
+ Returns:
+ The value of the `host_arch` attribute, or the architecture Bazel itself is running
+ on when that attribute is left at its empty default.
+ """
+ return rctx.attr.host_arch or _BAZEL_HOST_ARCHS.get(rctx.os.arch, ARCHS.x86_64)
+
+def _resolve_build(gcc_versions, gcc_version, target_arch, host_arch):
+ """Picks the archive to fetch for one (version, target, host) combination.
+
+ Args:
+ gcc_versions: The decoded `gcc_versions` attribute.
+ gcc_version: The GCC version to fetch.
+ target_arch: The architecture the toolchain produces code for.
+ host_arch: The architecture the toolchain binaries run on.
+
+ Returns:
+ The `{url, sha256}` dict of the archive to fetch.
+ """
+ build = gcc_versions[gcc_version][target_arch]
+
+ # A build entry is either a `{host_arch: {url, sha256}}` mapping, or the flat
+ # `{url, sha256}` of an x86_64-hosted toolchain. The flat form keeps a hand-written
+ # gcc_versions from before host_arch existed working, and means it as x86_64-hosted.
+ if "url" not in build:
+ if host_arch not in build:
+ fail("gcc {} for target {} has no {}-hosted build. Available: {}.".format(
+ gcc_version,
+ target_arch,
+ host_arch,
+ ", ".join(sorted(build)),
+ ))
+ return build[host_arch]
+ if host_arch != ARCHS.x86_64:
+ fail(("gcc_versions for {} target {} lists a single (x86_64-hosted) build, but this " +
+ "toolchain is {}-hosted. Give it a {{host_arch: {{url, sha256}}}} mapping.").format(
+ gcc_version,
+ target_arch,
+ host_arch,
+ ))
+ return build
+
def _gcc_toolchain_impl(rctx):
- versions = json.decode(rctx.attr.gcc_versions)
- url = versions[rctx.attr.gcc_version][rctx.attr.target_arch]["url"]
- sha256 = versions[rctx.attr.gcc_version][rctx.attr.target_arch]["sha256"]
+ host_arch = _resolve_host_arch(rctx)
+ build = _resolve_build(
+ json.decode(rctx.attr.gcc_versions),
+ rctx.attr.gcc_version,
+ rctx.attr.target_arch,
+ host_arch,
+ )
+ url = build["url"]
+ sha256 = build["sha256"]
rctx.download_and_extract(
url = url,
sha256 = sha256,
@@ -93,6 +154,12 @@ def _gcc_toolchain_impl(rctx):
elif target_arch == ARCHS.x86_64:
include_prefix = "x86_64-linux/"
+ # A NATIVE build (host == target) puts libstdc++ and the target headers at the root of
+ # the archive, while a CROSS build nests them under the target triple. This is a
+ # property of the build, not of the architecture: the aarch64-hosted aarch64 toolchain
+ # is native and therefore flat, whereas the aarch64-hosted x86_64 one is nested.
+ is_native = host_arch == target_arch
+
c_builtin_includes = [
include.format(
gcc_version = rctx.attr.gcc_version,
@@ -101,38 +168,28 @@ def _gcc_toolchain_impl(rctx):
for include in [
"%workspace%/lib/gcc/{include_prefix}{gcc_version}/include",
"%workspace%/lib/gcc/{include_prefix}{gcc_version}/include-fixed",
- ] + ([
+ ] + ([] if is_native else [
"%workspace%/{include_prefix}include",
- ] if target_arch != ARCHS.x86_64 else []) + [
+ ]) + [
"%workspace%/sysroot/usr/include",
]
]
- cxx_builtin_includes = []
- if target_arch == ARCHS.x86_64:
- cxx_builtin_includes.extend([
- include.format(
- gcc_version = rctx.attr.gcc_version,
- include_prefix = include_prefix,
- )
- for include in [
- "%workspace%/include/c++/{gcc_version}",
- "%workspace%/include/c++/{gcc_version}/{include_prefix}",
- "%workspace%/include/c++/{gcc_version}/backward",
- ]
- ])
- else:
- cxx_builtin_includes.extend([
- include.format(
- gcc_version = rctx.attr.gcc_version,
- include_prefix = include_prefix,
- )
- for include in [
- "%workspace%/{include_prefix}include/c++/{gcc_version}",
- "%workspace%/{include_prefix}include/c++/{gcc_version}/{include_prefix}",
- "%workspace%/{include_prefix}include/c++/{gcc_version}/backward",
- ]
+ cxx_builtin_includes = [
+ include.format(
+ gcc_version = rctx.attr.gcc_version,
+ include_prefix = include_prefix,
+ )
+ for include in ([
+ "%workspace%/include/c++/{gcc_version}",
+ "%workspace%/include/c++/{gcc_version}/{include_prefix}",
+ "%workspace%/include/c++/{gcc_version}/backward",
+ ] if is_native else [
+ "%workspace%/{include_prefix}include/c++/{gcc_version}",
+ "%workspace%/{include_prefix}include/c++/{gcc_version}/{include_prefix}",
+ "%workspace%/{include_prefix}include/c++/{gcc_version}/backward",
])
+ ]
f_builtin_includes = [
include.format(
@@ -315,86 +372,170 @@ def _fortran_vars(enable_fortran, gcc_toolchain_workspace_name, include_prefix,
AVAILABLE_GCC_VERSIONS = {
"12.5.0": {
"aarch64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-aarch64.tar.xz",
- "sha256": "7b0e25133a98d44b648a925ba11f64a3adc470e87668af80ce2c3af389ebe9be",
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-aarch64.tar.xz",
+ "sha256": "7b0e25133a98d44b648a925ba11f64a3adc470e87668af80ce2c3af389ebe9be",
+ },
},
"armv7": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-armv7.tar.xz",
- "sha256": "a0ef76c8cc517b3d76dd2f09b1a371975b2ff1082e2f9372ed79af01b9292934",
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-armv7.tar.xz",
+ "sha256": "a0ef76c8cc517b3d76dd2f09b1a371975b2ff1082e2f9372ed79af01b9292934",
+ },
},
"x86_64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-x86_64.tar.xz",
- "sha256": "51076e175839b434bb2dc0006c0096916df585e8c44666d35b0e3ce821d535db",
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-12.5.0-x86_64.tar.xz",
+ "sha256": "51076e175839b434bb2dc0006c0096916df585e8c44666d35b0e3ce821d535db",
+ },
},
},
"13.4.0": {
"aarch64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-aarch64.tar.xz",
- "sha256": "770cf6bf62bdf78763de526d3a9f5cae4c19f1a3aca0ef8f18b05f1a46d1ffaf",
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-aarch64.tar.xz",
+ "sha256": "770cf6bf62bdf78763de526d3a9f5cae4c19f1a3aca0ef8f18b05f1a46d1ffaf",
+ },
},
"armv7": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-armv7.tar.xz",
- "sha256": "1b2739b5003c5a3f0ab7c4cc7fb95cc99c0e933982512de7255c2bd9ced757ad",
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-armv7.tar.xz",
+ "sha256": "1b2739b5003c5a3f0ab7c4cc7fb95cc99c0e933982512de7255c2bd9ced757ad",
+ },
},
"x86_64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-x86_64.tar.xz",
- "sha256": "d96071c1b98499afd7b7b56ebd69ad414020edf66e982004acffe7df8aaf7e02",
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/18082025/gcc-toolchain-13.4.0-x86_64.tar.xz",
+ "sha256": "d96071c1b98499afd7b7b56ebd69ad414020edf66e982004acffe7df8aaf7e02",
+ },
},
},
"14.3.0": {
"aarch64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-aarch64.tar.xz",
- "sha256": "b5a73bc840938c8dbb49e2f15b8b8d63e5c33beae0be2aa9a7c52b593522cdcd",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-aarch64-host-aarch64.tar.xz",
+ "sha256": "def0f33e644f8586f6ca39754951eebe2189b92823bdaf6d4c4ba42fdad6c598",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-aarch64.tar.xz",
+ "sha256": "b5a73bc840938c8dbb49e2f15b8b8d63e5c33beae0be2aa9a7c52b593522cdcd",
+ },
},
"armv7": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-armv7.tar.xz",
- "sha256": "376684c062a23e84b619a717fa4c7bba336211c8b48169f76eb5aa6ed4da6bb8",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-armv7-host-aarch64.tar.xz",
+ "sha256": "ff3e11e2b222fb42146f1254c6a089234e8cd8e384128de56afc781af13d72d9",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-armv7.tar.xz",
+ "sha256": "376684c062a23e84b619a717fa4c7bba336211c8b48169f76eb5aa6ed4da6bb8",
+ },
},
"x86_64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-x86_64.tar.xz",
- "sha256": "d155a38e4acff9588df466f0edc98c1a2c54d09bc0162805ba38908cfd7a1d28",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-x86_64-host-aarch64.tar.xz",
+ "sha256": "716ed801e7f2cb35cf25614ffe8e8293934587198e919bcb8c55016c862628f1",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-14.3.0-x86_64.tar.xz",
+ "sha256": "d155a38e4acff9588df466f0edc98c1a2c54d09bc0162805ba38908cfd7a1d28",
+ },
},
},
"15.2.0": {
"aarch64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-aarch64.tar.xz",
- "sha256": "f38696590786e7c99d3bb5b8ce9ed66be6224d505fa45dcae0b2a6ec07eb0570",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-aarch64-host-aarch64.tar.xz",
+ "sha256": "963b612339998a2dc68aea42ac0928933c0aa4ae18be22f365ec83c86e685b52",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-aarch64.tar.xz",
+ "sha256": "f38696590786e7c99d3bb5b8ce9ed66be6224d505fa45dcae0b2a6ec07eb0570",
+ },
},
"armv7": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-armv7.tar.xz",
- "sha256": "8ecb5b35aa25efe78772701c70ed27eda727264303d03cffc372a6f24f18be90",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-armv7-host-aarch64.tar.xz",
+ "sha256": "24a3c48b46cd3d0b80f6a780cdc87e4327e06e7a6ba3b08de9045dda010e6721",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-armv7.tar.xz",
+ "sha256": "8ecb5b35aa25efe78772701c70ed27eda727264303d03cffc372a6f24f18be90",
+ },
},
"x86_64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-x86_64.tar.xz",
- "sha256": "f31edf791877935258dcc864afbfb7c9f9238be9f7d9da0ee57f5bc121074457",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-x86_64-host-aarch64.tar.xz",
+ "sha256": "5096ac470ff1023ac337b1fee847d941946401142121f1f094600b854e2569d6",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-15.2.0-x86_64.tar.xz",
+ "sha256": "f31edf791877935258dcc864afbfb7c9f9238be9f7d9da0ee57f5bc121074457",
+ },
},
},
"16.1.0": {
"aarch64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-aarch64.tar.xz",
- "sha256": "4331e513156a699c1015fb94021497306f0a896520efbad8b3e16418eb683468",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-aarch64-host-aarch64.tar.xz",
+ "sha256": "4492c3160e07f5a931112a1646413b5a0ccaefff1d6ae5dc58d361cb7840d394",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-aarch64.tar.xz",
+ "sha256": "4331e513156a699c1015fb94021497306f0a896520efbad8b3e16418eb683468",
+ },
},
"armv7": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-armv7.tar.xz",
- "sha256": "8d42c1fd130ccb170fe8d5d17148ae2d3f97134ac0009fdcac87550fec6a6289",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-armv7-host-aarch64.tar.xz",
+ "sha256": "0f51857564e065113dbec6b106241ec6437b9cba7bb5dedc54ada0fd6ab73e80",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-armv7.tar.xz",
+ "sha256": "8d42c1fd130ccb170fe8d5d17148ae2d3f97134ac0009fdcac87550fec6a6289",
+ },
},
"x86_64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-x86_64.tar.xz",
- "sha256": "cfd8ca5bc365c1c838825ed6e44c7b2c309aada25791f76ef73b1aec819e362e",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-x86_64-host-aarch64.tar.xz",
+ "sha256": "7b10a4d5e89d043044e7d7850e0693740bb4643ef231499d1c887759ed7b8615",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/08072026/gcc-toolchain-16.1.0-x86_64.tar.xz",
+ "sha256": "cfd8ca5bc365c1c838825ed6e44c7b2c309aada25791f76ef73b1aec819e362e",
+ },
},
},
"16.2.0": {
"aarch64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-aarch64.tar.xz",
- "sha256": "6407b35116f21c59e98ab5ad68ddd8ff5f3e0469723a5d465ec08ed615b11a55",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-aarch64-host-aarch64.tar.xz",
+ "sha256": "82a482d269cf75334cb969ef93593655f7e726e855043214e38b3672b10f97de",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-aarch64.tar.xz",
+ "sha256": "6407b35116f21c59e98ab5ad68ddd8ff5f3e0469723a5d465ec08ed615b11a55",
+ },
},
"armv7": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-armv7.tar.xz",
- "sha256": "515da8a22fa560002d3d149ad701acb725502c70f7bf8d4905f90b0830d38238",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-armv7-host-aarch64.tar.xz",
+ "sha256": "cb97908d9d375a9e7502898a7277832aa63ca696ffc1088411f0eac921d5d54d",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-armv7.tar.xz",
+ "sha256": "515da8a22fa560002d3d149ad701acb725502c70f7bf8d4905f90b0830d38238",
+ },
},
"x86_64": {
- "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-x86_64.tar.xz",
- "sha256": "54af34c821e59b03ded8f82d3a1104426ec4baaf3b226233e1fd76ad5dcb78cf",
+ "aarch64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-x86_64-host-aarch64.tar.xz",
+ "sha256": "600c8d1a6e70eb0b259a01eef3fd4429a43d3cfebe4c6e01659bc6fcf5556415",
+ },
+ "x86_64": {
+ "url": "https://github.com/f0rmiga/gcc-builds/releases/download/10082026/gcc-toolchain-16.2.0-x86_64.tar.xz",
+ "sha256": "54af34c821e59b03ded8f82d3a1104426ec4baaf3b226233e1fd76ad5dcb78cf",
+ },
},
},
}
@@ -451,7 +592,17 @@ _FEATURE_ATTRS = {
"gcc_versions": attr.string(
default = json.encode(AVAILABLE_GCC_VERSIONS),
doc = "A JSON dictionary of GCC versions to their download URLs and SHA256 hashes." +
- " The structure is {: {: {url: , sha256: }}}.",
+ " The structure is" +
+ " {: {: {: {url: , sha256: }}}}." +
+ " A {url, sha256} directly under is also accepted and means an" +
+ " x86_64-hosted build.",
+ ),
+ "host_arch": attr.string(
+ doc = "The architecture the toolchain binaries RUN on. E.g. aarch64." +
+ " Defaults to the architecture Bazel is running on, so a native build needs" +
+ " no configuration; set it only to fetch a toolchain for a different host.",
+ default = "",
+ values = ["", "aarch64", "x86_64"],
),
"includes": attr.string_list(
doc = "Extra includes for compiling C and C++." +
@@ -473,6 +624,14 @@ _FEATURE_ATTRS = {
# Attributes of the `toolchain` declarations, which live in the hub rather than in the repository
# holding the compiler itself.
_TOOLCHAIN_DECLARATION_ATTRS = {
+ "exec_compatible_with": attr.string_list(
+ default = [
+ "@platforms//os:linux",
+ "@platforms//cpu:{host_arch}",
+ ],
+ doc = "constraint_values passed to exec_compatible_with of the toolchain. {host_arch} is rendered to the host_arch attribute value.",
+ mandatory = False,
+ ),
"extra_target_compatible_with": attr.label_list(
doc = "Additional constraint_values appended to target_compatible_with of the toolchain," +
" on top of the values from the target_compatible_with attribute (including its defaults)." +
@@ -515,6 +674,14 @@ def _gcc_toolchains_hub_impl(rctx):
target_arch = rctx.attr.target_arch
gcc_version_flag = str(rctx.attr._gcc_version_flag)
+ # The toolchain binaries are built FOR host_arch, so that is what can execute them.
+ # Resolved the same way the toolchain repositories resolve it, since both see the same
+ # rctx.os.arch.
+ exec_compatible_with = [
+ v.format(host_arch = _resolve_host_arch(rctx))
+ for v in rctx.attr.exec_compatible_with
+ ]
+
target_compatible_with = [
v.format(target_arch = target_arch)
for v in rctx.attr.target_compatible_with
@@ -564,6 +731,7 @@ def _gcc_toolchains_hub_impl(rctx):
setting = ":_gcc_version_default" if is_default else ":_gcc_version_" + _sanitize_version(gcc_version)
content.append(_HUB_TOOLCHAIN_TEMPLATE.format(
suffix = suffix,
+ exec_compatible_with = exec_compatible_with,
target_compatible_with = target_compatible_with,
target_settings = [setting] + extra_target_settings,
toolchain_repo = toolchain_repos[gcc_version],
@@ -571,6 +739,7 @@ def _gcc_toolchains_hub_impl(rctx):
if rctx.attr.enable_fortran:
content.append(_HUB_FORTRAN_TOOLCHAIN_TEMPLATE.format(
suffix = suffix,
+ exec_compatible_with = exec_compatible_with,
target_compatible_with = target_compatible_with,
target_settings = [setting] + extra_target_settings,
toolchain_repo = toolchain_repos[gcc_version],
@@ -609,6 +778,9 @@ _gcc_toolchains_hub = repository_rule(
doc = "Whether to declare the Fortran toolchains.",
default = True,
),
+ # The same attribute the toolchain repositories take: the hub renders it into
+ # exec_compatible_with, they use it to pick the archive.
+ "host_arch": _FEATURE_ATTRS["host_arch"],
"target_arch": attr.string(
doc = "The target architecture the toolchains produce. E.g. x86_64.",
mandatory = True,
@@ -634,6 +806,7 @@ ATTRS_SHARED_WITH_MODULE_EXTENSION = {
for attr_name in [
"gcc_version",
"gcc_versions",
+ "host_arch",
"enable_fortran",
"extra_cflags",
"extra_cxxflags",
@@ -744,6 +917,10 @@ def gcc_declare_toolchain(
The attributes of the `toolchain` declarations themselves are also accepted here,
since they apply to the hub rather than to `gcc_toolchain`:
+ `exec_compatible_with`: constraint_values passed to `exec_compatible_with` of the
+ toolchain. `{host_arch}` is rendered to the `host_arch` argument value. Defaults to
+ `["@platforms//os:linux", "@platforms//cpu:{host_arch}"]`.
+
`target_compatible_with`: constraint_values passed to `target_compatible_with` of the
toolchain. `{target_arch}` is rendered to the `target_arch` argument value. Defaults to
`["@platforms//os:linux", "@platforms//cpu:{target_arch}"]`.
@@ -766,10 +943,16 @@ def gcc_declare_toolchain(
default_gcc_version = kwargs.pop("gcc_version", DEFAULT_GCC_VERSION)
gcc_versions = kwargs.pop("gcc_versions", json.encode(AVAILABLE_GCC_VERSIONS))
enable_fortran = kwargs.pop("enable_fortran", True)
+ exec_compatible_with = kwargs.pop("exec_compatible_with", None)
extra_target_compatible_with = kwargs.pop("extra_target_compatible_with", [])
target_compatible_with = kwargs.pop("target_compatible_with", None)
target_settings = kwargs.pop("target_settings", [])
+ # Read by both the hub, which renders it into exec_compatible_with, and every toolchain
+ # repository, which uses it to pick the archive. Left at "" it resolves to the host
+ # Bazel is running on, which each repository rule can see for itself.
+ host_arch = kwargs.pop("host_arch", "")
+
# Left in kwargs so that the per-version repositories keep receiving it.
repo_mapping = kwargs.get("repo_mapping", None)
@@ -798,12 +981,18 @@ def gcc_declare_toolchain(
fincludes = fincludes,
gcc_version = gcc_version,
gcc_versions = gcc_versions,
+ host_arch = host_arch,
target_arch = target_arch,
**kwargs
)
hub_kwargs = {}
+ # An explicitly empty exec_compatible_with / target_compatible_with drops the default
+ # constraints, so only an omitted one may fall back to the attribute default.
+ if exec_compatible_with != None:
+ hub_kwargs["exec_compatible_with"] = exec_compatible_with
+
# An explicitly empty target_compatible_with drops the default constraints, so only an omitted
# one may fall back to the attribute default.
if target_compatible_with != None:
@@ -819,6 +1008,7 @@ def gcc_declare_toolchain(
default_gcc_version = default_gcc_version,
enable_fortran = enable_fortran,
extra_target_compatible_with = extra_target_compatible_with,
+ host_arch = host_arch,
target_arch = target_arch,
target_settings = target_settings,
toolchain_repos = toolchain_repos,
@@ -895,10 +1085,7 @@ package(default_visibility = ["//visibility:public"])'''
_HUB_TOOLCHAIN_TEMPLATE = '''\
toolchain(
name = "cc_toolchain{suffix}",
- exec_compatible_with = [
- "@platforms//os:linux",
- "@platforms//cpu:x86_64",
- ],
+ exec_compatible_with = {exec_compatible_with},
target_compatible_with = {target_compatible_with},
target_settings = {target_settings},
toolchain = "@{toolchain_repo}//:_cc_toolchain",
@@ -908,10 +1095,7 @@ toolchain(
_HUB_FORTRAN_TOOLCHAIN_TEMPLATE = '''\
toolchain(
name = "fortran_toolchain{suffix}",
- exec_compatible_with = [
- "@platforms//os:linux",
- "@platforms//cpu:x86_64",
- ],
+ exec_compatible_with = {exec_compatible_with},
target_compatible_with = {target_compatible_with},
target_settings = {target_settings},
toolchain = "@{toolchain_repo}//:_fortran_toolchain",
diff --git a/toolchain/module_extensions.bzl b/toolchain/module_extensions.bzl
index efe9f27..bb4e182 100644
--- a/toolchain/module_extensions.bzl
+++ b/toolchain/module_extensions.bzl
@@ -15,6 +15,7 @@ def _gcc_register_toolchain_module_extension(mctx):
target_arch = declare.target_arch,
gcc_version = declare.gcc_version,
gcc_versions = declare.gcc_versions,
+ host_arch = declare.host_arch,
enable_fortran = declare.enable_fortran,
extra_cflags = declare.extra_cflags,
extra_cxxflags = declare.extra_cxxflags,