Skip to content
Merged
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
87 changes: 25 additions & 62 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,9 @@ bazel_dep(name = "score_rust_policies", version = "0.0.2")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "flatbuffers", version = "25.9.23")
bazel_dep(name = "download_utils", version = "1.2.2")
bazel_dep(name = "trlc", version = "3.0.0")
bazel_dep(name = "trlc", version = "3.0.1")
bazel_dep(name = "lobster", version = "1.0.6")
bazel_dep(name = "rules_distroless", version = "0.8.0")

# The released 0.8.0 only supports the old manifest/lock apt.install() API.
# apt.sysroot() (needed for the hermetic libclang sysroot below, and for the
# docs_runtime dependency_set API) is only available on this fork, which is
# also what eclipse-score-communication2 overrides to (see its
# third_party/score_tooling/bump_rules_distroless_api.patch, which exists
# specifically to migrate *this* module's old-API usage to match this fork
# when score_tooling is a non-root dependency).
git_override(
module_name = "rules_distroless",
commit = "e1df344fde5adaef7397c34076b56f27771d08b8",
remote = "https://github.com/LittleHuba/rules_distroless.git",
)

bazel_dep(name = "googletest", version = "1.17.0.bcr.2")

bazel_dep(name = "toolchains_llvm", version = "1.8.0", dev_dependency = True) # Libclang Tooling
Expand Down Expand Up @@ -299,7 +285,7 @@ multitool.hub(
hub_name = "actionlint_hub",
lockfile = "tools/actionlint.lock.json",
)
use_repo(multitool, "actionlint_hub")
use_repo(multitool, "actionlint_hub", "multitool")

register_toolchains("@actionlint_hub//toolchains:all")

