chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:29:29 +08:00
commit f52cf32e56
1718 changed files with 366293 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This BUILD file marks bazel/tools/ as a Bazel package so that loads
# of the form `//bazel/tools:xxx.bzl` are valid. The directory only
# hosts .bzl files (brpc_proto_library.bzl / proto_gen.bzl) and does
# not define any build targets.
package(default_visibility = ["//visibility:public"])
exports_files(glob(["*.bzl"]))
+138
View File
@@ -0,0 +1,138 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# brpc_proto_library: a proto -> cc_library macro that is robust against
# protobuf and Bazel version churn.
#
# Background:
# - Old protobuf (< 3.21) used to expose a `cc_proto_library` macro
# via `@com_google_protobuf//:protobuf.bzl`; newer protobuf removed
# that macro.
# - Newer protobuf expects callers to use Bazel's native
# `proto_library` / `cc_proto_library` (or the `cc_proto_library`
# re-exported from `@com_google_protobuf//bazel:cc_proto_library.bzl`),
# but older protobuf does not surface a complete `ProtoInfo`, so
# the native rules cannot build it.
# - Bazel 8 additionally removed `cc_proto_library` from
# `@rules_cc//cc:defs.bzl` (the load now resolves to a stub rule
# that fails analysis), forcing every caller to either load it
# from `@com_google_protobuf` or replace it.
# - Bazel's `load()` is static and cannot be conditional on the
# protobuf version, so a single brpc_proto_library.bzl cannot
# directly satisfy both old and new protobuf by switching imports.
#
# Solution (inspired by https://github.com/trpc-group/trpc-cpp/blob/a69d2950f4a9c16b3cb40a2750c69d8940c96820/trpc/trpc.bzl):
# We implement the proto compilation rule from scratch (see
# proto_gen.bzl in this directory). Dependency information is
# propagated through Bazel's native `ProtoInfo` provider, and the
# default well-known-proto source is
# `@com_google_protobuf//:descriptor_proto` -- a `proto_library`
# whose name has been stable across protobuf 3.x / 27.x / 34.x.
load("//bazel/tools:proto_gen.bzl", "brpc_proto_gen")
# `:descriptor_proto` is the protobuf repo's `proto_library` target;
# its label has been stable since protobuf 3.x. We consume it through
# Bazel's native `ProtoInfo` provider, which is uniform across PB
# versions. If a caller's .proto needs additional well-known protos
# (any.proto, timestamp.proto, ...), they can pass extra entries via
# the `proto_deps` argument.
_DEFAULT_PROTO_DEPS = ["@com_google_protobuf//:descriptor_proto"]
def brpc_proto_library(
name,
srcs,
deps = [],
include = None,
proto_deps = None,
visibility = None,
testonly = 0):
"""Generate a cc_library from a set of .proto files.
Args:
name: target name.
srcs: list of .proto files, paths relative to the current package.
deps: list of other `brpc_proto_library` targets this target
depends on. The macro internally translates these labels
to the underlying `<name>_genproto` rule so that .proto
include paths and sources propagate.
include: protoc `-I` root AND the resulting cc_library `includes`
root, relative to the current package.
When omitted, "" or None, the include root is the
current package itself (suitable for .proto files
sitting directly under the package root, as in `test/`
and `example/...`). The root `BUILD.bazel` of brpc must
pass `"src"` so that code can reference the protos as
`import "brpc/foo.proto"`.
proto_deps: list of native `proto_library` dependencies
(well-known protos or external .proto libraries).
Defaults to
`["@com_google_protobuf//:descriptor_proto"]`.
Pass `[]` explicitly to disable the default; pass
None (the default) to use it.
visibility: same semantics as cc_library.
testonly: same semantics as cc_library.
"""
real_include = include if include != None else ""
real_proto_deps = proto_deps if proto_deps != None else _DEFAULT_PROTO_DEPS
gen_name = name + "_genproto"
brpc_proto_gen(
name = gen_name,
srcs = srcs,
# Rewrite each `brpc_proto_library` dep to its underlying
# `<dep>_genproto` rule, which exports BrpcProtoInfo.
deps = [d + "_genproto" for d in deps],
include = real_include,
proto_deps = real_proto_deps,
visibility = visibility,
testonly = testonly,
)
# Split the generated files into .pb.h / .pb.cc via OutputGroupInfo
# and feed them to cc_library's hdrs / srcs separately. Bazel
# rejects declaring the same File in both hdrs and srcs, so a
# plain DefaultInfo wouldn't work here.
native.filegroup(
name = gen_name + "_hdrs",
srcs = [":" + gen_name],
output_group = "hdrs",
visibility = visibility,
testonly = testonly,
)
native.filegroup(
name = gen_name + "_srcs",
srcs = [":" + gen_name],
output_group = "srcs",
visibility = visibility,
testonly = testonly,
)
native.cc_library(
name = name,
srcs = [":" + gen_name + "_srcs"],
hdrs = [":" + gen_name + "_hdrs"],
# cc_library `includes` is required, otherwise the .pb.cc
# files inside this cc_library cannot find the .pb.h headers
# they just generated (the headers live under
# bazel-bin/<package>/<include>/...). When include="" we pass
# "." to mean "the current package itself"; Bazel then exposes
# both `-I <package>` and `-I bazel-bin/<package>`
# automatically to dependents.
includes = [real_include if real_include else "."],
deps = deps + ["@com_google_protobuf//:protobuf"],
visibility = visibility,
testonly = testonly,
)
+240
View File
@@ -0,0 +1,240 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# brpc's self-implemented proto -> .pb.{h,cc} compilation rule.
#
# Cross-protobuf-version compatibility strategy (inspired by trpc.bzl):
# 1) Do NOT load `@com_google_protobuf//:protobuf.bzl` and do NOT
# call `native.cc_proto_library` -- this side-steps the double
# incompatibility of newer protobuf removing the macro and older
# protobuf missing a complete `ProtoInfo` provider.
# 2) Do NOT hardcode any protobuf-repo-internal filegroup names
# (such as `well_known_protos` / `descriptor_proto_srcs`) -- the
# names of those filegroups have shifted between protobuf 3.x
# and 27.x+.
# 3) Propagate dependencies via Bazel's native `ProtoInfo` provider:
# callers pass `proto_library` targets through `proto_deps`
# (defaulting to `@com_google_protobuf//:descriptor_proto`, a
# `proto_library` whose label has been stable across PB versions),
# and this rule walks `transitive_sources` / `transitive_proto_path`
# to collect .proto source files and protoc `-I` paths -- fully
# decoupled from the PB version.
# 4) Among `brpc_proto_gen` targets themselves, dependencies are
# propagated via the custom `BrpcProtoInfo` provider declared
# below.
#
# Note on minimum Bazel version: this rule itself does not call any
# Bazel-version-specific API, but it still consumes `ProtoInfo` from
# `proto_library` targets (e.g. `descriptor_proto`) defined inside
# the protobuf repo. Protobuf >= 34 calls
# `ProtoInfo(option_deps = ..., extension_declarations = ...)` in its
# own `proto_library` implementation, and those fields are only
# accepted by Bazel >= 8. In other words, the minimum Bazel version
# brpc requires is whatever the bundled protobuf version requires --
# we just don't add any extra requirement on top of that.
BrpcProtoInfo = provider(
doc = "Carries transitive .proto sources and protoc -I flags between brpc_proto_gen targets.",
fields = {
"transitive_srcs": "depset of all transitive .proto Files.",
"transitive_imports": "depset of strings, all -I flags needed by protoc.",
},
)
def _resolve_include_dir(ctx):
"""Compute this target's protoc include root (workspace-relative).
Examples:
ctx.label.package = "" + include = "src" -> "src"
ctx.label.package = "test" + include = "" -> "test"
ctx.label.package = "" + include = "" -> "."
"""
pkg = ctx.label.package
inc = ctx.attr.include.rstrip("/")
if pkg and inc:
return pkg + "/" + inc
if pkg:
return pkg
if inc:
return inc
return "."
def _proto_gen_impl(ctx):
srcs = ctx.files.srcs
include_dir = _resolve_include_dir(ctx)
bin_root = ctx.bin_dir.path
# `-I` flags for this target itself: the source-tree root plus
# the corresponding bin-dir root. The bin-dir entry is needed
# when a transitive dep generates .proto files into bazel-bin
# (e.g. via a custom code generator).
own_imports = ["-I" + include_dir]
if include_dir == ".":
own_imports.append("-I" + bin_root)
else:
own_imports.append("-I" + bin_root + "/" + include_dir)
# Collect transitive info from other `brpc_proto_gen` deps.
dep_srcs_list = [d[BrpcProtoInfo].transitive_srcs for d in ctx.attr.deps]
dep_imports_list = [d[BrpcProtoInfo].transitive_imports for d in ctx.attr.deps]
# Collect native `proto_library` deps (well-known protos or
# external .proto libraries). Key design: .proto sources and
# `-I` paths are obtained via Bazel's native `ProtoInfo`,
# avoiding any reliance on protobuf-repo-internal filegroup
# names (descriptor_proto_srcs / well_known_protos / ...).
# `transitive_proto_path` already accounts for the
# `_virtual_imports` paths created by `strip_import_prefix`, so
# protoc can consume the paths directly.
#
# Important: `strip_import_prefix` causes .proto files to live at
# virtual paths under bazel-out/<config>/bin/<workspace_root>/<virtual>
# (see trpc.bzl for prior art). For every `proto_dep` repo we
# therefore expose FOUR candidate `-I` paths to be safe:
# 1) <workspace_root> -- source root (plain proto_library)
# 2) <bin_dir>/<workspace_root> -- virtual root after strip_import_prefix
# 3) <workspace_root>/src -- fallback for older PB descriptor_proto without strip
# 4) <bin_dir>/<workspace_root>/src -- same as #3, under bin-dir
# protoc only warns on non-existent `-I` paths, so this is harmless.
proto_dep_src_depsets = []
proto_dep_imports = []
extra_pb_root_imports = []
# Belt-and-suspenders: also feed each `proto_dep`'s default outputs
# (i.e. the .proto files themselves) into `inputs`, in case the
# ProtoInfo's transitive_sources does not cover everything we need.
proto_dep_src_depsets.append(depset(direct = ctx.files.proto_deps))
for pd in ctx.attr.proto_deps:
pi = pd[ProtoInfo]
proto_dep_src_depsets.append(pi.transitive_sources)
for path in pi.transitive_proto_path.to_list():
proto_dep_imports.append("-I" + path)
wsroot = pd.label.workspace_root
if wsroot:
extra_pb_root_imports.append("-I" + wsroot)
extra_pb_root_imports.append("-I" + bin_root + "/" + wsroot)
extra_pb_root_imports.append("-I" + wsroot + "/src")
extra_pb_root_imports.append("-I" + bin_root + "/" + wsroot + "/src")
# Deduplicate the workspace-level `-I` entries so the same repo
# is not listed multiple times when several proto_deps share it.
proto_dep_imports.extend(depset(extra_pb_root_imports).to_list())
all_imports = depset(
direct = own_imports + proto_dep_imports,
transitive = dep_imports_list,
)
# Output files: every .proto produces a .pb.h and a .pb.cc.
# NB: the `path` argument of `ctx.actions.declare_file(path)` is
# *relative to the current package*, while `src.short_path` is
# *relative to the workspace root*. The two differ by the package
# prefix; we must strip that prefix before calling declare_file,
# otherwise the outputs would land at
# bazel-bin/<pkg>/<pkg>/... (one level too deep).
pkg = ctx.label.package
pkg_prefix = pkg + "/" if pkg else ""
outs = []
for src in srcs:
if not src.short_path.endswith(".proto"):
fail("brpc_proto_gen srcs must be .proto, got: %s" % src.short_path)
rel = src.short_path
if pkg_prefix and rel.startswith(pkg_prefix):
rel = rel[len(pkg_prefix):]
base = rel[:-len(".proto")]
outs.append(ctx.actions.declare_file(base + ".pb.h"))
outs.append(ctx.actions.declare_file(base + ".pb.cc"))
# protoc's --cpp_out points at the include root under bin_root.
# After protoc organizes outputs by their import-relative path,
# the .pb.{h,cc} files land exactly where declare_file declared
# them above.
if include_dir == ".":
cpp_out_dir = bin_root
else:
cpp_out_dir = bin_root + "/" + include_dir
args = ctx.actions.args()
args.add_all(all_imports.to_list())
args.add("--cpp_out=" + cpp_out_dir)
args.add_all([s.path for s in srcs])
ctx.actions.run(
executable = ctx.executable.protoc,
arguments = [args],
inputs = depset(
direct = srcs,
transitive = dep_srcs_list + proto_dep_src_depsets,
),
outputs = outs,
mnemonic = "BrpcProtoCompile",
progress_message = "BrpcProtoCompile %s" % ctx.label,
)
hdr_files = [f for f in outs if f.path.endswith(".pb.h")]
src_files = [f for f in outs if f.path.endswith(".pb.cc")]
return [
DefaultInfo(files = depset(outs)),
# Split outputs so the brpc_proto_library macro can route
# them to cc_library.hdrs vs cc_library.srcs separately.
OutputGroupInfo(
hdrs = depset(hdr_files),
srcs = depset(src_files),
),
BrpcProtoInfo(
transitive_srcs = depset(direct = srcs, transitive = dep_srcs_list),
transitive_imports = all_imports,
),
]
brpc_proto_gen = rule(
implementation = _proto_gen_impl,
attrs = {
"srcs": attr.label_list(
allow_files = [".proto"],
mandatory = True,
),
# Other `brpc_proto_gen` targets; deps are propagated via the
# custom `BrpcProtoInfo` provider.
"deps": attr.label_list(
providers = [BrpcProtoInfo],
default = [],
),
# The include root, relative to the current BUILD package
# (e.g. "src" for the brpc root BUILD).
"include": attr.string(default = ""),
"protoc": attr.label(
default = Label("@com_google_protobuf//:protoc"),
executable = True,
# `"host"` is the legacy spelling of `"exec"`. Modern
# Bazel (>= 6) prefers `"exec"`, but still accepts
# `"host"` as an alias through at least Bazel 8.x. We
# keep `"host"` here for the broad range of Bazel
# versions used to build brpc; switch to `"exec"` once
# `"host"` is finally removed (likely a future major
# Bazel release).
cfg = "host",
allow_files = True,
),
# Native `proto_library` deps (well-known protos or external
# .proto libraries). .proto sources and -I paths are obtained
# automatically through Bazel's native `ProtoInfo`, fully
# decoupled from the protobuf version.
"proto_deps": attr.label_list(
providers = [ProtoInfo],
default = [],
),
},
)