Make cc_grpc_library compatible with native proto_library and cc_proto_library rules.
This is needed to comply with bazel best practices (each proto file is first processed by proto_library: https://docs.bazel.build/versions/master/be/protocol-buffer.html#proto_library) and generally bring cc_grcp_library rule up to date with latest Bazel changes (the rule hasn't gotten much updates since 2016). Detailed description. Bazel has native `cc_proto_library` rule, but it does not have `cc_grpc_library`. The rule in cc_grpc_library in this repo seems like the best candidate. This change makes possible using `cc_grpc_library` to generate on grpc library, and consume protobuf protion as dependencies. The typical `BUILD.bazel` file configuraiton now should look like the following: ```python proto_library( name = "my_proto", srcs = ["my.proto"], ) cc_proto_library( name = "my_cc_proto", deps = [":my_proto"] ) cc_grpc_library( name = "my_cc_grpc", srcs = [":my_proto"], deps = [":my_cc_proto"] ) ``` This allows to decouple all thre phases: proto descriptors generation (`proto_library`), protobuf messages library creation (`cc_proto_library`), grpc library creatio (`cc_grpc_library`). Notice how `cc_grpc_library` depends on `proto_library` (as `src`) and on `cc_proto_library` (as `deps`). Currently cc_grpc_library is designed in a way that it encapsulates all of the above and directly accepts .proto files as srcs. The previous version (before this PR) of cc_proto_library was encapsulating all of the 3 phases inside single `cc_proto_library` and also was doing it manually (without relying on the native `cc_proto_library`). The `cc_proto_library` is kept backward-compatible with the old version.
This commit is contained in:
parent
e3c80dc35f
commit
4269ce08f4
12
bazel/BUILD
12
bazel/BUILD
|
|
@ -17,15 +17,3 @@ licenses(["notice"]) # Apache v2
|
|||
package(default_visibility = ["//:__subpackages__"])
|
||||
|
||||
load(":cc_grpc_library.bzl", "cc_grpc_library")
|
||||
|
||||
proto_library(
|
||||
name = "well_known_protos_list",
|
||||
srcs = ["@com_google_protobuf//:well_known_protos"],
|
||||
)
|
||||
|
||||
cc_grpc_library(
|
||||
name = "well_known_protos",
|
||||
srcs = "well_known_protos_list",
|
||||
proto_only = True,
|
||||
deps = [],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,70 +2,94 @@
|
|||
|
||||
load("//bazel:generate_cc.bzl", "generate_cc")
|
||||
|
||||
def cc_grpc_library(name, srcs, deps, proto_only, well_known_protos, generate_mocks = False, use_external = False, **kwargs):
|
||||
"""Generates C++ grpc classes from a .proto file.
|
||||
def cc_grpc_library(
|
||||
name,
|
||||
srcs,
|
||||
deps,
|
||||
proto_only = False,
|
||||
well_known_protos = True,
|
||||
generate_mocks = False,
|
||||
use_external = False,
|
||||
grpc_only = False,
|
||||
**kwargs):
|
||||
"""Generates C++ grpc classes for services defined in a proto file.
|
||||
|
||||
Assumes the generated classes will be used in cc_api_version = 2.
|
||||
If grpc_only is True, this rule is compatible with proto_library and
|
||||
cc_proto_library native rules such that it expects proto_library target
|
||||
as srcs argument and generates only grpc library classes, expecting
|
||||
protobuf messages classes library (cc_proto_library target) to be passed in
|
||||
deps argument. By default grpc_only is False which makes this rule to behave
|
||||
in a backwards-compatible mode (trying to generate both proto and grpc
|
||||
classes).
|
||||
|
||||
Arguments:
|
||||
name: name of rule.
|
||||
srcs: a single proto_library, which wraps the .proto files with services.
|
||||
deps: a list of C++ proto_library (or cc_proto_library) which provides
|
||||
the compiled code of any message that the services depend on.
|
||||
well_known_protos: Should this library additionally depend on well known
|
||||
protos
|
||||
use_external: When True the grpc deps are prefixed with //external. This
|
||||
allows grpc to be used as a dependency in other bazel projects.
|
||||
generate_mocks: When True, Google Mock code for client stub is generated.
|
||||
**kwargs: rest of arguments, e.g., compatible_with and visibility.
|
||||
"""
|
||||
if len(srcs) > 1:
|
||||
fail("Only one srcs value supported", "srcs")
|
||||
Assumes the generated classes will be used in cc_api_version = 2.
|
||||
|
||||
proto_target = "_" + name + "_only"
|
||||
codegen_target = "_" + name + "_codegen"
|
||||
codegen_grpc_target = "_" + name + "_grpc_codegen"
|
||||
proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(':') == -1]
|
||||
proto_deps += [dep.split(':')[0] + ':' + "_" + dep.split(':')[1] + "_only" for dep in deps if dep.find(':') != -1]
|
||||
Args:
|
||||
name (str): Name of rule.
|
||||
srcs (list): A single .proto file which contains services definitions,
|
||||
or if grpc_only parameter is True, a single proto_library which
|
||||
contains services descriptors.
|
||||
deps (list): A list of C++ proto_library (or cc_proto_library) which
|
||||
provides the compiled code of any message that the services depend on.
|
||||
proto_only (bool): If True, create only C++ proto classes library,
|
||||
avoid creating C++ grpc classes library (expect it in deps).
|
||||
well_known_protos (bool): Should this library additionally depend on
|
||||
well known protos.
|
||||
generate_mocks: when True, Google Mock code for client stub is generated.
|
||||
use_external: Not used.
|
||||
grpc_only: if True, generate only grpc library, expecting protobuf
|
||||
messages library (cc_proto_library target) to be passed as deps.
|
||||
**kwargs: rest of arguments, e.g., compatible_with and visibility
|
||||
"""
|
||||
if len(srcs) > 1:
|
||||
fail("Only one srcs value supported", "srcs")
|
||||
if grpc_only and proto_only:
|
||||
fail("A mutualy exclusive configuraiton is specified: grpc_only = True and proto_only = True")
|
||||
|
||||
native.proto_library(
|
||||
name = proto_target,
|
||||
srcs = srcs,
|
||||
deps = proto_deps,
|
||||
**kwargs
|
||||
)
|
||||
extra_deps = []
|
||||
|
||||
generate_cc(
|
||||
name = codegen_target,
|
||||
srcs = [proto_target],
|
||||
well_known_protos = well_known_protos,
|
||||
**kwargs
|
||||
)
|
||||
if not grpc_only:
|
||||
proto_target = "_" + name + "_only"
|
||||
cc_proto_target = name if proto_only else "_" + name + "_cc_proto"
|
||||
|
||||
if not proto_only:
|
||||
plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin"
|
||||
generate_cc(
|
||||
name = codegen_grpc_target,
|
||||
srcs = [proto_target],
|
||||
plugin = plugin,
|
||||
well_known_protos = well_known_protos,
|
||||
generate_mocks = generate_mocks,
|
||||
**kwargs
|
||||
)
|
||||
grpc_deps = ["@com_github_grpc_grpc//:grpc++_codegen_proto",
|
||||
"//external:protobuf"]
|
||||
native.cc_library(
|
||||
name = name,
|
||||
srcs = [":" + codegen_grpc_target, ":" + codegen_target],
|
||||
hdrs = [":" + codegen_grpc_target, ":" + codegen_target],
|
||||
deps = deps + grpc_deps,
|
||||
**kwargs
|
||||
)
|
||||
else:
|
||||
native.cc_library(
|
||||
name = name,
|
||||
srcs = [":" + codegen_target],
|
||||
hdrs = [":" + codegen_target],
|
||||
deps = deps + ["//external:protobuf"],
|
||||
**kwargs
|
||||
)
|
||||
proto_deps = ["_" + dep + "_only" for dep in deps if dep.find(":") == -1]
|
||||
proto_deps += [dep.split(":")[0] + ":" + "_" + dep.split(":")[1] + "_only" for dep in deps if dep.find(":") != -1]
|
||||
|
||||
native.proto_library(
|
||||
name = proto_target,
|
||||
srcs = srcs,
|
||||
deps = proto_deps,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
native.cc_proto_library(
|
||||
name = cc_proto_target,
|
||||
deps = [":" + proto_target],
|
||||
**kwargs
|
||||
)
|
||||
extra_deps.append(":" + cc_proto_target)
|
||||
else:
|
||||
if not srcs:
|
||||
fail("srcs cannot be empty", "srcs")
|
||||
proto_target = srcs[0]
|
||||
|
||||
if not proto_only:
|
||||
codegen_grpc_target = "_" + name + "_grpc_codegen"
|
||||
generate_cc(
|
||||
name = codegen_grpc_target,
|
||||
srcs = [proto_target],
|
||||
plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin",
|
||||
well_known_protos = well_known_protos,
|
||||
generate_mocks = generate_mocks,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
native.cc_library(
|
||||
name = name,
|
||||
srcs = [":" + codegen_grpc_target],
|
||||
hdrs = [":" + codegen_grpc_target],
|
||||
deps = deps +
|
||||
extra_deps +
|
||||
["@com_github_grpc_grpc//:grpc++_codegen_proto"],
|
||||
**kwargs
|
||||
)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package(default_visibility = ["//visibility:public"])
|
|||
|
||||
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
|
||||
load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
|
||||
load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
|
||||
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library")
|
||||
|
||||
grpc_proto_library(
|
||||
|
|
@ -30,11 +31,25 @@ grpc_proto_library(
|
|||
srcs = ["protos/hellostreamingworld.proto"],
|
||||
)
|
||||
|
||||
grpc_proto_library(
|
||||
name = "helloworld",
|
||||
# The following three rules demonstrate the usage of the cc_grpc_library rule in
|
||||
# in a mode compatible with the native proto_library and cc_proto_library rules.
|
||||
proto_library(
|
||||
name = "helloworld_proto",
|
||||
srcs = ["protos/helloworld.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "helloworld_cc_proto",
|
||||
deps = [":helloworld_proto"],
|
||||
)
|
||||
|
||||
cc_grpc_library(
|
||||
name = "helloworld_cc_grpc",
|
||||
srcs = [":helloworld_proto"],
|
||||
grpc_only = True,
|
||||
deps = [":helloworld_cc_proto"],
|
||||
)
|
||||
|
||||
grpc_proto_library(
|
||||
name = "route_guide",
|
||||
srcs = ["protos/route_guide.proto"],
|
||||
|
|
@ -49,7 +64,7 @@ py_proto_library(
|
|||
name = "py_helloworld",
|
||||
protos = ["protos/helloworld.proto"],
|
||||
with_grpc = True,
|
||||
deps = [requirement('protobuf'),],
|
||||
deps = [requirement("protobuf")],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
|
|
@ -164,8 +179,10 @@ cc_binary(
|
|||
|
||||
cc_binary(
|
||||
name = "keyvaluestore_client",
|
||||
srcs = ["cpp/keyvaluestore/caching_interceptor.h",
|
||||
"cpp/keyvaluestore/client.cc"],
|
||||
srcs = [
|
||||
"cpp/keyvaluestore/caching_interceptor.h",
|
||||
"cpp/keyvaluestore/client.cc",
|
||||
],
|
||||
defines = ["BAZEL_BUILD"],
|
||||
deps = [
|
||||
":keyvaluestore",
|
||||
|
|
|
|||
Loading…
Reference in New Issue