91 lines
3.5 KiB
Python
91 lines
3.5 KiB
Python
"""Create a repository to hold the toolchains
|
|
|
|
This follows guidance here:
|
|
https://docs.bazel.build/versions/main/skylark/deploying.html#registering-toolchains
|
|
"
|
|
Note that in order to resolve toolchains in the analysis phase
|
|
Bazel needs to analyze all toolchain targets that are registered.
|
|
Bazel will not need to analyze all targets referenced by toolchain.toolchain attribute.
|
|
If in order to register toolchains you need to perform complex computation in the repository,
|
|
consider splitting the repository with toolchain targets
|
|
from the repository with <LANG>_toolchain targets.
|
|
Former will be always fetched,
|
|
and the latter will only be fetched when user actually needs to build <LANG> code.
|
|
"
|
|
The "complex computation" in our case is simply downloading large artifacts.
|
|
This guidance tells us how to avoid that: we put the toolchain targets in the alias repository
|
|
with only the toolchain attribute pointing into the platform-specific repositories.
|
|
"""
|
|
|
|
# Add more platforms as needed to mirror all the binaries
|
|
# published by the upstream project.
|
|
|
|
DEFS_TMPL = """\
|
|
# Generated by source_toolchains_repo.bzl for {toolchain_type}
|
|
load("@bazel_skylib//lib:structs.bzl", "structs")
|
|
|
|
# Forward all the providers
|
|
def _resolved_toolchain_impl(ctx):
|
|
toolchain_info = ctx.toolchains["{toolchain_type}"]
|
|
return [toolchain_info] + structs.to_dict(toolchain_info).values()
|
|
|
|
# Copied from java_toolchain_alias
|
|
# https://cs.opensource.google/bazel/bazel/+/master:tools/jdk/java_toolchain_alias.bzl
|
|
resolved_toolchain = rule(
|
|
implementation = _resolved_toolchain_impl,
|
|
toolchains = ["{toolchain_type}"],
|
|
incompatible_use_toolchain_transition = True,
|
|
)
|
|
"""
|
|
|
|
BUILD_TMPL = """\
|
|
# Generated by source_toolchains_repo.bzl
|
|
#
|
|
# These can be registered in the workspace file or passed to --extra_toolchains flag.
|
|
# By default all of these toolchains are registered by the oci_register_toolchains macro
|
|
# so you don't normally need to interact with these targets.
|
|
|
|
load(":defs.bzl", "resolved_toolchain")
|
|
load("{toolchain_rule_load_from}", toolchain_rule = "{toolchain_rule}")
|
|
|
|
resolved_toolchain(name = "current_toolchain", visibility = ["//visibility:public"])
|
|
|
|
toolchain_rule(
|
|
name = "source",
|
|
bin = "{binary}",
|
|
visibility = ["//visibility:public"],
|
|
)
|
|
|
|
toolchain(
|
|
name = "toolchain",
|
|
toolchain = ":source",
|
|
toolchain_type = "{toolchain_type}",
|
|
)
|
|
"""
|
|
|
|
def _source_toolchains_repo_impl(rctx):
|
|
# Expose a concrete toolchain which is the result of Bazel resolving the toolchain
|
|
# for the execution or target platform.
|
|
# Workaround for https://github.com/bazelbuild/bazel/issues/14009
|
|
rctx.file("defs.bzl", DEFS_TMPL.format(
|
|
toolchain_type = rctx.attr.toolchain_type,
|
|
))
|
|
|
|
rctx.file("BUILD.bazel", BUILD_TMPL.format(
|
|
toolchain_type = rctx.attr.toolchain_type,
|
|
toolchain_rule_load_from = rctx.attr.toolchain_rule_load_from,
|
|
toolchain_rule = rctx.attr.toolchain_rule,
|
|
binary = rctx.attr.binary,
|
|
))
|
|
|
|
source_toolchains_repo = repository_rule(
|
|
_source_toolchains_repo_impl,
|
|
doc = "Creates a repository with toolchain definitions for source binaries.",
|
|
attrs = {
|
|
"toolchain_type": attr.string(doc = "Label to the toolchain_type", mandatory = True),
|
|
"toolchain_rule_load_from": attr.string(doc = "Label to the concrete toolchain rule to load from", mandatory = True),
|
|
"toolchain_rule": attr.string(doc = "Name of the concrete toolchain rule", mandatory = True),
|
|
"binary": attr.string(doc = "Label to the binary", mandatory = True),
|
|
},
|
|
)
|