Expand All @@ -317,72 +303,49 @@ deb(
###############################################################################
# Hermetic apt packages (docs_runtime sysroot + LLVM toolchain sysroot)
#
# Pinned to the Ubuntu 24.04 (noble) snapshot so the package closure is
# reproducible. Both dependency sets below share this one sources_list.
# Both use the upstream (BCR-published) rules_distroless manifest/lock API --
# no fork/override needed. Pinned to the Ubuntu 24.04 (noble) snapshot in each
# manifest.yaml so the package closure is reproducible.
###############################################################################
# bsdtar (used by //bazel/rules/exec_in_sysroot to extract sysroot archives).
bazel_dep(name = "tar.bzl", version = "0.6.0")

apt = use_extension("@rules_distroless//apt:extensions.bzl", "apt")
apt.sources_list(
architectures = ["amd64"],
components = [
"main",
"universe",
],
suites = [
"noble",
"noble-security",
"noble-updates",
],
types = ["deb"],
uris = ["https://snapshot.ubuntu.com/ubuntu/20260401T104001Z"],
)

# Distroless rootfs providing graphviz + fakechroot for hermetic dot execution
# via //third_party/docs_runtime:dot (exec_in_sysroot).
apt.install(
dependency_set = "docs_runtime",
packages = [
"base-files",
"fakechroot", # /usr/bin/fakechroot + libfakechroot.so for exec_in_sysroot
"graphviz", # /usr/bin/dot and plugins used by Sphinx + PlantUML
],
suites = [
"noble",
"noble-security",
"noble-updates",
],
name = "docs_runtime",
manifest = "//third_party/docs_runtime:manifest.yaml",
nolock = True,
)
use_repo(apt, "docs_runtime")

# Hermetic sysroot for the LLVM toolchain (see cpp/libclang), so that
# cpp_parser's cc_common-derived flags (and any normal C++ compile using this
# toolchain) resolve libc/libstdc++ headers from a pinned rootfs instead of the
# build host, matching eclipse-score-communication2's ubuntu24_04_sysroot setup.
apt.install(
dependency_set = "tooling_sysroot",
packages = [
"base-files",
"libatomic1", # Non-lock-free atomics support
"libc6", # Core C/POSIX
"libc6-dev", # Core C/POSIX
"libgcc-s1", # Exception unwinding
"libstdc++-13-dev", # C++ standard library headers
"libstdc++6", # C++ standard library runtime
"linux-libc-dev", # Core C/POSIX
],
suites = [
"noble",
"noble-security",
"noble-updates",
],
name = "tooling_sysroot",
manifest = "//third_party/tooling_sysroot:manifest.yaml",
nolock = True,
)
apt.sysroot(
use_repo(apt, "tooling_sysroot", "tooling_sysroot_resolve")

# Unpacks the tooling_sysroot lockfile's packages into a flat, fetch-time
# sysroot directory -- our own replacement for the LittleHuba fork's fork-only
# apt.sysroot(), so no rules_distroless override is needed (see
# //bazel/rules/sysroot_from_lock:sysroot_from_lock.bzl for attribution).
sysroot_from_lock = use_repo_rule(
"//bazel/rules/sysroot_from_lock:sysroot_from_lock.bzl",
"sysroot_from_lock",
)

sysroot_from_lock(
name = "tooling_sysroot_amd64",
architecture = "amd64",
dependency_set = "tooling_sysroot",
lock = "@tooling_sysroot_resolve//:lock.json",
)
use_repo(apt, "docs_runtime", "tooling_sysroot_amd64")

register_toolchains(
"//bazel/rules/rules_score:sphinx_default_toolchain",
Expand Down
15 changes: 0 additions & 15 deletions bazel/rules/rules_score/examples/integrator/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,6 @@ local_path_override(
path = "../some_other_library",
)

# score_tooling's own git_override for rules_distroless (needed for
# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic
# libclang sysroot) is only honored when score_tooling is the root module.
# Since score_tooling is merely a transitive dependency here, this module
# must repeat the override, or the registry rules_distroless 0.8.0 (which
# lacks those tag classes) is used instead and score_tooling's own
# MODULE.bazel fails to load with "does not have a tag class named
# sources_list".
bazel_dep(name = "rules_distroless", version = "0.8.0")
git_override(
module_name = "rules_distroless",
commit = "e1df344fde5adaef7397c34076b56f27771d08b8",
remote = "https://github.com/LittleHuba/rules_distroless.git",
)

bazel_dep(name = "trlc", version = "3.0.0")
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
bazel_dep(name = "lobster", version = "1.0.4")
Expand Down
15 changes: 0 additions & 15 deletions bazel/rules/rules_score/examples/minimal/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,6 @@ local_path_override(
path = "../../../../..",
)

# score_tooling's own git_override for rules_distroless (needed for
# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic
# libclang sysroot) is only honored when score_tooling is the root module.
# Since score_tooling is merely a transitive dependency here, this module
# must repeat the override, or the registry rules_distroless 0.8.0 (which
# lacks those tag classes) is used instead and score_tooling's own
# MODULE.bazel fails to load with "does not have a tag class named
# sources_list".
bazel_dep(name = "rules_distroless", version = "0.8.0")
git_override(
module_name = "rules_distroless",
commit = "e1df344fde5adaef7397c34076b56f27771d08b8",
remote = "https://github.com/LittleHuba/rules_distroless.git",
)

bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True)

llvm = use_extension(
Expand Down
15 changes: 0 additions & 15 deletions bazel/rules/rules_score/examples/seooc/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,6 @@ local_path_override(
path = "../some_other_library",
)

# score_tooling's own git_override for rules_distroless (needed for
# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic
# libclang sysroot) is only honored when score_tooling is the root module.
# Since score_tooling is merely a transitive dependency here, this module
# must repeat the override, or the registry rules_distroless 0.8.0 (which
# lacks those tag classes) is used instead and score_tooling's own
# MODULE.bazel fails to load with "does not have a tag class named
# sources_list".
bazel_dep(name = "rules_distroless", version = "0.8.0")
git_override(
module_name = "rules_distroless",
commit = "e1df344fde5adaef7397c34076b56f27771d08b8",
remote = "https://github.com/LittleHuba/rules_distroless.git",
)

# Some other llvm toolchain
bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,6 @@ local_path_override(
path = "../../../../../",
)

# score_tooling's own git_override for rules_distroless (needed for
# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic
# libclang sysroot) is only honored when score_tooling is the root module.
# Since score_tooling is merely a transitive dependency here, this module
# must repeat the override, or the registry rules_distroless 0.8.0 (which
# lacks those tag classes) is used instead and score_tooling's own
# MODULE.bazel fails to load with "does not have a tag class named
# sources_list".
bazel_dep(name = "rules_distroless", version = "0.8.0")
git_override(
module_name = "rules_distroless",
commit = "e1df344fde5adaef7397c34076b56f27771d08b8",
remote = "https://github.com/LittleHuba/rules_distroless.git",
)

# Some other llvm toolchain
bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True)

Expand Down
15 changes: 0 additions & 15 deletions bazel/rules/rules_score/test/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,6 @@ local_path_override(
path = "../../../..",
)

# score_tooling's own git_override for rules_distroless (needed for
# apt.sources_list()/apt.sysroot()/dependency_set, used by its hermetic
# libclang sysroot) is only honored when score_tooling is the root module.
# Since score_tooling is merely a transitive dependency here, this module
# must repeat the override, or the registry rules_distroless 0.8.0 (which
# lacks those tag classes) is used instead and score_tooling's own
# MODULE.bazel fails to load with "does not have a tag class named
# sources_list".
bazel_dep(name = "rules_distroless", version = "0.8.0")
git_override(
module_name = "rules_distroless",
commit = "e1df344fde5adaef7397c34076b56f27771d08b8",
remote = "https://github.com/LittleHuba/rules_distroless.git",
)

register_toolchains(
"//:score_toolchain",
)
Expand Down
14 changes: 14 additions & 0 deletions bazel/rules/sysroot_from_lock/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# *******************************************************************************
# 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
# *******************************************************************************

exports_files(["sysroot_from_lock.bzl"])
117 changes: 117 additions & 0 deletions bazel/rules/sysroot_from_lock/sysroot_from_lock.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# *******************************************************************************
# 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 unpack logic in this file (_materialize_deb_data_into_root, _unpack) is
# adapted from `apt/private/sysroot_repository.bzl` in
# https://github.com/LittleHuba/rules_distroless (commit
# e1df344fde5adaef7397c34076b56f27771d08b8), which is licensed under the
# Apache License, Version 2.0 (https://github.com/LittleHuba/rules_distroless
# has no per-file copyright headers; the repository's LICENSE file is
# Apache-2.0). It has been reworked to consume a plain rules_distroless
# `apt.install()` lockfile (as produced by the upstream, BCR-published
# rules_distroless, without requiring that fork's fork-only `apt.sysroot()`
# extension or its `dependency_set`-keyed lockfile format), so this repo needs
# no `rules_distroless` override.

"""Repository rule that unpacks a rules_distroless apt.install() lockfile's
packages into a flat, fetch-time sysroot directory, for use as a C/C++
toolchain sysroot (e.g. toolchains_llvm's `llvm.sysroot(label = ...)`)."""

_BUILD_TMPL = """\
"Generated by sysroot_from_lock. DO NOT EDIT."

filegroup(
name = "sysroot",
srcs = ["."],
visibility = ["//visibility:public"],
)
"""

def _materialize_deb_data_into_root(rctx, deb_path, ar_dir, unpack_dir):
"""Unpacks the data.tar.* payload of a .deb archive into unpack_dir.

This relies exclusively on Bazel's built-in support for extracting the
`ar` container format used by .deb files, and the nested `tar.*` payload,
via repository_ctx.extract().
"""

# .deb files are `ar` archives containing debian-binary, control.tar.* and
# data.tar.* members. Extracting unpacks those members as plain,
# uncompressed files (the ".deb" extension is auto-detected as ar).
rctx.extract(archive = deb_path, output = ar_dir)

data_member = None
for entry in rctx.path(ar_dir).readdir():
if entry.basename.startswith("data.tar"):
data_member = entry
break

if data_member == None:
fail("No data archive found in {}".format(deb_path))

# The archive type (tar.gz/tar.xz/tar.zst/...) is auto-detected from the
# data_member's file extension.
rctx.extract(archive = data_member, output = unpack_dir)

def _unpack(rctx, packages, architecture):
unpack_dir = "sysroot"
work_dir = ".unpack_work"

for package in packages:
if package["arch"] not in (architecture, "all"):
continue

key = package["key"]
deb_path = "{}/{}.deb".format(work_dir, key)
ar_dir = "{}/{}.ar".format(work_dir, key)

rctx.download(
output = deb_path,
sha256 = package["sha256"],
url = package["urls"],
)

_materialize_deb_data_into_root(rctx, deb_path, ar_dir, unpack_dir)

rctx.delete(work_dir)

def _sysroot_from_lock_impl(rctx):
lock = json.decode(rctx.read(rctx.attr.lock))
if lock["version"] != 1:
fail("invalid lockfile version")

_unpack(rctx, lock["packages"], rctx.attr.architecture)

rctx.file("sysroot/BUILD.bazel", _BUILD_TMPL)

sysroot_from_lock = repository_rule(
implementation = _sysroot_from_lock_impl,
attrs = {
"lock": attr.label(
mandatory = True,
doc = "Label of a rules_distroless apt.install() lockfile's " +
"generated lock.json file, e.g. " +
"'@<name>_resolve//:lock.json'.",
),
"architecture": attr.string(
mandatory = True,
doc = "Debian architecture (e.g. 'amd64') to unpack packages " +
"for; packages for other architectures in the lockfile " +
"are skipped. Packages with arch 'all' are always " +
"included.",
),
},
doc = "Unpacks a rules_distroless apt.install() lockfile's packages " +
"for a single architecture into a flat, fetch-time sysroot " +
"directory, exposed as a `:sysroot` filegroup.",
)
4 changes: 2 additions & 2 deletions third_party/docs_runtime/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
# *******************************************************************************

# Hermetic doc-tool runtime rootfs. The @docs_runtime repo (rules_distroless
# apt.install(dependency_set = "docs_runtime", ...)) is defined in
# //MODULE.bazel, which lists the pinned packages directly.
# apt.install(name = "docs_runtime", ...)) is defined in //MODULE.bazel;
# pinned packages are listed in manifest.yaml in this package.

load("//bazel/rules/exec_in_sysroot:exec_in_sysroot.bzl", "exec_in_sysroot", "prepare_sysroot")

Expand Down
Loading
Loading