pw_protobuf_compiler: Allow subset of sub-targets
Allow a `pw_proto_library` target to explicitly specify which
sub-targets should be enabled. This can prevent build failures in cases
where an unused sub-target conflicts with another target in the same
package.
Bugs: b/235132083, b/230487701
Change-Id: Ia9205ef1a3fa94c1033665be499cce84949a6f0e
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/96980
Commit-Queue: Matthias Guenther <mrguenther@google.com>
Reviewed-by: Ted Pudlik <tpudlik@google.com>
diff --git a/pw_protobuf_compiler/docs.rst b/pw_protobuf_compiler/docs.rst
index 48053d6..e1b6a7a 100644
--- a/pw_protobuf_compiler/docs.rst
+++ b/pw_protobuf_compiler/docs.rst
@@ -106,6 +106,14 @@
input files must be nested under this path.
* ``python_package``: Label of Python package to which to add the proto modules.
The .python subtarget will redirect to this package.
+* ``enabled_targets``: List of sub-targets to enable (see Supported Codegen),
+ e.g. ``["pwpb", "raw_rpc"]``. By default, all sub-targets are enabled. The
+ enabled sub-targets are built only as requested by the build system, but it
+ may be necessary to explicitly disable an unused sub-target if it conflicts
+ with another target in the same package. (For example, ``nanopb`` codegen can
+ conflict with the default C++ codegen provided by ``protoc``.)
+ TODO(b/235132083): Remove this argument once we've removed the file-name
+ conflict between nanopb and protoc code generators.
**Example**
diff --git a/pw_protobuf_compiler/pw_proto_library.bzl b/pw_protobuf_compiler/pw_proto_library.bzl
index 162df20..4a5de15 100644
--- a/pw_protobuf_compiler/pw_proto_library.bzl
+++ b/pw_protobuf_compiler/pw_proto_library.bzl
@@ -53,7 +53,11 @@
load("@rules_proto//proto:defs.bzl", "ProtoInfo")
load("//pw_protobuf_compiler:pw_nanopb_cc_library", "pw_nanopb_cc_library")
-def pw_proto_library(name = "", deps = [], nanopb_options = None):
+def pw_proto_library(
+ name = "",
+ deps = [],
+ nanopb_options = None,
+ enabled_targets = None):
"""Generate Pigweed proto C++ code.
This is the only public symbol in this file: everything else is
@@ -64,6 +68,13 @@
deps: proto_library targets from which to generate Pigweed C++.
nanopb_options: path to file containing nanopb options, if any
(https://jpa.kapsi.fi/nanopb/docs/reference.html#proto-file-options).
+ enabled_targets: Specifies which libraries should be generated. Libraries
+ will only be generated as needed, but unnecessary outputs may conflict
+ with other build rules and thus cause build failures. This filter allows
+ manual selection of which libraries should be supported by this build
+ target in order to prevent such conflicts. The argument, if provided,
+ should be a subset of ["pwpb", "nanopb", "raw_rpc", "nanopb_rpc"]. All
+ are enabled by default. Note that "nanopb_rpc" relies on "nanopb".
Example usage:
@@ -98,14 +109,23 @@
"benchmark.rpc.pb.h" header.
"""
- # Use nanopb to generate the pb.h and pb.c files, and the target exposing
- # them.
- pw_nanopb_cc_library(name + ".nanopb", deps, options = nanopb_options)
+ def is_plugin_enabled(plugin):
+ return (enabled_targets == None or plugin in enabled_targets)
+
+ if is_plugin_enabled("nanobp"):
+ # Use nanopb to generate the pb.h and pb.c files, and the target
+ # exposing them.
+ pw_nanopb_cc_library(name + ".nanopb", deps, options = nanopb_options)
# Use Pigweed proto plugins to generate the remaining files and targets.
for plugin_name, info in PIGWEED_PLUGIN.items():
+ if not is_plugin_enabled(plugin_name):
+ continue
+
name_pb = name + "_pb." + plugin_name
- info["compiler"](
+
+ plugin_rule = info["compiler"]
+ plugin_rule(
name = name_pb,
deps = deps,
)
@@ -141,6 +161,7 @@
def _proto_compiler_aspect_impl(target, ctx):
# List the files we will generate for this proto_library target.
genfiles = []
+
for src in target[ProtoInfo].direct_sources:
path = src.basename[:-len("proto")] + ctx.attr._extension
genfiles.append(ctx.actions.declare_file(path, sibling = src))
@@ -154,6 +175,7 @@
join_with = ctx.host_configuration.host_path_separator,
map_each = _get_path,
)
+
args.add_all(target[ProtoInfo].direct_sources, map_each = _get_short_path)
ctx.actions.run(
@@ -200,6 +222,7 @@
),
},
implementation = _proto_compiler_aspect_impl,
+ provides = [PwProtoInfo],
)
def _impl_pw_proto_library(ctx):
@@ -279,8 +302,13 @@
"pwpb": {
"compiler": _pw_proto_library,
"deps": [
+ "//pw_assert:facade",
+ "//pw_containers:vector",
+ "//pw_preprocessor",
+ "//pw_protobuf",
+ "//pw_result",
"//pw_span",
- "//pw_protobuf:pw_protobuf",
+ "//pw_status",
],
"include_nanopb_dep": False,
"include_pwpb_dep": False,