Files
oh-my-pi/bazel/toolchains/msvc/llvm.bzl
T
can1357 8facd237d5 feat(build): migrated native pipeline to bazel with remote caching
- Replaced the napi-cli/cargo-zigbuild/cargo-xwin/sccache build path with
  Bazel: rules_rust + crate_universe over Cargo.lock, hermetic zig cc
  toolchains (linux-gnu pinned to glibc 2.17, linux-musl), host Xcode for
  darwin, and a repo-local hermetic clang-cl + llvm-ml + xwin toolchain for
  windows-msvc (bazel/toolchains/msvc).
- All eight shipped addons build as //:natives-<target> via the release
  transition in bazel/defs.bzl (opt, thin LTO, cgu=16, stripped, canonical
  .node naming); scripts/bazel-natives.ts is the single driver for local
  dev and CI.
- Rust validation moved to bazel test + clippy aspects (strict workspace
  policy for opted-in crates, default lints elsewhere, mirroring cargo
  semantics) and the rustfmt aspect; cargo stays as the dev-iteration
  surface, with brush-core/brush-builtins promoted to workspace members
  and excluded from cargo dev tasks to keep their historical scope.
- CI caches through an in-cluster bazel-remote action cache (TLS + basic
  auth, cluster-internal only); GitHub-hosted runners never touch the
  infrastructure and use an actions/cache-backed disk cache instead.
- Deleted the hand-rolled caching machinery: ci-target-cache,
  ci-native-artifact-cache, ci-build-native, native-source-hash,
  find-native-artifacts, restore-linux-native, native-prewarm workflow,
  ensure-* toolchain actions, and all sccache/Swatinem wiring.
- Warm native rebuilds drop from ~20 minutes to seconds; a cold client
  with a warm remote cache rebuilds the linux x64 pair in ~2.5 minutes.
2026-07-27 12:22:19 +02:00

127 lines
4.5 KiB
Python

"""Repository rule fetching the LLVM binaries used by the msvc cross toolchain.
Downloads the official LLVM release archive for the host that fetches the repo
(linux-x64 CI pods, darwin dev hosts) and prunes it down to the clang-cl /
lld-link / llvm-lib / llvm-rc slice plus the clang builtin headers
(lib/clang/<major>/include — immintrin.h & co, required for the SSE units in
bundled opus). The pruned tree is ~300 MiB instead of ~10 GiB.
The archive download (~1.5-2 GiB) goes through repository_ctx.download_and_extract
with a pinned sha256, so it lands in Bazel's content-addressed repository cache:
re-fetches after `bazel clean --expunge` or a .bzl edit only pay extraction.
Checksums are the official llvm-project release assets, cross-checked against
bazel-contrib/toolchains_llvm's distribution table.
"""
_LLVM_VERSION = "20.1.7"
# host key -> (release asset suffix, sha256)
_LLVM_DISTS = {
"linux-arm64": ("Linux-ARM64", "832f2802a29457dc758f56e26e98558c6cd0e45fcd07186f540cb6e7f4e59385"),
"linux-x64": ("Linux-X64", "8494c98a774051a40bfe1187a2d6442f4bc107598998bbe1673d9bb1572cfd6f"),
"macos-arm64": ("macOS-ARM64", "6aa75de00575ad0663183b00f00f39992ded611b5136e57649ace1e6a53c0d16"),
"macos-x64": ("macOS-X64", "ccf82ffe7e136ee49659cb57157856a7963d0950fac3d05aabba0db75bfba26f"),
}
# bin/ entries to keep. Symlink chains (clang-cl -> clang -> clang-20,
# llvm-lib -> llvm-ar, lld-link -> lld) are closed over at fetch time by
# resolving realpaths, so version-suffixed real binaries need no hardcoding.
_KEEP_BINS = [
"clang",
"clang-cl",
"lld",
"lld-link",
"llvm-ar",
"llvm-lib",
"llvm-ml",
"llvm-mt",
"llvm-rc",
]
def _host_key(rctx):
os_name = rctx.os.name.lower()
arch = rctx.os.arch.lower()
if os_name.startswith("linux"):
host_os = "linux"
elif os_name.startswith("mac") or os_name.startswith("darwin"):
host_os = "macos"
else:
fail("bazel/toolchains/msvc: unsupported exec host OS for the msvc cross toolchain: " + rctx.os.name)
if arch in ("amd64", "x86_64", "x64"):
host_cpu = "x64"
elif arch in ("aarch64", "arm64"):
host_cpu = "arm64"
else:
fail("bazel/toolchains/msvc: unsupported exec host CPU for the msvc cross toolchain: " + rctx.os.arch)
return host_os + "-" + host_cpu
_BUILD = """\
# Generated by //bazel/toolchains/msvc:llvm.bzl — pruned LLVM {version} for the
# msvc cross toolchain ({host} exec host). Consumed by @msvc_cc wrappers.
package(default_visibility = ["//visibility:public"])
filegroup(
name = "bin",
srcs = glob(["bin/*"]),
)
filegroup(
name = "builtin_headers",
srcs = glob(["lib/clang/*/include/**"]),
)
filegroup(
name = "all",
srcs = [
":bin",
":builtin_headers",
],
)
"""
def _llvm_msvc_tools_impl(rctx):
key = _host_key(rctx)
if key not in _LLVM_DISTS:
fail("bazel/toolchains/msvc: no pinned LLVM release archive for host " + key)
suffix, sha256 = _LLVM_DISTS[key]
prefix = "LLVM-{}-{}".format(_LLVM_VERSION, suffix)
rctx.report_progress("Downloading LLVM {} ({}, ~2 GiB, repository-cache backed)".format(_LLVM_VERSION, suffix))
rctx.download_and_extract(
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-{}/{}.tar.xz".format(_LLVM_VERSION, prefix),
sha256 = sha256,
stripPrefix = prefix,
)
# Close the keep-set over symlink targets, then prune bin/.
keep = {name: None for name in _KEEP_BINS}
bin_dir = rctx.path("bin")
for name in _KEEP_BINS:
tool = bin_dir.get_child(name)
if tool.exists:
keep[tool.realpath.basename] = None
for entry in bin_dir.readdir():
if entry.basename not in keep:
rctx.delete(entry)
# Prune everything outside bin/ and lib/clang/<ver>/include.
for entry in rctx.path(".").readdir():
if entry.basename not in ("bin", "lib"):
rctx.delete(entry)
lib_dir = rctx.path("lib")
for entry in lib_dir.readdir():
if entry.basename != "clang":
rctx.delete(entry)
for verdir in lib_dir.get_child("clang").readdir():
for entry in verdir.readdir():
if entry.basename != "include":
rctx.delete(entry)
rctx.file("BUILD.bazel", _BUILD.format(version = _LLVM_VERSION, host = key), executable = False)
llvm_msvc_tools_repository = repository_rule(
implementation = _llvm_msvc_tools_impl,
doc = "Pruned LLVM release binaries (clang-cl/lld-link/llvm-lib/llvm-rc) for the exec host.",
)