1*d4726bddSHONG Yifan#[[ 2*d4726bddSHONG Yifan## Overview 3*d4726bddSHONG YifanThese build rules are used for building [protobufs][protobuf]/[gRPC][grpc] in [Rust][rust] with Bazel. 4*d4726bddSHONG Yifan 5*d4726bddSHONG YifanThere are two rule sets. The first ruleset defines the `rust_prost_library` which generates Rust code 6*d4726bddSHONG Yifanusing the [`prost`] and [`tonic`] dependencies. The second ruleset defines the `rust_proto_library` and 7*d4726bddSHONG Yifan`rust_grpc_library` rules which generate Rust code using the [`rust-protobuf`] dependencies. 8*d4726bddSHONG Yifan 9*d4726bddSHONG Yifan[rust]: http://www.rust-lang.org/ 10*d4726bddSHONG Yifan[protobuf]: https://developers.google.com/protocol-buffers/ 11*d4726bddSHONG Yifan[grpc]: https://grpc.io 12*d4726bddSHONG Yifan[`rust-protobuf`]: https://github.com/stepancheg/rust-protobuf/ 13*d4726bddSHONG Yifan 14*d4726bddSHONG YifanSee the [protobuf example](../examples/proto) for a more complete example of use. 15*d4726bddSHONG Yifan 16*d4726bddSHONG Yifan### Prost Setup 17*d4726bddSHONG Yifan 18*d4726bddSHONG Yifan```python 19*d4726bddSHONG Yifanload("@rules_rust//proto/prost:repositories.bzl", "rust_prost_dependencies") 20*d4726bddSHONG Yifan 21*d4726bddSHONG Yifanrust_prost_dependencies() 22*d4726bddSHONG Yifan 23*d4726bddSHONG Yifanload("@rules_rust//proto/prost:transitive_repositories.bzl", "rust_prost_transitive_repositories") 24*d4726bddSHONG Yifan 25*d4726bddSHONG Yifanrust_prost_transitive_repositories() 26*d4726bddSHONG Yifan``` 27*d4726bddSHONG Yifan 28*d4726bddSHONG YifanThe `prost` and `tonic` rules do not specify a default toolchain in order to avoid mismatched 29*d4726bddSHONG Yifandependency issues. To setup the `prost` and `tonic` toolchain, please see the section 30*d4726bddSHONG Yifan[Customizing `prost` and `tonic` Dependencies](#custom-prost-deps). 31*d4726bddSHONG Yifan 32*d4726bddSHONG YifanFor additional information about Bazel toolchains, see [here](https://docs.bazel.build/versions/master/toolchains.html). 33*d4726bddSHONG Yifan 34*d4726bddSHONG Yifan#### <a name="custom-prost-deps">Customizing `prost` and `tonic` Dependencies 35*d4726bddSHONG Yifan 36*d4726bddSHONG YifanThese rules depend on the [`prost`] and [`tonic`] dependencies. To setup the necessary toolchain 37*d4726bddSHONG Yifanfor these rules, you must define a toolchain with the [`prost`], [`prost-types`], [`tonic`], [`protoc-gen-prost`], and [`protoc-gen-tonic`] crates as well as the [`protoc`] binary. 38*d4726bddSHONG Yifan 39*d4726bddSHONG Yifan[`prost`]: https://crates.io/crates/prost 40*d4726bddSHONG Yifan[`prost-types`]: https://crates.io/crates/prost-types 41*d4726bddSHONG Yifan[`protoc-gen-prost`]: https://crates.io/crates/protoc-gen-prost 42*d4726bddSHONG Yifan[`protoc-gen-tonic`]: https://crates.io/crates/protoc-gen-tonic 43*d4726bddSHONG Yifan[`tonic`]: https://crates.io/crates/tonic 44*d4726bddSHONG Yifan[`protoc`]: https://github.com/protocolbuffers/protobuf 45*d4726bddSHONG Yifan 46*d4726bddSHONG YifanTo get access to these crates, you can use the [crate_universe](./crate_universe.md) repository 47*d4726bddSHONG Yifanrules. For example: 48*d4726bddSHONG Yifan 49*d4726bddSHONG Yifan```python 50*d4726bddSHONG Yifanload("//crate_universe:defs.bzl", "crate", "crates_repository") 51*d4726bddSHONG Yifan 52*d4726bddSHONG Yifancrates_repository( 53*d4726bddSHONG Yifan name = "crates_io", 54*d4726bddSHONG Yifan annotations = { 55*d4726bddSHONG Yifan "protoc-gen-prost": [crate.annotation( 56*d4726bddSHONG Yifan gen_binaries = ["protoc-gen-prost"], 57*d4726bddSHONG Yifan patch_args = [ 58*d4726bddSHONG Yifan "-p1", 59*d4726bddSHONG Yifan ], 60*d4726bddSHONG Yifan patches = [ 61*d4726bddSHONG Yifan # Note: You will need to use this patch until a version greater than `0.2.2` of 62*d4726bddSHONG Yifan # `protoc-gen-prost` is released. 63*d4726bddSHONG Yifan "@rules_rust//proto/prost/private/3rdparty/patches:protoc-gen-prost.patch", 64*d4726bddSHONG Yifan ], 65*d4726bddSHONG Yifan )], 66*d4726bddSHONG Yifan "protoc-gen-tonic": [crate.annotation( 67*d4726bddSHONG Yifan gen_binaries = ["protoc-gen-tonic"], 68*d4726bddSHONG Yifan )], 69*d4726bddSHONG Yifan }, 70*d4726bddSHONG Yifan cargo_lockfile = "Cargo.Bazel.lock", 71*d4726bddSHONG Yifan mode = "remote", 72*d4726bddSHONG Yifan packages = { 73*d4726bddSHONG Yifan "prost": crate.spec( 74*d4726bddSHONG Yifan version = "0", 75*d4726bddSHONG Yifan ), 76*d4726bddSHONG Yifan "prost-types": crate.spec( 77*d4726bddSHONG Yifan version = "0", 78*d4726bddSHONG Yifan ), 79*d4726bddSHONG Yifan "protoc-gen-prost": crate.spec( 80*d4726bddSHONG Yifan version = "0", 81*d4726bddSHONG Yifan ), 82*d4726bddSHONG Yifan "protoc-gen-tonic": crate.spec( 83*d4726bddSHONG Yifan version = "0", 84*d4726bddSHONG Yifan ), 85*d4726bddSHONG Yifan "tonic": crate.spec( 86*d4726bddSHONG Yifan version = "0", 87*d4726bddSHONG Yifan ), 88*d4726bddSHONG Yifan }, 89*d4726bddSHONG Yifan repository_name = "rules_rust_prost", 90*d4726bddSHONG Yifan tags = ["manual"], 91*d4726bddSHONG Yifan) 92*d4726bddSHONG Yifan``` 93*d4726bddSHONG Yifan 94*d4726bddSHONG YifanYou can then define a toolchain with the `rust_prost_toolchain` rule which uses the crates 95*d4726bddSHONG Yifandefined above. For example: 96*d4726bddSHONG Yifan 97*d4726bddSHONG Yifan```python 98*d4726bddSHONG Yifanload("@rules_rust//proto/prost:defs.bzl", "rust_prost_toolchain") 99*d4726bddSHONG Yifanload("@rules_rust//rust:defs.bzl", "rust_library_group") 100*d4726bddSHONG Yifan 101*d4726bddSHONG Yifanrust_library_group( 102*d4726bddSHONG Yifan name = "prost_runtime", 103*d4726bddSHONG Yifan deps = [ 104*d4726bddSHONG Yifan "@crates_io//:prost", 105*d4726bddSHONG Yifan ], 106*d4726bddSHONG Yifan) 107*d4726bddSHONG Yifan 108*d4726bddSHONG Yifanrust_library_group( 109*d4726bddSHONG Yifan name = "tonic_runtime", 110*d4726bddSHONG Yifan deps = [ 111*d4726bddSHONG Yifan ":prost_runtime", 112*d4726bddSHONG Yifan "@crates_io//:tonic", 113*d4726bddSHONG Yifan ], 114*d4726bddSHONG Yifan) 115*d4726bddSHONG Yifan 116*d4726bddSHONG Yifanrust_prost_toolchain( 117*d4726bddSHONG Yifan name = "prost_toolchain_impl", 118*d4726bddSHONG Yifan prost_plugin = "@crates_io//:protoc-gen-prost__protoc-gen-prost", 119*d4726bddSHONG Yifan prost_runtime = ":prost_runtime", 120*d4726bddSHONG Yifan prost_types = "@crates_io//:prost-types", 121*d4726bddSHONG Yifan proto_compiler = "@com_google_protobuf//:protoc", 122*d4726bddSHONG Yifan tonic_plugin = "@crates_io//:protoc-gen-tonic__protoc-gen-tonic", 123*d4726bddSHONG Yifan tonic_runtime = ":tonic_runtime", 124*d4726bddSHONG Yifan) 125*d4726bddSHONG Yifan 126*d4726bddSHONG Yifantoolchain( 127*d4726bddSHONG Yifan name = "prost_toolchain", 128*d4726bddSHONG Yifan toolchain = "prost_toolchain_impl", 129*d4726bddSHONG Yifan toolchain_type = "@rules_rust//proto/prost:toolchain_type", 130*d4726bddSHONG Yifan) 131*d4726bddSHONG Yifan``` 132*d4726bddSHONG Yifan 133*d4726bddSHONG YifanLastly, you must register the toolchain in your `WORKSPACE` file. For example: 134*d4726bddSHONG Yifan 135*d4726bddSHONG Yifan```python 136*d4726bddSHONG Yifanregister_toolchains("//toolchains:prost_toolchain") 137*d4726bddSHONG Yifan``` 138*d4726bddSHONG Yifan 139*d4726bddSHONG Yifan## Rust-Protobuf Setup 140*d4726bddSHONG Yifan 141*d4726bddSHONG YifanTo use the Rust proto rules, add the following to your `WORKSPACE` file to add the 142*d4726bddSHONG Yifanexternal repositories for the Rust proto toolchain (in addition to the [rust rules setup](..)): 143*d4726bddSHONG Yifan 144*d4726bddSHONG Yifan```python 145*d4726bddSHONG Yifanload("@rules_rust//proto/protobuf:repositories.bzl", "rust_proto_protobuf_dependencies", "rust_proto_protobuf_register_toolchains") 146*d4726bddSHONG Yifan 147*d4726bddSHONG Yifanrust_proto_protobuf_dependencies() 148*d4726bddSHONG Yifan 149*d4726bddSHONG Yifanrust_proto_protobuf_register_toolchains() 150*d4726bddSHONG Yifan 151*d4726bddSHONG Yifanload("@rules_rust//proto/protobuf:transitive_repositories.bzl", "rust_proto_protobuf_transitive_repositories") 152*d4726bddSHONG Yifan 153*d4726bddSHONG Yifanrust_proto_protobuf_transitive_repositories() 154*d4726bddSHONG Yifan``` 155*d4726bddSHONG Yifan 156*d4726bddSHONG YifanThis will load the required dependencies for the [`rust-protobuf`] rules. It will also 157*d4726bddSHONG Yifanregister a default toolchain for the `rust_proto_library` and `rust_grpc_library` rules. 158*d4726bddSHONG Yifan 159*d4726bddSHONG YifanTo customize the `rust_proto_library` and `rust_grpc_library` toolchain, please see the section 160*d4726bddSHONG Yifan[Customizing `rust-protobuf` Dependencies](#custom-proto-deps). 161*d4726bddSHONG Yifan 162*d4726bddSHONG YifanFor additional information about Bazel toolchains, see [here](https://docs.bazel.build/versions/master/toolchains.html). 163*d4726bddSHONG Yifan 164*d4726bddSHONG Yifan#### <a name="custom-proto-deps">Customizing `rust-protobuf` Dependencies 165*d4726bddSHONG Yifan 166*d4726bddSHONG YifanThese rules depend on the [`protobuf`](https://crates.io/crates/protobuf) and 167*d4726bddSHONG Yifanthe [`grpc`](https://crates.io/crates/grpc) crates in addition to the [protobuf 168*d4726bddSHONG Yifancompiler](https://github.com/google/protobuf). To obtain these crates, 169*d4726bddSHONG Yifan`rust_proto_repositories` imports the given crates using BUILD files generated with 170*d4726bddSHONG Yifan[crate_universe](./crate_universe.md). 171*d4726bddSHONG Yifan 172*d4726bddSHONG YifanIf you want to either change the protobuf and gRPC rust compilers, or to 173*d4726bddSHONG Yifansimply use [crate_universe](./crate_universe.md) in a more 174*d4726bddSHONG Yifancomplex scenario (with more dependencies), you must redefine those 175*d4726bddSHONG Yifandependencies. 176*d4726bddSHONG Yifan 177*d4726bddSHONG YifanTo do this, once you've imported the needed dependencies (see our 178*d4726bddSHONG Yifan[@rules_rust//proto/3rdparty/BUILD.bazel](https://github.com/bazelbuild/rules_rust/blob/main/proto/3rdparty/BUILD.bazel) 179*d4726bddSHONG Yifanfile to see the default dependencies), you need to create your own toolchain. 180*d4726bddSHONG YifanTo do so you can create a BUILD file with your toolchain definition, for example: 181*d4726bddSHONG Yifan 182*d4726bddSHONG Yifan```python 183*d4726bddSHONG Yifanload("@rules_rust//proto:toolchain.bzl", "rust_proto_toolchain") 184*d4726bddSHONG Yifan 185*d4726bddSHONG Yifanrust_proto_toolchain( 186*d4726bddSHONG Yifan name = "proto-toolchain-impl", 187*d4726bddSHONG Yifan # Path to the protobuf compiler. 188*d4726bddSHONG Yifan protoc = "@com_google_protobuf//:protoc", 189*d4726bddSHONG Yifan # Protobuf compiler plugin to generate rust gRPC stubs. 190*d4726bddSHONG Yifan grpc_plugin = "//3rdparty/crates:cargo_bin_protoc_gen_rust_grpc", 191*d4726bddSHONG Yifan # Protobuf compiler plugin to generate rust protobuf stubs. 192*d4726bddSHONG Yifan proto_plugin = "//3rdparty/crates:cargo_bin_protoc_gen_rust", 193*d4726bddSHONG Yifan) 194*d4726bddSHONG Yifan 195*d4726bddSHONG Yifantoolchain( 196*d4726bddSHONG Yifan name = "proto-toolchain", 197*d4726bddSHONG Yifan toolchain = ":proto-toolchain-impl", 198*d4726bddSHONG Yifan toolchain_type = "@rules_rust//proto/protobuf:toolchain_type", 199*d4726bddSHONG Yifan) 200*d4726bddSHONG Yifan``` 201*d4726bddSHONG Yifan 202*d4726bddSHONG YifanNow that you have your own toolchain, you need to register it by 203*d4726bddSHONG Yifaninserting the following statement in your `WORKSPACE` file: 204*d4726bddSHONG Yifan 205*d4726bddSHONG Yifan```python 206*d4726bddSHONG Yifanregister_toolchains("//my/toolchains:proto-toolchain") 207*d4726bddSHONG Yifan``` 208*d4726bddSHONG Yifan 209*d4726bddSHONG YifanFinally, you might want to set the `rust_deps` attribute in 210*d4726bddSHONG Yifan`rust_proto_library` and `rust_grpc_library` to change the compile-time 211*d4726bddSHONG Yifandependencies: 212*d4726bddSHONG Yifan 213*d4726bddSHONG Yifan```python 214*d4726bddSHONG Yifanrust_proto_library( 215*d4726bddSHONG Yifan ... 216*d4726bddSHONG Yifan rust_deps = ["//3rdparty/crates:protobuf"], 217*d4726bddSHONG Yifan ... 218*d4726bddSHONG Yifan) 219*d4726bddSHONG Yifan 220*d4726bddSHONG Yifanrust_grpc_library( 221*d4726bddSHONG Yifan ... 222*d4726bddSHONG Yifan rust_deps = [ 223*d4726bddSHONG Yifan "//3rdparty/crates:protobuf", 224*d4726bddSHONG Yifan "//3rdparty/crates:grpc", 225*d4726bddSHONG Yifan "//3rdparty/crates:tls_api", 226*d4726bddSHONG Yifan "//3rdparty/crates:tls_api_stub", 227*d4726bddSHONG Yifan ], 228*d4726bddSHONG Yifan ... 229*d4726bddSHONG Yifan) 230*d4726bddSHONG Yifan``` 231*d4726bddSHONG Yifan 232*d4726bddSHONG Yifan__Note__: Ideally, we would inject those dependencies from the toolchain, 233*d4726bddSHONG Yifanbut due to [bazelbuild/bazel#6889](https://github.com/bazelbuild/bazel/issues/6889) 234*d4726bddSHONG Yifanall dependencies added via the toolchain ends-up being in the wrong 235*d4726bddSHONG Yifanconfiguration. 236*d4726bddSHONG Yifan 237*d4726bddSHONG Yifan--- 238*d4726bddSHONG Yifan--- 239*d4726bddSHONG Yifan 240*d4726bddSHONG Yifan]]# 241