Skip to content

Roadmap ​

What xclang supports today, and the status of everything it does not. Every item that no release carries has one row here, with one status word. Other pages link to that row instead of restating the status. Nothing here has a date. What each release changed is in the CHANGELOG.

statusmeaning
SupportedIn a release.
UnreleasedOn main and tested by CI, but no release carries it.
PlannedDecided, and in no release yet. It may be in progress on a branch.
In researchWanted. Whether it can be done well is still open.
ConsideredWanted. Its form or its cost is still open.
Not plannedOut of scope by design.

The Vision ​

xclang's vision is what rustup, cross-rs and cargo-zigbuild do for Rust, for clang: one compiler for every target.

  • The common targets come with the toolchain, as the six of today do.
  • Every other target is an archive of its own, fetched when a build needs it: its sysroot, its prebuilt runtimes and its config file.
  • Vendor SDKs that no one may redistribute (Apple's, Microsoft's) are fetched from the vendor by the user, who accepts their license. xclang never redistributes them.
  • Runtimes can also be built from source on demand, for options the prebuilt ones lack.

Today, the first and the third are in a release: the six targets, and since 23.1.2.7 Microsoft's and Apple's SDKs, which the user fetches with the xclang command. The rest is planned, in research or considered, item by item, in the tables below.

Every target keeps the hermeticity rule. A program depends at run time only on the libraries of its OS that cannot be redistributed, and links everything else statically.

Targets ​

A target's tier says how it is tested (tiers). For the targets here, tier 1 can also mean a runner that runs the target's programs: Windows x64 runs x86 programs, wasmtime WebAssembly ones. A tier 3 target may get its runtimes built on demand instead of prebuilt. "The user (SDK)" means the target needs a vendor SDK that the user fetches, accepting its license.

targetC runtimefromtierstatus
Linux x64, arm64glibc 2.17the toolchain1Supported
Windows x64, arm64 (MinGW)mingw-w64, UCRTthe toolchain1Supported
macOS arm64, x64, from macOS hostsApple's SDKXcode1Supported
Windows x64, arm64 (MSVC), with their sanitizersMicrosoft's CRT and STL, Windows SDKthe user (SDK)1Supported
macOS arm64, x64, from Linux and Windows hostsApple's SDKthe user (SDK)1Supported
Linux x64, arm64 (musl)muslxclang1Planned
Windows x86 (MSVC)Microsoft's CRT and STL, Windows SDKthe user (SDK)1In research
Windows 7 and XP (MSVC)Microsoft's CRT, static, with YY-Thunksthe user (SDK)3In research
Windows x86 (MinGW)mingw-w64, UCRTxclang1Considered
Windows arm64ecMicrosoft's ARM64EC librariesthe user (SDK)3Considered
Windows (MinGW) on msvcrt, before Windows 10msvcrtNot planned
Linux x64, arm64 with a newer glibcglibc 2.28xclang1Considered
Linux x86glibc 2.17xclang1Considered
Linux armv7 (hard float)glibc 2.17xclang2Considered
Linux riscv64glibc 2.31xclang2Considered
Linux ppc64le, s390xglibc 2.17xclang2Considered
Linux loongarch64glibc 2.36xclang2Considered
Linux riscv64, armv7 (musl)muslxclang2Considered
WebAssembly (wasm32-wasip1, wasm32-wasip2)wasi-libcxclang1Considered
Android arm64, x64, armv7bionicthe user, from the NDK (SDK)2Considered
OpenHarmony arm64OpenHarmony's muslxclang2Considered
FreeBSD x64, arm64FreeBSD 14's libcxclang2Considered
OpenBSD, NetBSDtheir libcxclang3Considered
Bare metal: Arm Cortex-M, -R, -A, AArch64, RISC-Vpicolibcxclang2Considered
iOS, tvOS, watchOS, visionOS, their simulatorsApple's SDKsthe user, from full Xcode (SDK)3In research
EmscriptenEmscripten's ownemsdkNot planned

