Skip to content

Installation ​

Four ways to get xclang. Each gives the same toolchain of the same release, so pick the one that fits the build.

wayforwhat it downloads
pixi or condaa developer machine, CI, any build systemthe host toolchain, as a conda package
release archiveanything: unpack and usethe host toolchain
CMake FetchContenta CMake project that configures with nothing installedthe host toolchain, into the cache of the user
Bazel registrya Bazel projectthe host toolchain, and libclang if used, by sha256

In these docs, the toolchain directory is where the toolchain is installed or unpacked, $XCLANG in commands. Its bin/ holds clang, lld and the other tools (archive layout).

pixi and conda ​

xclang is in the clice conda channel. With pixi, a workspace names the channel and the package:

toml
[workspace]
name = "hello"
channels = ["conda-forge", "https://conda.clice.io"]
platforms = ["linux-64", "linux-aarch64", "osx-64", "osx-arm64", "win-64", "win-arm64"]

[dependencies]
xclang = "*"
sh
pixi install
  • The package is the host archive, every target included, in $PREFIX/opt/xclang. The activation of the environment puts its bin/ first in PATH. Nothing goes to $PREFIX/bin, so the compilers of conda-forge stay as they are.
  • There is one package per host: linux-64, linux-aarch64, osx-64, osx-arm64, win-64 and win-arm64.
  • * takes the newest release, and pixi.lock keeps the one installed until pixi update. "<version>.*" keeps one release, its newest build: the build number counts packaging fixes (versions).
  • llvm-option-inc, a noarch package, holds the option tables in $PREFIX/include/llvm-options-td.

xclang is not a compiler for building conda-forge packages (why).

Archives ​

Every GitHub release has the toolchain for each host, xclang-<version>-<host>.tar.xz, 86 to 94 MB. It unpacks anywhere, and is used from there: the toolchain directory is xclang/. The SHA256SUMS of the newest release names its archives, and so its version. On Linux:

sh
h=x86_64-unknown-linux-gnu
curl -LO https://github.com/clice-io/xclang/releases/latest/download/SHA256SUMS
v=$(sed -n "s/^[0-9a-f]*  xclang-\(.*\)-$h\.tar\.xz$/\1/p" SHA256SUMS)
curl -LO https://github.com/clice-io/xclang/releases/download/$v/xclang-$v-$h.tar.xz
sha256sum -c --ignore-missing SHA256SUMS
tar -xf xclang-$v-$h.tar.xz
xclang/bin/clang++ --target=aarch64-w64-mingw32 hello.cpp -o hello.exe

On macOS, check the download with shasum -a 256 -c --ignore-missing SHA256SUMS. On Windows, use PowerShell, whose tar is the one of the system (C:\Windows\System32\tar.exe):

powershell
$h = "x86_64-w64-mingw32"
curl.exe -LO https://github.com/clice-io/xclang/releases/latest/download/SHA256SUMS
$v = (Select-String -Path SHA256SUMS -Pattern "  xclang-(.+)-$h\.tar\.xz$").Matches[0].Groups[1].Value
curl.exe -LO https://github.com/clice-io/xclang/releases/download/$v/xclang-$v-$h.tar.xz
$sum = (Get-FileHash xclang-$v-$h.tar.xz -Algorithm SHA256).Hash.ToLower()
if (-not (Select-String -SimpleMatch -Quiet "$sum  xclang-$v-$h.tar.xz" SHA256SUMS)) { throw "sha256 mismatch" }
tar -xf xclang-$v-$h.tar.xz
xclang\bin\clang++ --target=aarch64-unknown-linux-gnu hello.cpp -o hello

For one release, set v to its version and download its SHA256SUMS from releases/download/$v. hello.cpp is the one of the quick start. Put xclang/bin in PATH, or name the programs by their path. A Windows archive holds no symbolic links, so it unpacks without extra rights (launchers). The other assets of a release, such as libclang, are listed in releases.

CMake FetchContent ​

A CMake project can download the toolchain itself, before project(), so it configures on a machine with nothing but CMake and Ninja:

cmake
include(FetchContent)
FetchContent_Declare(xclang
    GIT_REPOSITORY https://github.com/clice-io/xclang
    GIT_TAG latest)
FetchContent_MakeAvailable(xclang)
include(${xclang_SOURCE_DIR}/packages/cmake/xclang.cmake)

latest is a branch at the tag of the newest release; a release's tag keeps that release. It checks the archive against the SHA256SUMS of the release, and unpacks it into the cache of the user, once per release and host. The whole project is in CMake.

Bazel ​

The clice registry, bazel.clice.io, has the module. Add the registry to .bazelrc:

common --registry=https://bazel.clice.io/
common --registry=https://bcr.bazel.build/

Then depend on xclang in MODULE.bazel:

python
bazel_dep(name = "xclang", version = "23.1.2.8")

The version is the oldest release the project takes: Bazel uses the newest one that a module of the build asks for. The module downloads the host archive by the sha256 that its release pins, and registers it as the C++ toolchain for every target. The whole project is in Bazel.

Check It Works ​

clang++ --version, from PATH or from the toolchain directory, prints the clang version and InstalledDir, the bin/ it runs from:

sh
pixi run clang++ --version

xclang --version names the release, tagged <llvm version>.<revision> (versions). What each release changed is in the CHANGELOG.

Next ​