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.
The full example workspaces for C++ can be found here, along with the demo proto files here. Example workspaces for all other languages are also available.
Step 1: Load the module for C++¶
First, include the C++ specific rules_proto_grpc module in your MODULE.bazel file:
# MODULE.bazel
bazel_dep(name = "rules_proto_grpc_cpp", version = "<version number 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.
// 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:
# BUILD.bazel
proto_library(
name = "thing_proto",
srcs = ["thing.proto"],
deps = ["@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 ("@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: Build it!¶
We can now build the cpp_thing_proto target:
$ bazel build //:cpp_thing_proto
Target //:cpp_thing_proto up-to-date:
bazel-genfiles/cpp_thing_proto/thing.pb.h
bazel-genfiles/cpp_thing_proto/thing.pb.cc
You should now see generated .cc and .h files in your bazel-bin output tree.
Step 6: 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 //:cpp_thing_proto
Target //:cpp_thing_proto up-to-date:
bazel-bin/libcpp_thing_proto.a
bazel-bin/libcpp_thing_proto.so
bazel-genfiles/cpp_thing_proto/thing.pb.h
bazel-genfiles/cpp_thing_proto/thing.pb.cc
This time, we also have .a and .so files built. We can now use
//: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 //:cpp_thing_proto_pb