| """Repository rule that relies on fetching a protoc binary from GitHub Releases. |
| |
| It exposes bin/protoc as a proto_toolchain. |
| """ |
| |
| load(":versions.bzl", "PROTOC_PLATFORMS", "PROTOC_VERSIONS") |
| |
| # TODO: we should read this dynamically by `ls *.proto` and then search for "import" statements |
| # inside the files. Currently this assumes the wkt srcs/deps are fixed over time. |
| GOOGLE_PROTOBUF_DEP_EDGES = { |
| "any": [], |
| "api": ["source_context", "type"], |
| "compiler/plugin": ["descriptor"], |
| "descriptor": [], |
| "duration": [], |
| "empty": [], |
| "field_mask": [], |
| "source_context": [], |
| "struct": [], |
| "timestamp": [], |
| "type": ["any", "source_context"], |
| "wrappers": [], |
| } |
| |
| def _prebuilt_protoc_repo_impl(rctx): |
| release_version = rctx.attr.version |
| if release_version == "LATEST": |
| release_version = PROTOC_VERSIONS.keys()[0] |
| |
| filename = "{}-{}-{}.zip".format( |
| "protoc", |
| release_version.removeprefix("v"), |
| rctx.attr.platform, |
| ) |
| url = "https://github.com/protocolbuffers/protobuf/releases/download/{}/{}".format( |
| release_version, |
| filename, |
| ) |
| rctx.download_and_extract( |
| url = url, |
| integrity = PROTOC_VERSIONS[release_version][filename], |
| ) |
| build_content = """\ |
| # Generated by @rules_proto//proto/toolchains:prebuilt_protoc_toolchain.bzl |
| load("@rules_proto//proto/private/rules:proto_toolchain_rule.bzl", "proto_toolchain") |
| |
| package(default_visibility=["//visibility:public"]) |
| |
| proto_toolchain( |
| name = "prebuilt_protoc_toolchain", |
| proto_compiler = "{protoc_label}", |
| visibility = ["//visibility:public"], |
| ) |
| """.format( |
| protoc_label = ":bin/protoc.exe" if rctx.attr.platform.startswith("win") else ":bin/protoc", |
| ) |
| |
| for src, deps in GOOGLE_PROTOBUF_DEP_EDGES.items(): |
| build_content += """\ |
| proto_library( |
| name = "{0}_proto", |
| srcs = ["include/google/protobuf/{0}.proto"], |
| deps = [":%s_proto" % dep for dep in {1}], |
| strip_import_prefix = "include", |
| ) |
| """.format(src, deps) |
| rctx.file("BUILD.bazel", build_content) |
| |
| prebuilt_protoc_repo = repository_rule( |
| doc = "Download a pre-built protoc and create a concrete toolchains for it", |
| implementation = _prebuilt_protoc_repo_impl, |
| attrs = { |
| "platform": attr.string( |
| doc = "A platform that protobuf ships a release for", |
| mandatory = True, |
| values = PROTOC_PLATFORMS.keys(), |
| ), |
| "version": attr.string( |
| doc = "Release tag from protocolbuffers/protobuf repo, e.g. 'v25.3'", |
| mandatory = True, |
| ), |
| }, |
| ) |