What sets these targets apart:

  • MSVC targets. First-class targets, as the MinGW ones are, since 23.1.2.7. The default C runtime is Microsoft's "hybrid CRT": the VC runtime and the STL static, UCRT dynamic. xclang builds their compiler-rt: the builtins, the profile runtime and UBSan, and for x64 AddressSanitizer, whose runtime is a DLL, and libFuzzer. The MSVC and Windows SDK versions are pinned to ones the shipped clang accepts, and the user fetches them with the xclang command, which every toolchain archive carries (Windows). CMake builds them; the Bazel module does not yet (below).
  • macOS from any host. Since 23.1.2.7. Apple's macOS SDK is in the Command Line Tools package on Apple's update servers, and needs no Apple ID to download. The user fetches it with the xclang command into the toolchain, whose config files then use it on Linux and Windows hosts; on macOS, Xcode's SDK stays the one in use. The programs are those of a macOS host: xclang's libc++ linked in, ld64.lld, dSYMs, the sanitizers (macOS). CMake builds them; the Bazel module does not yet (below).
  • musl. Static programs that take nothing from the system they run on.
  • A newer glibc. The same targets for programs that need what glibc 2.17 lacks, such as -static-pie and newer functions, with the same runtimes.
  • Other Linux architectures. Each gets the oldest glibc it has; riscv64 and loongarch64 have nothing as old as 2.17. Their sanitizers are the ones compiler-rt supports on them.
  • WebAssembly. wasm32-wasip2 links with wasm-component-ld, which each host's toolchain needs to carry. C++ exceptions are opt-in.
  • Android. The NDK's sysroot, with xclang's static libc++ in the NDK's ABI namespace (__ndk1).
  • iOS and Apple's other devices. Their SDKs come only with full Xcode, downloaded with an Apple ID; xclang cannot remove that limit. Their runtimes are likely to be built on demand.
  • Windows 7 and XP. The MSVC target with the CRT linked statically, and YY-Thunks for the functions the old systems lack. MinGW with libc++ cannot reach XP. The goal is to find out how far hermeticity reaches there; Windows 9x is out of scope.
  • msvcrt. The MinGW targets use UCRT, which is part of Windows 10 and later. A MinGW variant on the older msvcrt is not planned.
  • Emscripten. emsdk is its toolchain, so it is not an xclang target.

The xclang Command ​

itemstatus
The xclang command: xclang sdk fetch for the vendor SDKsSupported
Target archives and a release index, for xclang target addPlanned
Fetched targets and vendor SDKs in the CMake package and the Bazel modulePlanned
The MSVC targets in the Bazel module, with the Windows SDK fetched by a repository rulePlanned
macOS targets from Linux and Windows hosts in the Bazel module, with the macOS SDK fetched by a repository rulePlanned

xclang is a program in Rust (cli/), built for every host with xclang as its C compiler and linker. Every toolchain archive carries it, as bin/xclang, since 23.1.2.7 (the xclang command).

  • xclang sdk fetch downloads a vendor SDK from the vendor, by version and sha256, once the user accepts its license. It is in every release since 23.1.2.7.
  • xclang target add unpacks a target's archive of the same release into the toolchain: its sysroot, its runtimes, compiler-rt, its config files and the licenses of its C runtime. No release publishes target archives yet, so it has nothing to add.
  • Each release gets an index of its target archives, as rustup's channel manifests are: archive, sha256, size, tier and the SDK it needs.
  • The CMake package and the Bazel module take fetched targets as they come. Today their toolchains build for the six targets of the host's archive, and the CMake package also for the MSVC targets, and for macOS from Linux and Windows hosts, with the fetched SDKs.
  • The plan for the MSVC targets in the Bazel module: a repository rule fetches the Windows SDK once the user accepts its license in MODULE.bazel, and the targets build with the GNU-style clang of the other toolchains.
  • The plan for macOS from Linux and Windows hosts in the Bazel module: the same repository rule fetches the macOS SDK, which stands in for the one a macOS host's rule finds with xcrun, and the macOS toolchains are registered on every host.

Runtimes and Tools ​

itemstatus
libc++, libc++abi and libunwind built from source on demandPlanned
MemorySanitizer, through libc++ built on demandPlanned
Sanitizers for MinGW targetsConsidered
@xclang//bazel:llvm-gsymutil, the toolchain's llvm-gsymutil for bazel runSupported
An xclang cargo helper that sets cargo's variablesConsidered
libgcc_s.a as a linker script naming libunwind, for Rust's Linux targetsConsidered
libc++ as the C++ library of MSVC targetsPlanned
An OpenMP runtimeNot planned
clang-format, clang-tidy and clangd programsNot planned
A shared C++ runtime across shared librariesNot planned
A compiler for building conda-forge packagesNot planned
libclang for programs built with the MSVC ABINot planned

