diff options
author | Nathaniel Brough <nathaniel.brough@gmail.com> | 2022-01-11 14:35:43 +0800 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-02-04 20:39:01 +0000 |
commit | 059e10ae69cfb22ef53731dee2ef374d341beab0 (patch) | |
tree | a8023357a14e49fcd2770eba6b125e7c4735f7cc | |
parent | e4ce994be88911bfac16c688e8fd000e2f5a695f (diff) | |
download | pigweed-059e10ae69cfb22ef53731dee2ef374d341beab0.tar.gz |
pw_protobuf_compiler: Adds Nanopb to Bazel build
This change adds support for Protobuf code generation in the Bazel build
using the Nanopb plugin. As a side affect this also fixes a number of
packages, however requires some renaming to prevent clashes.
Fixed: 507
Bug: 317
Change-Id: Ie4a25a9cc7a7b550b4ef73e67f71308e48bdbc4c
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/78020
Reviewed-by: Ted Pudlik <tpudlik@google.com>
Commit-Queue: Ted Pudlik <tpudlik@google.com>
-rw-r--r-- | WORKSPACE | 42 | ||||
-rw-r--r-- | pw_log/BUILD.bazel | 4 | ||||
-rw-r--r-- | pw_log_rpc/BUILD.bazel | 31 | ||||
-rw-r--r-- | pw_multisink/BUILD.bazel | 2 | ||||
-rw-r--r-- | pw_protobuf/BUILD.bazel | 9 | ||||
-rw-r--r-- | pw_protobuf_compiler/BUILD.bazel | 11 | ||||
-rw-r--r-- | pw_protobuf_compiler/docs.rst | 48 | ||||
-rw-r--r-- | pw_protobuf_compiler/proto.bzl | 94 | ||||
-rw-r--r-- | pw_protobuf_compiler/ts/BUILD.bazel | 2 | ||||
-rw-r--r-- | pw_protobuf_compiler/ts/codegen/BUILD.bazel | 2 | ||||
-rw-r--r-- | pw_protobuf_compiler/ts/ts_proto_collection.bzl | 2 | ||||
-rw-r--r-- | pw_rpc/BUILD.bazel | 97 | ||||
-rw-r--r-- | pw_rpc/nanopb/BUILD.bazel | 130 | ||||
-rw-r--r-- | pw_rpc/py/BUILD.bazel | 2 | ||||
-rw-r--r-- | pw_rpc/raw/BUILD.bazel | 32 | ||||
-rw-r--r-- | pw_rpc/ts/BUILD.bazel | 15 | ||||
-rw-r--r-- | pw_transfer/BUILD.bazel | 3 | ||||
-rw-r--r-- | pw_transfer/ts/BUILD.bazel | 2 | ||||
-rw-r--r-- | pw_unit_test/BUILD.bazel | 27 | ||||
-rw-r--r-- | pw_web_ui/BUILD.bazel | 20 | ||||
-rw-r--r-- | third_party/rules_proto_grpc/BUILD.bazel | 15 | ||||
-rw-r--r-- | third_party/rules_proto_grpc/internal_proto.bzl | 237 |
22 files changed, 591 insertions, 236 deletions
@@ -31,12 +31,13 @@ load("@cipd_deps//:cipd_init.bzl", "cipd_init") cipd_init() # Set up Python support. -# Required by: rules_fuzzing. +# Required by: rules_fuzzing, com_github_nanopb_nanopb. # Used in modules: None. http_archive( name = "rules_python", - sha256 = "934c9ceb552e84577b0faf1e5a2f0450314985b4d8712b2b70717dc679fdc01b", - url = "https://github.com/bazelbuild/rules_python/releases/download/0.3.0/rules_python-0.3.0.tar.gz", + sha256 = "a30abdfc7126d497a7698c29c46ea9901c6392d6ed315171a6df5ce433aa4502", + strip_prefix = "rules_python-0.6.0", + url = "https://github.com/bazelbuild/rules_python/archive/0.6.0.tar.gz", ) # Set up Starlark library. @@ -122,6 +123,41 @@ rules_proto_grpc_toolchains() rules_proto_grpc_repos() +# Set up Protobuf rules. +# Required by: pigweed, com_github_bazelbuild_buildtools. +# Used in modules: //pw_protobuf. +http_archive( + name = "com_google_protobuf", + sha256 = "c6003e1d2e7fefa78a3039f19f383b4f3a61e81be8c19356f85b6461998ad3db", + strip_prefix = "protobuf-3.17.3", + url = "https://github.com/protocolbuffers/protobuf/archive/v3.17.3.tar.gz", +) + +load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") + +protobuf_deps() + +# Setup Nanopb protoc plugin. +# Required by: Pigweed. +# Used in modules: pw_protobuf. +git_repository( + name = "com_github_nanopb_nanopb", + commit = "e601fca6d9ed7fb5c09e2732452753b2989f128b", + remote = "https://github.com/nanopb/nanopb.git", +) + +load("@com_github_nanopb_nanopb//:nanopb_deps.bzl", "nanopb_deps") + +nanopb_deps() + +load("@com_github_nanopb_nanopb//:python_deps.bzl", "nanopb_python_deps") + +nanopb_python_deps() + +load("@com_github_nanopb_nanopb//:nanopb_workspace.bzl", "nanopb_workspace") + +nanopb_workspace() + # Set up Bazel platforms. # Required by: pigweed. # Used in modules: //pw_build, (Assorted modules via select statements). diff --git a/pw_log/BUILD.bazel b/pw_log/BUILD.bazel index ee9bff004..bc25ec318 100644 --- a/pw_log/BUILD.bazel +++ b/pw_log/BUILD.bazel @@ -58,7 +58,7 @@ pw_cc_library( ], deps = [ ":facade", - ":log_pwpb", + ":log_proto_cc.pwpb", "//pw_bytes", "//pw_log_tokenized:headers", "//pw_result", @@ -79,7 +79,7 @@ proto_library( ) pw_proto_library( - name = "log_pwpb", + name = "log_proto_cc", deps = [":log_proto"], ) diff --git a/pw_log_rpc/BUILD.bazel b/pw_log_rpc/BUILD.bazel index 3db6e856b..bc80d4bde 100644 --- a/pw_log_rpc/BUILD.bazel +++ b/pw_log_rpc/BUILD.bazel @@ -34,8 +34,8 @@ pw_cc_library( ":log_filter", ":rpc_log_drain", "//pw_log", - "//pw_log:log_pwpb", - "//pw_log:protos.raw_rpc", + "//pw_log:log_proto_cc.pwpb", + "//pw_log:log_proto_cc.raw_rpc", ], ) @@ -47,8 +47,8 @@ pw_cc_library( deps = [ ":log_filter", "//pw_log", - "//pw_log:log_pwpb", - "//pw_log:protos.raw_rpc", + "//pw_log:log_proto_cc.pwpb", + "//pw_log:log_proto_cc.raw_rpc", "//pw_protobuf", "//pw_protobuf:bytes_utils", ], @@ -56,20 +56,21 @@ pw_cc_library( pw_cc_library( name = "log_filter", - srcs = ["log_filter.cc"], + srcs = [ + "log_filter.cc", + "public/pw_log_rpc/internal/config.h", + ], hdrs = [ "public/pw_log_rpc/log_filter.h", "public/pw_log_rpc/log_filter_map.h", ], includes = ["public"], deps = [ - "public/pw_log_rpc/internal/config.h", "//pw_assert", "//pw_bytes", "//pw_containers:vector", "//pw_log", - "//pw_log:log_pwpb", - "//pw_log:protos.pwpb", + "//pw_log:log_proto_cc.pwpb", "//pw_protobuf", "//pw_status", ], @@ -86,8 +87,8 @@ pw_cc_library( deps = [ ":log_filter", "//pw_assert", - "//pw_log:log_pwpb", - "//pw_log:protos.raw_rpc", + "//pw_log:log_proto_cc.pwpb", + "//pw_log:log_proto_cc.raw_rpc", "//pw_multisink", "//pw_protobuf", "//pw_result", @@ -121,9 +122,9 @@ pw_cc_test( ":log_service", "//pw_containers:vector", "//pw_log", - "//pw_log:log_pwpb", + "//pw_log:log_proto_cc.pwpb", "//pw_log:proto_utils", - "//pw_log_tokenized:metadata", + "//pw_log_tokenized:headers", "//pw_protobuf", "//pw_protobuf:bytes_utils", "//pw_result", @@ -139,7 +140,7 @@ pw_cc_test( deps = [ ":log_filter", ":log_filter_service", - "//pw_log:log_pwpb", + "//pw_log:log_proto_cc.pwpb", "//pw_protobuf", "//pw_protobuf:bytes_utils", "//pw_result", @@ -153,9 +154,9 @@ pw_cc_test( srcs = ["log_filter_test.cc"], deps = [ ":log_filter", - "//pw_log:log_pwpb", + "//pw_log:log_proto_cc.pwpb", "//pw_log:proto_utils", - "//pw_log_tokenized:metadata", + "//pw_log_tokenized:headers", "//pw_result", "//pw_status", "//pw_unit_test", diff --git a/pw_multisink/BUILD.bazel b/pw_multisink/BUILD.bazel index 56b6e9c39..acd90027e 100644 --- a/pw_multisink/BUILD.bazel +++ b/pw_multisink/BUILD.bazel @@ -61,7 +61,7 @@ pw_cc_library( "//pw_bytes", "//pw_function", "//pw_log", - "//pw_log:log_pwpb", + "//pw_log:log_proto_cc.pwpb", "//pw_status", ], ) diff --git a/pw_protobuf/BUILD.bazel b/pw_protobuf/BUILD.bazel index 711ac97d6..97c4b44c0 100644 --- a/pw_protobuf/BUILD.bazel +++ b/pw_protobuf/BUILD.bazel @@ -178,8 +178,11 @@ proto_library( ) pw_proto_library( - name = "codegen_test_protos_pwpb", - deps = [":codegen_test_proto"], + name = "codegen_test_proto_cc", + deps = [ + ":codegen_test_proto", + ":common_protos", + ], ) pw_cc_test( @@ -188,7 +191,7 @@ pw_cc_test( "codegen_test.cc", ], deps = [ - ":codegen_test_protos_pwpb", + ":codegen_test_proto_cc.pwpb", ":pw_protobuf", "//pw_span", "//pw_unit_test", diff --git a/pw_protobuf_compiler/BUILD.bazel b/pw_protobuf_compiler/BUILD.bazel index a96bed43c..045285e84 100644 --- a/pw_protobuf_compiler/BUILD.bazel +++ b/pw_protobuf_compiler/BUILD.bazel @@ -32,18 +32,11 @@ py_proto_library( ], ) -filegroup( - name = "protos", - srcs = [ - "pw_protobuf_compiler_protos/nested/more_nesting/test.proto", - "pw_protobuf_compiler_protos/test.proto", - ], -) - proto_library( name = "test_protos", srcs = [ - ":protos", + "pw_protobuf_compiler_protos/nested/more_nesting/test.proto", + "pw_protobuf_compiler_protos/test.proto", ], ) diff --git a/pw_protobuf_compiler/docs.rst b/pw_protobuf_compiler/docs.rst index 9362ca1bd..31160e865 100644 --- a/pw_protobuf_compiler/docs.rst +++ b/pw_protobuf_compiler/docs.rst @@ -375,13 +375,52 @@ compile them. e.g. deps = [":my_proto"], ) - # Library that depends on generated proto targets. + # Library that depends on only pw_protobuf generated proto targets. + pw_cc_library( + name = "my_proto_only_lib", + srcs = ["my/proto_only.cc"], + deps = [":my_cc_proto.pwpb"], + ) + + # Library that depends on only Nanopb generated proto targets. + pw_cc_library( + name = "my_nanopb_only_lib", + srcs = ["my/nanopb_only.cc"], + deps = [":my_cc_proto.nanopb"], + ) + + # Library that depends on pw_protobuf and pw_rpc/raw. + pw_cc_library( + name = "my_raw_rpc_lib", + srcs = ["my/raw_rpc.cc"], + deps = [ + ":my_cc_proto.pwpb", + ":my_cc_proto.raw_rpc", + ], + ) + pw_cc_library( + name = "my_nanopb_rpc_lib", + srcs = ["my/proto_only.cc"], + deps = [ + ":my_cc_proto.nanopb_rpc", + ], + ) + + + # Library that depends on generated proto targets. Prefer to depend only on + # those generated targets ("my_lib.pwpb", "my_lib.nanopb") that are actually + # required. Note that the .nanopb target may not compile for some proto + # messages, e.g. self-referring messages; + # see https://github.com/nanopb/nanopb/issues/433. pw_cc_library( name = "my_lib", srcs = ["my/lib.cc"], + # This target depends on all generated proto targets + # e.g. name.{pwpb, nanopb, raw_rpc, nanopb_rpc} deps = [":my_cc_proto"], ) + From ``my/lib.cc`` you can now include the generated headers. e.g. @@ -390,10 +429,10 @@ e.g. #include "my_protos/bar.pwpb.h" // and/or RPC headers #include "my_protos/bar.raw_rpc.pb.h + // or + #include "my_protos/bar.nanopb_rpc.pb.h" -.. note:: - Currently only raw RPC is supported by the Bazel build. **Supported Codegen** @@ -401,5 +440,8 @@ Bazel supports the following compiled proto libraries via the specified sub-targets generated by a ``pw_proto_library``. * ``${NAME}.pwpb`` - Generated C++ pw_protobuf code +* ``${NAME}.nanopb`` - Generated C++ nanopb code * ``${NAME}.raw_rpc`` - Generated C++ raw pw_rpc code (no protobuf library) +* ``${NAME}.nanopb_rpc`` - Generated C++ Nanopb pw_rpc code + diff --git a/pw_protobuf_compiler/proto.bzl b/pw_protobuf_compiler/proto.bzl index 37ac82d69..effe3de70 100644 --- a/pw_protobuf_compiler/proto.bzl +++ b/pw_protobuf_compiler/proto.bzl @@ -1,4 +1,4 @@ -# Copyright 2021 The Pigweed Authors +# Copyright 2022 The Pigweed Authors # # Licensed 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 @@ -13,94 +13,10 @@ # the License. """Embedded-friendly replacement for native.cc_proto_library.""" -load("//pw_build:pigweed.bzl", "pw_cc_library") -load("@rules_proto//proto:defs.bzl", "ProtoInfo") load( - "@rules_proto_grpc//:defs.bzl", - "ProtoLibraryAspectNodeInfo", - "ProtoPluginInfo", - "proto_compile_aspect_attrs", - "proto_compile_aspect_impl", - "proto_compile_attrs", - "proto_compile_impl", + "//third_party/rules_proto_grpc:internal_proto.bzl", + _pw_proto_library = "pw_proto_library", ) -# Create aspect for cc_proto_compile -cc_proto_compile_aspect = aspect( - implementation = proto_compile_aspect_impl, - provides = [ProtoLibraryAspectNodeInfo], - attr_aspects = ["deps"], - attrs = dict( - proto_compile_aspect_attrs, - _plugins = attr.label_list( - doc = "List of protoc plugins to apply", - providers = [ProtoPluginInfo], - default = [ - Label("@pigweed//pw_protobuf:pw_cc_plugin"), - Label("@pigweed//pw_rpc:pw_cc_plugin"), - ], - ), - _prefix = attr.string( - doc = "String used to disambiguate aspects when generating outputs", - default = "cc_proto_compile_aspect", - ), - ), - toolchains = [str(Label("@rules_proto_grpc//protobuf:toolchain_type"))], -) - -# Create compile rule to apply aspect -_rule = rule( - implementation = proto_compile_impl, - attrs = dict( - proto_compile_attrs, - deps = attr.label_list( - mandatory = True, - providers = [ProtoInfo, ProtoLibraryAspectNodeInfo], - aspects = [cc_proto_compile_aspect], - ), - protos = attr.label_list( - providers = [ProtoInfo], - doc = "List of proto_library targets.", - ), - ), -) - -# Create macro for converting attrs and passing to compile -def _cc_proto_compile(**kwargs): - _rule( - verbose_string = "{}".format(kwargs.get("verbose", 0)), - **kwargs - ) - -def pw_proto_library(**kwargs): - """ Embedded friendly replacement for native.cc_proto_library - - This Protobuf implementation is designed to run on embedded - computers. Because of this the cc API differs from the standard - Protobuf cc plugin. The generated headers in this library are not a drop in - replacement for the standard cc_proto_library. - - Args: - **kwargs: Equivalent inputs to cc_proto_library - """ - - # Compile protos - name_pb = kwargs.get("name") + "_pb" - _cc_proto_compile( - name = name_pb, - # Forward deps and verbose tags to implementation - **{k: v for (k, v) in kwargs.items() if k in ("deps", "verbose")} - ) - - # Create cc_library - pw_cc_library( - name = kwargs.get("name"), - srcs = [name_pb], - deps = [ - "@pigweed//pw_protobuf", - ], - includes = [name_pb], - strip_include_prefix = ".", - visibility = kwargs.get("visibility"), - linkstatic = 1, - ) +# Export internal symbols. +pw_proto_library = _pw_proto_library diff --git a/pw_protobuf_compiler/ts/BUILD.bazel b/pw_protobuf_compiler/ts/BUILD.bazel index 5e995915e..020da8fe4 100644 --- a/pw_protobuf_compiler/ts/BUILD.bazel +++ b/pw_protobuf_compiler/ts/BUILD.bazel @@ -56,7 +56,7 @@ ts_library( deps = [ ":test_proto_collection", "//pw_protobuf_compiler:test_protos_tspb", - "//pw_rpc:packet_proto_tspb", + "//pw_rpc/ts:packet_proto_tspb", "@npm//@types/google-protobuf", "@npm//@types/jasmine", ], diff --git a/pw_protobuf_compiler/ts/codegen/BUILD.bazel b/pw_protobuf_compiler/ts/codegen/BUILD.bazel index 80c0e7e84..f1959cfcf 100644 --- a/pw_protobuf_compiler/ts/codegen/BUILD.bazel +++ b/pw_protobuf_compiler/ts/codegen/BUILD.bazel @@ -23,7 +23,7 @@ ts_library( "template_replacement.ts", ], deps = [ - "@//pw_rpc:packet_proto_tspb", + "@//pw_rpc/ts:packet_proto_tspb", "@npm//@types/argparse", "@npm//@types/google-protobuf", "@npm//@types/node", diff --git a/pw_protobuf_compiler/ts/ts_proto_collection.bzl b/pw_protobuf_compiler/ts/ts_proto_collection.bzl index fe57e28c5..fe9af959e 100644 --- a/pw_protobuf_compiler/ts/ts_proto_collection.bzl +++ b/pw_protobuf_compiler/ts/ts_proto_collection.bzl @@ -37,7 +37,7 @@ def _lib(name, proto_library, js_proto_library): deps = [ js_proto_library, "@//pw_protobuf_compiler/ts:pw_protobuf_compiler", - "@//pw_rpc:packet_proto_tspb", + "@//pw_rpc/ts:packet_proto_tspb", "@npm//@types/google-protobuf", "@npm//@types/node", "@npm//base64-js", diff --git a/pw_rpc/BUILD.bazel b/pw_rpc/BUILD.bazel index 38e9aa946..83431ef09 100644 --- a/pw_rpc/BUILD.bazel +++ b/pw_rpc/BUILD.bazel @@ -17,7 +17,6 @@ load("//pw_protobuf_compiler:proto.bzl", "pw_proto_library") load("@com_google_protobuf//:protobuf.bzl", "py_proto_library") load("@rules_proto//proto:defs.bzl", "proto_library") load("@rules_proto_grpc//:defs.bzl", "proto_plugin") -load("@rules_proto_grpc//js:defs.bzl", "js_proto_library") package(default_visibility = ["//visibility:public"]) @@ -31,7 +30,7 @@ proto_library( ) pw_proto_library( - name = "benchmark_pwpb", + name = "benchmark_cc", deps = [":benchmark_proto"], ) @@ -41,11 +40,8 @@ pw_cc_library( hdrs = ["public/pw_rpc/benchmark.h"], includes = ["public"], deps = [ - ":benchmark_pwpb", - # TODO(hepler): RPC deps not used directly should be provided by the proto library - ":pw_rpc", - "//pw_rpc/raw:server_api", - "//pw_rpc/raw:client_api", + ":benchmark_cc.pwpb", + ":benchmark_cc.raw_rpc", ], ) @@ -106,7 +102,7 @@ pw_cc_library( ], includes = ["public"], deps = [ - ":internal_packet_pwpb", + ":internal_packet_cc.pwpb", "//pw_assert", "//pw_bytes", "//pw_containers", @@ -178,41 +174,6 @@ filegroup( srcs = ["client_integration_test.cc"], ) -# TODO(pwbug/507): Cannot build nanopb-dependent code in Bazel at the moment. Need -# to determine how best to support Nanopb builds and protobuf generation. -filegroup( - name = "nanopb", - srcs = [ - "nanopb/client_call_test.cc", - "nanopb/client_integration_test.cc", - "nanopb/client_reader_writer_test.cc", - "nanopb/codegen_test.cc", - "nanopb/common.cc", - "nanopb/echo_service_test.cc", - "nanopb/fake_channel_output_test.cc", - "nanopb/method.cc", - "nanopb/method_info_test.cc", - "nanopb/method_lookup_test.cc", - "nanopb/method_test.cc", - "nanopb/method_union_test.cc", - "nanopb/public/pw_rpc/echo_service_nanopb.h", - "nanopb/public/pw_rpc/nanopb/client_reader_writer.h", - "nanopb/public/pw_rpc/nanopb/client_testing.h", - "nanopb/public/pw_rpc/nanopb/fake_channel_output.h", - "nanopb/public/pw_rpc/nanopb/internal/common.h", - "nanopb/public/pw_rpc/nanopb/internal/method.h", - "nanopb/public/pw_rpc/nanopb/internal/method_union.h", - "nanopb/public/pw_rpc/nanopb/server_reader_writer.h", - "nanopb/public/pw_rpc/nanopb/test_method_context.h", - "nanopb/pw_rpc_nanopb_private/internal_test_utils.h", - "nanopb/serde_test.cc", - "nanopb/server_callback_test.cc", - "nanopb/server_reader_writer.cc", - "nanopb/server_reader_writer_test.cc", - "nanopb/stub_generation_test.cc", - ], -) - pw_cc_test( name = "call_test", srcs = [ @@ -295,12 +256,7 @@ pw_cc_test( proto_library( name = "internal_packet_proto", srcs = ["internal/packet.proto"], - visibility = ["//visibility:private"], -) - -js_proto_library( - name = "packet_proto_tspb", - protos = [":internal_packet_proto"], + visibility = [":__subpackages__"], ) java_lite_proto_library( @@ -314,7 +270,7 @@ py_proto_library( ) pw_proto_library( - name = "internal_packet_pwpb", + name = "internal_packet_cc", deps = [":internal_packet_proto"], ) @@ -325,24 +281,55 @@ proto_library( ) pw_proto_library( - name = "pw_rpc_test_pwpb", + name = "pw_rpc_test_cc", deps = [":pw_rpc_test_proto"], ) proto_plugin( - name = "pw_cc_plugin", + name = "pw_cc_plugin_raw", outputs = [ "{protopath}.raw_rpc.pb.h", ], protoc_plugin_name = "raw_rpc", - tool = "@pigweed//pw_rpc/py:plugin", + tool = "@pigweed//pw_rpc/py:plugin_raw", use_built_in_shell_environment = True, visibility = ["//visibility:public"], ) -filegroup( - name = "echo", +proto_plugin( + name = "pw_cc_plugin_nanopb_rpc", + outputs = [ + "{protopath}.rpc.pb.h", + ], + protoc_plugin_name = "nanopb_rpc", + tool = "@pigweed//pw_rpc/py:plugin_nanopb", + use_built_in_shell_environment = True, + visibility = ["//visibility:public"], +) + +proto_plugin( + name = "nanopb_plugin", + options = [ + "--library-include-format='#include\"%s\"'", + ], + outputs = [ + "{protopath}.pb.h", + "{protopath}.pb.c", + ], + separate_options_flag = True, + tool = "@com_github_nanopb_nanopb//:bazel_generator", + use_built_in_shell_environment = True, + visibility = ["//visibility:public"], +) + +proto_library( + name = "echo_proto", srcs = [ "echo.proto", ], ) + +pw_proto_library( + name = "echo_cc", + deps = [":echo_proto"], +) diff --git a/pw_rpc/nanopb/BUILD.bazel b/pw_rpc/nanopb/BUILD.bazel new file mode 100644 index 000000000..3594c078b --- /dev/null +++ b/pw_rpc/nanopb/BUILD.bazel @@ -0,0 +1,130 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed 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 +# +# https://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. + +load( + "//pw_build:pigweed.bzl", + "pw_cc_library", + "pw_cc_test", +) + +package(default_visibility = ["//visibility:public"]) + +pw_cc_library( + name = "server_api", + srcs = [ + "method.cc", + "server_reader_writer.cc", + ], + hdrs = [ + "public/pw_rpc/nanopb/internal/method.h", + "public/pw_rpc/nanopb/internal/method_union.h", + "public/pw_rpc/nanopb/server_reader_writer.h", + ], + includes = ["public"], + deps = [ + ":common", + "//pw_rpc/raw:server_api", + ], +) + +pw_cc_library( + name = "client_api", + hdrs = [ + "public/pw_rpc/nanopb/client_reader_writer.h", + ], + includes = ["public"], + deps = [ + ":common", + ], +) + +pw_cc_library( + name = "common", + srcs = ["common.cc"], + hdrs = [ + "public/pw_rpc/nanopb/internal/common.h", + "public/pw_rpc/nanopb/server_reader_writer.h", + ], + includes = ["public"], + deps = [ + "//pw_rpc", + "@com_github_nanopb_nanopb//:nanopb", + ], +) + +pw_cc_library( + name = "test_method_context", + hdrs = [ + "public/pw_rpc/nanopb/fake_channel_output.h", + "public/pw_rpc/nanopb/test_method_context.h", + ], + includes = ["public"], + deps = [ + "//pw_containers", + "//pw_rpc:internal_test_utils", + ], +) + +pw_cc_library( + name = "client_testing", + hdrs = [ + "public/pw_rpc/nanopb/client_testing.h", + ], + includes = ["public"], + deps = [ + ":test_method_context", + "//pw_rpc", + "//pw_rpc/raw:client_testing", + ], +) + +pw_cc_library( + name = "internal_test_utils", + hdrs = ["pw_rpc_nanopb_private/internal_test_utils.h"], + deps = ["//pw_rpc:internal_test_utils"], +) + +pw_cc_library( + name = "echo_service", + hdrs = ["public/pw_rpc/echo_service_nanopb.h"], + deps = [ + "//pw_rpc:echo_cc.nanopb_rpc", + ], +) + +# TODO(pwbug/507): Enable this library when logging_event_handler can be used. +filegroup( + name = "client_integration_test", + srcs = [ + "client_integration_test.cc", + ], + #deps = [ + # "//pw_rpc:integration_testing", + # "//pw_sync:binary_semaphore", + # "//pw_rpc:benchmark_cc.nanopb_rpc", + #] +) + +pw_cc_test( + name = "client_call_test", + srcs = [ + "client_call_test.cc", + ], + deps = [ + ":client_api", + ":internal_test_utils", + "//pw_rpc", + "//pw_rpc:pw_rpc_test_cc.nanopb", + ], +) diff --git a/pw_rpc/py/BUILD.bazel b/pw_rpc/py/BUILD.bazel index e077b6752..4d9d454fe 100644 --- a/pw_rpc/py/BUILD.bazel +++ b/pw_rpc/py/BUILD.bazel @@ -42,7 +42,7 @@ filegroup( ) py_binary( - name = "plugin", + name = "plugin_raw", srcs = [":pw_rpc_common_sources"], imports = ["."], main = "pw_rpc/plugin_raw.py", diff --git a/pw_rpc/raw/BUILD.bazel b/pw_rpc/raw/BUILD.bazel index b21c56217..4e5a4c008 100644 --- a/pw_rpc/raw/BUILD.bazel +++ b/pw_rpc/raw/BUILD.bazel @@ -36,7 +36,7 @@ pw_cc_library( deps = [ "//pw_bytes", "//pw_rpc", - "//pw_rpc:internal_packet_pwpb", + "//pw_rpc:internal_packet_cc.pwpb", ], ) @@ -47,7 +47,7 @@ pw_cc_library( deps = [ "//pw_bytes", "//pw_rpc", - "//pw_rpc:internal_packet_pwpb", + "//pw_rpc:internal_packet_cc.pwpb", ], ) @@ -102,7 +102,7 @@ pw_cc_test( deps = [ ":client_api", ":client_testing", - "//pw_rpc:pw_rpc_test_pwpb", + "//pw_rpc:pw_rpc_test_cc.raw_rpc", ], ) @@ -118,7 +118,8 @@ pw_cc_test( ":test_method_context", "//pw_protobuf", "//pw_rpc:internal_test_utils", - "//pw_rpc:pw_rpc_test_pwpb", + "//pw_rpc:pw_rpc_test_cc.pwpb", + "//pw_rpc:pw_rpc_test_cc.raw_rpc", ], ) @@ -131,7 +132,7 @@ pw_cc_test( ":server_api", "//pw_protobuf", "//pw_rpc:internal_test_utils", - "//pw_rpc:pw_rpc_test_pwpb", + "//pw_rpc:pw_rpc_test_cc.pwpb", ], ) @@ -141,12 +142,8 @@ pw_cc_test( "method_info_test.cc", ], deps = [ - "//pw_rpc", "//pw_rpc:internal_test_utils", - "//pw_rpc:pw_rpc_test_pwpb", - # TODO(hepler): RPC deps not used directly should be provided by the proto library - "//pw_rpc/raw:client_api", - "//pw_rpc/raw:server_api", + "//pw_rpc:pw_rpc_test_cc.raw_rpc", ], ) @@ -159,7 +156,7 @@ pw_cc_test( ":server_api", "//pw_protobuf", "//pw_rpc:internal_test_utils", - "//pw_rpc:pw_rpc_test_pwpb", + "//pw_rpc:pw_rpc_test_cc.pwpb", ], ) @@ -167,12 +164,10 @@ pw_cc_test( name = "server_reader_writer_test", srcs = ["server_reader_writer_test.cc"], deps = [ - # TODO(hepler): RPC deps not used directly should be provided by the proto library - ":client_api", - ":server_api", ":test_method_context", "//pw_rpc:internal_test_utils", - "//pw_rpc:pw_rpc_test_pwpb", + "//pw_rpc:pw_rpc_test_cc.pwpb", + "//pw_rpc:pw_rpc_test_cc.raw_rpc", ], ) @@ -180,10 +175,7 @@ pw_cc_test( name = "stub_generation_test", srcs = ["stub_generation_test.cc"], deps = [ - # TODO(hepler): RPC deps not used directly should be provided by the proto library - "//pw_rpc", - "//pw_rpc:pw_rpc_test_pwpb", - ":server_api", - ":client_api", + "//pw_rpc:pw_rpc_test_cc.pwpb", + "//pw_rpc:pw_rpc_test_cc.raw_rpc", ], ) diff --git a/pw_rpc/ts/BUILD.bazel b/pw_rpc/ts/BUILD.bazel index 18b6ba7c0..ef3bc6496 100644 --- a/pw_rpc/ts/BUILD.bazel +++ b/pw_rpc/ts/BUILD.bazel @@ -35,8 +35,8 @@ ts_project( declaration = True, source_map = True, deps = [ + ":packet_proto_tspb", "//pw_protobuf_compiler/ts:pw_protobuf_compiler", - "//pw_rpc:packet_proto_tspb", "//pw_status/ts:pw_status", "@npm//@types/google-protobuf", "@npm//wait-queue", @@ -52,8 +52,8 @@ js_library( ts_proto_collection( name = "rpc_proto_collection", - js_proto_library = "@//pw_rpc/ts:test_protos_tspb", - proto_library = "@//pw_rpc/ts:test_protos", + js_proto_library = "@pigweed//pw_rpc/ts:test_protos_tspb", + proto_library = "@pigweed//pw_rpc/ts:test_protos", ) ts_library( @@ -68,11 +68,11 @@ ts_library( ":test_protos", ], deps = [ - "test_protos_tspb", ":lib", + ":packet_proto_tspb", ":rpc_proto_collection", + ":test_protos_tspb", "//pw_protobuf_compiler/ts:pw_protobuf_compiler", - "//pw_rpc:packet_proto_tspb", "//pw_status/ts:pw_status", "@npm//@types/google-protobuf", "@npm//@types/jasmine", @@ -99,3 +99,8 @@ js_proto_library( name = "test_protos_tspb", protos = [":test_protos"], ) + +js_proto_library( + name = "packet_proto_tspb", + protos = ["//pw_rpc:internal_packet_proto"], +) diff --git a/pw_transfer/BUILD.bazel b/pw_transfer/BUILD.bazel index ad9673c6a..5fd33a2b1 100644 --- a/pw_transfer/BUILD.bazel +++ b/pw_transfer/BUILD.bazel @@ -54,8 +54,7 @@ pw_cc_library( "//pw_log", "//pw_protobuf", "//pw_result", - "//pw_rpc:internal_packet_pwpb", - "//pw_rpc/raw:client_api", + "//pw_rpc:internal_packet_cc.pwpb", "//pw_rpc/raw:server_api", "//pw_status", "//pw_stream", diff --git a/pw_transfer/ts/BUILD.bazel b/pw_transfer/ts/BUILD.bazel index c84824f3a..ca639ae64 100644 --- a/pw_transfer/ts/BUILD.bazel +++ b/pw_transfer/ts/BUILD.bazel @@ -58,8 +58,8 @@ ts_library( deps = [ ":lib", ":transfer_proto_collection", - "//pw_rpc:packet_proto_tspb", "//pw_rpc/ts:lib", + "//pw_rpc/ts:packet_proto_tspb", "//pw_status/ts:pw_status", "//pw_transfer:transfer_proto_tspb", "@npm//@types/jasmine", diff --git a/pw_unit_test/BUILD.bazel b/pw_unit_test/BUILD.bazel index b0f883886..af98b9cb7 100644 --- a/pw_unit_test/BUILD.bazel +++ b/pw_unit_test/BUILD.bazel @@ -14,6 +14,7 @@ load( "//pw_build:pigweed.bzl", + "pw_cc_binary", "pw_cc_library", "pw_cc_test", ) @@ -66,19 +67,32 @@ pw_cc_library( ], ) -filegroup( +pw_cc_library( name = "logging_event_handler", srcs = [ "logging_event_handler.cc", + ], + hdrs = [ "public/pw_unit_test/logging_event_handler.h", ], + includes = [ + "public", + ], + deps = [ + "//pw_log", + "//pw_unit_test", + ], ) -filegroup( +pw_cc_binary( name = "logging_main", srcs = [ "logging_main.cc", ], + deps = [ + ":logging_event_handler", + "//pw_unit_test", + ], ) pw_cc_library( @@ -101,7 +115,7 @@ proto_library( ) pw_proto_library( - name = "unit_test_pwpb", + name = "unit_test_cc", deps = [":unit_test_proto"], ) @@ -117,12 +131,9 @@ pw_cc_library( ], deps = [ ":pw_unit_test", - ":unit_test_pwpb", + ":unit_test_cc.pwpb", + ":unit_test_cc.raw_rpc", "//pw_log", - # TODO(hepler): RPC deps not used directly should be provided by the proto library - "//pw_rpc", - "//pw_rpc/raw:client_api", - "//pw_rpc/raw:server_api", ], ) diff --git a/pw_web_ui/BUILD.bazel b/pw_web_ui/BUILD.bazel index 97c30cade..1fe99a2ec 100644 --- a/pw_web_ui/BUILD.bazel +++ b/pw_web_ui/BUILD.bazel @@ -22,29 +22,17 @@ load("@rules_proto_grpc//js:defs.bzl", "js_proto_library") package(default_visibility = ["//visibility:public"]) -filegroup( - name = "echo_service", - srcs = [ - "@//pw_rpc:echo", - ], -) - -proto_library( - name = "rpc_protos", - srcs = [ - ":echo_service", - ], -) - js_proto_library( name = "rpc_protos_tspb", - protos = [":rpc_protos"], + protos = [ + "//pw_rpc:echo_proto", + ], ) ts_proto_collection( name = "web_proto_collection", js_proto_library = "@//pw_web_ui:rpc_protos_tspb", - proto_library = "@//pw_web_ui:rpc_protos", + proto_library = "@//pw_rpc:echo_proto", ) ts_project( diff --git a/third_party/rules_proto_grpc/BUILD.bazel b/third_party/rules_proto_grpc/BUILD.bazel new file mode 100644 index 000000000..a524793e9 --- /dev/null +++ b/third_party/rules_proto_grpc/BUILD.bazel @@ -0,0 +1,15 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed 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 +# +# https://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. + +exports_files(["internal_proto.bzl"]) diff --git a/third_party/rules_proto_grpc/internal_proto.bzl b/third_party/rules_proto_grpc/internal_proto.bzl new file mode 100644 index 000000000..cab19d405 --- /dev/null +++ b/third_party/rules_proto_grpc/internal_proto.bzl @@ -0,0 +1,237 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed 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 +# +# https://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. + +"""Backend implementation for 'pw_protobuf_compiler/proto.bzl'""" + +# Apache License, Version 2.0, January 2004, http://www.apache.org/licenses/ +# Adapted from: https://github.com/rules-proto-grpc/rules_proto_grpc/ +# Files adapted: +# - rules_proto_grpc/cpp/cpp_grpc_library.bzl +# - rules_proto_grpc/cpp/cpp_grpc_compile.bzl +# These two files have been adapted for use in Pigweed and combined into this +# file. + +load("@rules_proto//proto:defs.bzl", "ProtoInfo") +load( + "@rules_proto_grpc//:defs.bzl", + "ProtoLibraryAspectNodeInfo", + "ProtoPluginInfo", + "proto_compile_aspect_attrs", + "proto_compile_aspect_impl", + "proto_compile_attrs", + "proto_compile_impl", +) +load("@rules_proto_grpc//internal:filter_files.bzl", "filter_files") + +# Create compile rule +def _proto_compiler_aspect(plugin_group, prefix): + return aspect( + implementation = proto_compile_aspect_impl, + provides = [ProtoLibraryAspectNodeInfo], + attr_aspects = ["deps"], + attrs = dict( + proto_compile_aspect_attrs, + _plugins = attr.label_list( + doc = "List of protoc plugins to apply", + providers = [ProtoPluginInfo], + default = plugin_group, + ), + _prefix = attr.string( + doc = "String used to disambiguate aspects when generating \ +outputs", + default = prefix, + ), + ), + toolchains = [str(Label("@rules_proto_grpc//protobuf:toolchain_type"))], + ) + +def _proto_compiler_rule(plugin_group, aspect): + return rule( + implementation = proto_compile_impl, + attrs = dict( + proto_compile_attrs, + _plugins = attr.label_list( + doc = "List of protoc plugins to apply", + providers = [ProtoPluginInfo], + default = plugin_group, + ), + protos = attr.label_list( + providers = [ProtoInfo], + doc = "List of proto_library targets.", + ), + deps = attr.label_list( + doc = "List of proto_library targets. Prefer protos.", + aspects = [aspect], + ), + ), + toolchains = [str(Label("@rules_proto_grpc//protobuf:toolchain_type"))], + ) + +nanopb_compile_aspect = _proto_compiler_aspect( + [Label("//pw_rpc:nanopb_plugin")], + "nanopb_proto_compile_aspect", +) +nanopb_compile = _proto_compiler_rule( + [Label("//pw_rpc:nanopb_plugin")], + nanopb_compile_aspect, +) + +pwpb_compile_aspect = _proto_compiler_aspect( + [Label("@pigweed//pw_protobuf:pw_cc_plugin")], + "pwpb_proto_compile_aspect", +) +pwpb_compile = _proto_compiler_rule( + [Label("@pigweed//pw_protobuf:pw_cc_plugin")], + pwpb_compile_aspect, +) + +raw_rpc_compile_aspect = _proto_compiler_aspect( + [Label("@pigweed//pw_rpc:pw_cc_plugin_raw")], + "raw_rpc_proto_compile_aspect", +) +raw_rpc_compile = _proto_compiler_rule( + [Label("@pigweed//pw_rpc:pw_cc_plugin_raw")], + raw_rpc_compile_aspect, +) + +nanopb_rpc_compile_aspect = _proto_compiler_aspect( + [ + Label("@pigweed//pw_rpc:pw_cc_plugin_nanopb_rpc"), + Label("//pw_rpc:nanopb_plugin"), + ], + "nanopb_rpc_proto_compile_aspect", +) +nanopb_rpc_compile = _proto_compiler_rule( + [ + Label("@pigweed//pw_rpc:pw_cc_plugin_nanopb_rpc"), + Label("//pw_rpc:nanopb_plugin"), + ], + nanopb_rpc_compile_aspect, +) + +PLUGIN_INFO = { + "nanopb": { + "compiler": nanopb_compile, + "deps": ["@com_github_nanopb_nanopb//:nanopb"], + "has_srcs": True, + # TODO: Find a way to get Nanopb to generate nested structs. + # Otherwise add the manual tag to the resulting library, + # preventing it from being built unless directly depended on. + # e.g. The 'Pigweed' message in + # pw_protobuf/pw_protobuf_test_protos/full_test.proto will fail to + # compile as it has a self referring nested message. According to + # the docs + # https://jpa.kapsi.fi/nanopb/docs/reference.html#proto-file-options + # and https://github.com/nanopb/nanopb/issues/433 it seams like it + # should be possible to configure nanopb to generate nested structs. + "additional_tags": ["manual"], + }, + "nanopb_rpc": { + "compiler": nanopb_rpc_compile, + "deps": [ + "@com_github_nanopb_nanopb//:nanopb", + "@pigweed//pw_rpc/nanopb:server_api", + "@pigweed//pw_rpc/nanopb:client_api", + "@pigweed//pw_rpc", + ], + "has_srcs": True, + # See above todo. + "additional_tags": ["manual"], + }, + "pwpb": { + "compiler": pwpb_compile, + "deps": ["@pigweed//pw_protobuf"], + "has_srcs": False, + "additional_tags": [], + }, + "raw_rpc": { + "compiler": raw_rpc_compile, + "deps": [ + "@pigweed//pw_rpc", + "@pigweed//pw_rpc/raw:server_api", + "@pigweed//pw_rpc/raw:client_api", + ], + "has_srcs": False, + "additional_tags": [], + }, +} + +def pw_proto_library(name, **kwargs): # buildifier: disable=function-docstring + for plugin_name, info in PLUGIN_INFO.items(): + name_pb = name + "_pb" + "." + plugin_name + additional_tags = [ + tag + for tag in info["additional_tags"] + if tag not in kwargs.get("tags", []) + ] + info["compiler"]( + name = name_pb, + tags = additional_tags, + # Forward deps and verbose tags to implementation + verbose = kwargs.get("verbose", 0), + deps = kwargs.get("deps", []), + protos = kwargs.get("protos", []), + ) + + # Filter files to sources and headers + filter_files( + name = name_pb + "_srcs", + target = name_pb, + extensions = ["c", "cc", "cpp", "cxx"], + tags = additional_tags, + ) + + filter_files( + name = name_pb + "_hdrs", + target = name_pb, + extensions = ["h"], + tags = additional_tags, + ) + + # Cannot use pw_cc_library here as it will add cxxopts. + # Note that the srcs attribute here is passed in as a DefaultInfo + # object, which is not supported by pw_cc_library. + native.cc_library( + name = name + "." + plugin_name, + hdrs = [name_pb + "_hdrs"], + includes = [name_pb], + alwayslink = kwargs.get("alwayslink"), + copts = kwargs.get("copts", []), + defines = kwargs.get("defines", []), + srcs = [name_pb + "_srcs"] if info["has_srcs"] else [], + deps = info["deps"], + include_prefix = kwargs.get("include_prefix", ""), + linkopts = kwargs.get("linkopts", []), + linkstatic = kwargs.get("linkstatic", True), + local_defines = kwargs.get("local_defines", []), + nocopts = kwargs.get("nocopts", ""), + visibility = kwargs.get("visibility"), + tags = kwargs.get("tags", []) + additional_tags, + ) + + if "manual" in kwargs.get("tags", []): + additional_tags = [] + else: + additional_tags = ["manual"] + + # Combine all plugins into a single library. + native.cc_library( + name = name, + deps = [ + name + "." + plugin_name + for plugin_name in PLUGIN_INFO.keys() + ], + tags = kwargs.get("tags", []) + additional_tags, + **{k: v for k, v in kwargs.items() if k not in ["deps", "protos"]} + ) |