Example Usage¶
These steps walk through the actions required to go from a raw .proto
file to a C++ library. Other languages will have
a similar high-level layout, but you should check the language specific pages too.
Step 1: Install rules_proto_grpc¶
First, follow the instructions to install the rules_proto_grpc rules here
Step 2: Write a .proto
file¶
Write a protobuf .proto file
, following the specification.
In this case, we’ve called the file thing.proto
.
syntax = "proto3";
package example;
import "google/protobuf/any.proto";
message Thing {
string name = 1;
google.protobuf.Any payload = 2;
}
Step 3: Write a BUILD
file¶
This file should introduce a proto_library target:
proto_library(
name = "thing_proto",
srcs = ["thing.proto"],
deps = ["@com_google_protobuf//:any_proto"],
)
This rule takes no visible action, but is used to group a set of related .proto
files and their dependencies.
In this example we have a dependency on a well-known type any.proto
, hence the proto_library
to proto_library
dependency ("@com_google_protobuf//:any_proto"
)
Step 4: Add a cpp_proto_compile
target¶
We now add a target using the cpp_proto_compile
rule. This rule converts our .proto
file into the
C++ specific .h
and .cc
files.
Note: In this example thing.proto
does not include service definitions (gRPC). For protos with services, use the
cpp_grpc_compile
rule instead.
# BUILD.bazel
load("@rules_proto_grpc//cpp:defs.bzl", "cpp_proto_compile")
cpp_proto_compile(
name = "cpp_thing_proto",
protos = [":thing_proto"],
)
Step 5: Load the WORKSPACE
macro¶
But wait, before we can build this, we need to load the dependencies necessary for this rule in our WORKSPACE
.
(see cpp_proto_compile):
# WORKSPACE
load("@rules_proto_grpc//cpp:repositories.bzl", "cpp_repos")
cpp_repos()
Step 6: Build it!¶
We can now build the cpp_thing_proto
target:
$ bazel build //example/proto:cpp_thing_proto
Target //example/proto:cpp_thing_proto up-to-date:
bazel-genfiles/example/proto/cpp_thing_proto/example/proto/thing.pb.h
bazel-genfiles/example/proto/cpp_thing_proto/example/proto/thing.pb.cc
You should now see generated .cc
and .h
files in your bazel-bin output tree.
Step 7: Create a library¶
If we were only interested in the generated files, the cpp_grpc_compile
rule would be fine. However, for
convenience we’d rather have the outputs compiled into a C++ library with the necessary dependencies
linked. To do that, let’s change the rule from cpp_proto_compile
to cpp_proto_library
:
# BUILD.bazel
load("@rules_proto_grpc//cpp:defs.bzl", "cpp_proto_library")
cpp_proto_library(
name = "cpp_thing_proto",
protos = [":thing_proto"],
)
Now we can build again:
$ bazel build //example/proto:cpp_thing_proto
Target //example/proto:cpp_thing_proto up-to-date:
bazel-bin/example/proto/libcpp_thing_proto.a
bazel-bin/example/proto/libcpp_thing_proto.so
bazel-genfiles/example/proto/cpp_thing_proto/example/proto/thing.pb.h
bazel-genfiles/example/proto/cpp_thing_proto/example/proto/thing.pb.cc
This time, we also have .a
and .so
files built. We can now use //example/proto:cpp_thing_proto
as a dependency of
any other cc_library
or cc_binary
target as per normal.
Note: The cpp_proto_library
target implicitly calls cpp_proto_compile
, and we can access that rule’s by adding
_pb
at the end of the target name, like bazel build //example/proto:cpp_thing_proto_pb