libc++ built on demand means libc++, libc++abi and libunwind built from source inside a CMake or Bazel build, from LLVM's runtime sources of the release, with its patches. It covers what the prebuilt runtimes cannot be:

  • MemorySanitizer, which needs every library instrumented, libc++ too. ThreadSanitizer also reports better through an instrumented libc++.
  • Hardening and ABI options: a hardening mode checked inside the library, libc++'s ABI version 2, bounded iterators, an ABI namespace of one's own, and builds without exceptions or RTTI.
  • LTO and PGO of libc++ together with the program.
  • Targets without prebuilt runtimes: tier 3 ones and Apple's devices.

The prebuilt runtimes stay the default.

Rust and cargo work with xclang today as a recipe of environment variables (Rust and Cargo). A helper that sets them, as cargo-zigbuild's wrapper does, is considered. So is making libgcc_s.a a linker script, INPUT(-lunwind), instead of an empty archive: Rust's Linux targets then link without -l:libunwind.a. A test with 23.1.2.5's arm64 sysroot linked Rust, and C++ programs and shared libraries that name -lgcc_s.

libc++ for MSVC targets gives them the C++ library of every other target, its import std included, and becomes their default. Microsoft's STL stays a choice: C++ types passed between a program and libraries built with MSVC need the same library on both sides.

The not-planned items follow from what xclang is. It is a compiler toolchain, and libclang has the libraries that tools on clang link. Its runtimes are linked into every program (one libc++ per shared object). conda-forge's compilers link packaged runtimes dynamically, which xclang does not do. libclang is there for clice, which builds for MinGW on Windows, so no libclang is built with the MSVC ABI.

Speed ​

itemstatus
A PGO training that covers Objective-C, clang-cl, Mach-O links and clang-tidy's checksPlanned
BOLT for the Linux hosts' clang and lld, on top of PGO and ThinLTOIn research

The training is widened between releases, not while one is pending (PGO).

Reproducibility and Supply Chain ​

itemstatus
Relative paths in the debug information of CMake buildsPlanned
The same GSYM file on every run (xclang_debug_symbols passing --num-threads=1)Supported
Immutable GitHub releasesPlanned
Reproducible release archivesSupported
Third-party license notices in the archivesSupported
SLSA provenance attestationsConsidered
  • CMake builds write the build tree's absolute paths into debug information. Bazel builds already use paths relative to the execution root (debugging).
  • GSYM files from llvm-gsymutil's default threads differ run to run, with the same lookups. One thread is deterministic, about 1.4 times as slow; xclang_debug_symbols passes --num-threads=1 by default since 23.1.2.7.
  • Immutable releases keep an archive and its SHA256SUMS from being replaced together (releases).
  • Reproducible archives, since 23.1.2.7: sorted entries, the commit's time and no owner in the .tar.xz files, xz in fixed blocks whatever its threads; each host's archives are made twice, on two machines, and compared (build). The toolchain builds themselves are not compared.
  • License notices, since 23.1.2.7: every archive has share/licenses, each component's license files and an SPDX document (layout).

Following LLVM ​

itemstatus
LLVM 23.1.3 and 24.x, each as it is releasedPlanned

Each LLVM release is built with the patches checked against it. 23.1.3 has the fix for the macOS 27 SDK's arm64e.x1 stubs, which xclang carries as patch 0009 since 23.1.2.6.

Documentation ​

itemstatus
The docs in ChinesePlanned

The docs are in English only for now. The README has a Chinese version.

Open Questions ​

Questions inside the items above, not items of their own:

  • Android's sysroot: fetched by the user from Google's NDK (only the files it needs), or redistributed by xclang.
  • The runtimes of Apple's devices: published prebuilt, or only built on demand. Apple's license treats libraries for those platforms apart from macOS ones.
  • A glibc other than 2.17: chosen with a named config file (--config=), or with a spelling of the target.
  • Where fetched targets go: into the toolchain directory only, or also into a directory of the user's.
  • musl and the sanitizers: none, or a dynamically linked variant (Alpine's way) that has them.