Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,58 @@ use_repo(
"score_qcc_x86_64_toolchain_pkg",
)

# LLVM toolchain (used for clang-format and clang-tidy)
# `toolchains_llvm` supplies Bazel rules that describe an LLVM installation as
# a collection of Bazel toolchains (C++, clang-format, clang-tidy, and so on).
# Declaring this dependency does not download LLVM or make Clang the C++
# compiler by itself.
bazel_dep(name = "toolchains_llvm", version = "1.4.0", dev_dependency = True)

# Load the module extension that creates LLVM toolchain repositories. `llvm`
# is the extension instance used by the calls below; it is not the compiler.
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True)

# Ask the extension to create toolchain definitions for LLVM 19.1.0. These
# definitions refer to an LLVM distribution, which is supplied below.
llvm.toolchain(
# The version must also be present in `_LLVM_DISTRIBUTIONS` in
# `fast_llvm_repo.bzl`.
llvm_version = "19.1.1",
# Use the operating system's libstdc++ headers and libraries when this
# toolchain compiles for Linux x86-64, rather than LLVM's libc++.
stdlib = {"linux-x86_64": "stdc++"},
)

# Make the repository generated by the extension addressable as
# `@llvm_toolchain`. This exposes LLVM tools to Bazel rules, but does not
# register it as the C++ compiler.
use_repo(llvm, "llvm_toolchain")

# Load our repository rule. It downloads and unpacks LLVM directly from the
# upstream release archive, avoiding the slower default distribution download.
fast_llvm_repo = use_repo_rule("//:fast_llvm_repo.bzl", "fast_llvm_repo")

# Run that repository rule to create `@llvm_dist`, the local external
# repository containing the unpacked LLVM 19.1.0 distribution.
fast_llvm_repo(
# The external repository name referred to by `toolchain_root` below.
name = "llvm_dist",
# Select the URL and checksum entry in `_LLVM_DISTRIBUTIONS`.
llvm_version = "19.1.1",
)

# Tell the LLVM extension that its toolchain definitions must use our
# downloaded distribution as their compiler/tool root. This makes the
# download available to clang-format and clang-tidy, but still does not change
# which C++ compiler `bazel build` selects.
llvm.toolchain_root(label = "@llvm_dist//:root")

# Registering these toolchains is the opt-in switch that lets Bazel choose
# Clang for C++ compilation. Leave this disabled to keep the existing
# GCC/default C++ toolchain while still using the downloaded LLVM tools above.
# Enabling it can expose Clang-specific warnings; project-wide `-Werror` then
# turns those warnings into build failures.
# register_toolchains("@llvm_toolchain//:all")

# UTs on QNX
bazel_dep(name = "score_qnx_unit_tests", version = "0.2.0", dev_dependency = True)
bazel_dep(name = "score_rules_imagefs", version = "0.0.4", dev_dependency = True)
Expand Down
465 changes: 227 additions & 238 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions fast_llvm_repo.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

# The supported LLVM releases. Each entry maps a requested version to the
# upstream archive Bazel downloads and the checksum used to verify it.
_LLVM_DISTRIBUTIONS = {
"19.1.0": {
# Official prebuilt LLVM package for 64-bit Linux hosts.
"url": "https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.0/LLVM-19.1.0-Linux-X64.tar.xz",
# SHA-256 of that archive. `ctx.download` rejects altered or corrupt
# downloads instead of unpacking them.
"sha256": "cee77d641690466a193d9b88c89705de1c02bbad46bde6a3b126793c0a0f2923",
},
"19.1.1": {
# Official prebuilt LLVM package for 64-bit Linux hosts.
"url": "https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.1/LLVM-19.1.1-Linux-X64.tar.xz",
# SHA-256 pinned by toolchains_llvm for this exact upstream archive.
"sha256": "8204de000b6a6921f0572e038336601e3225898e9a253c8aaa43b0a5fae8a4ce",
},
}

# Implementation of `fast_llvm_repo`. Repository rules run while Bazel is
# preparing external dependencies, before analysing or building project code.
def _fast_llvm_repo_impl(ctx):
# Look up the requested release in the table above.
dist = _LLVM_DISTRIBUTIONS.get(ctx.attr.llvm_version)

# Fail with a useful message if MODULE.bazel asks for a version that has no
# URL and checksum entry yet.
if not dist:
fail("Unsupported LLVM version: %s" % ctx.attr.llvm_version)

# Choose a temporary file inside this external repository for the archive.
archive = ctx.path("llvm.tar.xz")

# Download the archive and verify its SHA-256 before using it.
ctx.download(
url = dist["url"],
output = archive,
sha256 = dist["sha256"],
)

# Use the host's `tar` executable to unpack the xz archive. `ctx.which`
# returns None instead of guessing when `tar` is unavailable.
tar = ctx.which("tar")
if not tar:
fail("tar not found in PATH")

# Unpack the distribution into the root of this external repository.
# `--strip-components=1` removes LLVM's top-level directory so paths such
# as `bin/clang` are directly under `@llvm_dist`.
result = ctx.execute(
[
tar,
"-xf",
archive,
"--strip-components=1",
# Extract into the external repository represented by `ctx`.
"-C",
ctx.path("."),
],
# Allow the relatively large archive up to 30 minutes to unpack.
timeout = 1800,
# Do not suppress `tar` output from Bazel's repository-rule log.
quiet = False,
)

# Stop repository creation if `tar` reported an extraction error.
if result.return_code:
fail(result.stderr)

# The archive is no longer needed after extraction; leave only the LLVM
# distribution files in the external repository.
ctx.delete(archive)

# Generate the BUILD file expected by `toolchains_llvm`. It exposes the
# unpacked distribution through the `@llvm_dist//:root` label used above.
ctx.template(
"BUILD.bazel",
Label("@toolchains_llvm//toolchain:BUILD.llvm_repo"),
)

# Public repository rule used from MODULE.bazel. Its only user-facing input
# is an LLVM version.
fast_llvm_repo = repository_rule(
implementation = _fast_llvm_repo_impl,
attrs = {
# Required version key used to select an entry in `_LLVM_DISTRIBUTIONS`.
"llvm_version": attr.string(mandatory = True),
# Reserved private template label. The implementation currently refers
# to the same label directly in `ctx.template` above, so this attribute
# has no effect; it documents the intended template dependency.
"_llvm_repo_build": attr.label(
default = Label("@toolchains_llvm//toolchain:BUILD.llvm_repo"),
),
},
)
Loading