Support incompatible enable proto toolchain resolution (#2741)

This allows using a shared (generally pre-built) protoc definition,
rather than needing to supply one via a label.

We allow (but deprecate) users to still bring along their own protoc as
a label, but if they want to do so, they will need to ensure they have
the correct repositories registered in order to build/bring their
protoc, rather than us setting them up by default.
This commit is contained in:
Daniel Wagner-Hall 2024-07-19 10:10:10 +02:00 committed by GitHub
parent ca7a3df6d2
commit ffe8eff049
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 1091 additions and 49 deletions

View File

@ -765,6 +765,12 @@ tasks:
working_directory: examples/bzlmod/proto
build_targets:
- "//..."
bzlmod_proto:
name: Proto and Prost with prebuilt protoc with bzlmod
platform: ubuntu2004
working_directory: examples/bzlmod/proto_with_toolchain
build_targets:
- "//..."
compile_one_dependency:
name: --compile_one_dependency flag
platform: ubuntu2004

View File

@ -27,7 +27,7 @@ bazel_dep(
)
bazel_dep(
name = "rules_proto",
version = "5.3.0-21.7",
version = "6.0.2",
)
bazel_dep(
name = "apple_support",
@ -68,7 +68,6 @@ use_repo(
"cargo_bazel.buildifier-linux-amd64",
"cargo_bazel.buildifier-linux-arm64",
"cargo_bazel.buildifier-windows-amd64.exe",
"com_google_googleapis",
"cui",
"cui__anyhow-1.0.75",
"cui__camino-1.1.6",

View File

@ -11,6 +11,7 @@ bzl_library(
"@com_google_protobuf//:bzl_srcs",
],
deps = [
"@bazel_features//:deps",
"@bazel_features//:features",
"@bazel_skylib//lib:paths",
"@bazel_skylib//lib:selects",

View File

@ -8,5 +8,5 @@ bazel_dep(
)
bazel_dep(
name = "bazel_features",
version = "1.11.0",
version = "1.14.0",
)

View File

@ -809,7 +809,7 @@ Rust Prost toolchain rule.
| <a id="rust_prost_toolchain-prost_plugin_flag"></a>prost_plugin_flag | Prost plugin flag format. (e.g. `--plugin=protoc-gen-prost=%s`) | String | optional | `"--plugin=protoc-gen-prost=%s"` |
| <a id="rust_prost_toolchain-prost_runtime"></a>prost_runtime | The Prost runtime crates to use. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="rust_prost_toolchain-prost_types"></a>prost_types | The Prost types crates to use. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="rust_prost_toolchain-proto_compiler"></a>proto_compiler | The protoc compiler to use. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="rust_prost_toolchain-proto_compiler"></a>proto_compiler | The protoc compiler to use. Note that this attribute is deprecated - prefer to use --incompatible_enable_proto_toolchain_resolution. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="rust_prost_toolchain-tonic_opts"></a>tonic_opts | Additional options to add to Tonic. | List of strings | optional | `[]` |
| <a id="rust_prost_toolchain-tonic_plugin"></a>tonic_plugin | Additional plugins to add to Tonic. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="rust_prost_toolchain-tonic_plugin_flag"></a>tonic_plugin_flag | Tonic plugin flag format. (e.g. `--plugin=protoc-gen-tonic=%s`)) | String | optional | `"--plugin=protoc-gen-tonic=%s"` |
@ -1778,14 +1778,18 @@ This macro should be called immediately after the `rust_protobuf_dependencies` m
rust_proto_protobuf_dependencies(<a href="#rust_proto_protobuf_dependencies-bzlmod">bzlmod</a>)
</pre>
Sets up dependencies for rules_rust's proto support.
**PARAMETERS**
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="rust_proto_protobuf_dependencies-bzlmod"></a>bzlmod | <p align="center"> - </p> | `False` |
| <a id="rust_proto_protobuf_dependencies-bzlmod"></a>bzlmod | Whether this function is being called from a bzlmod context rather than a workspace context. | `False` |
**RETURNS**
A list of structs containing information about root module deps to report to bzlmod's extension_metadata.
<a id="rust_proto_protobuf_register_toolchains"></a>

View File

@ -319,7 +319,7 @@ Rust Prost toolchain rule.
| <a id="rust_prost_toolchain-prost_plugin_flag"></a>prost_plugin_flag | Prost plugin flag format. (e.g. `--plugin=protoc-gen-prost=%s`) | String | optional | `"--plugin=protoc-gen-prost=%s"` |
| <a id="rust_prost_toolchain-prost_runtime"></a>prost_runtime | The Prost runtime crates to use. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="rust_prost_toolchain-prost_types"></a>prost_types | The Prost types crates to use. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="rust_prost_toolchain-proto_compiler"></a>proto_compiler | The protoc compiler to use. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="rust_prost_toolchain-proto_compiler"></a>proto_compiler | The protoc compiler to use. Note that this attribute is deprecated - prefer to use --incompatible_enable_proto_toolchain_resolution. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="rust_prost_toolchain-tonic_opts"></a>tonic_opts | Additional options to add to Tonic. | List of strings | optional | `[]` |
| <a id="rust_prost_toolchain-tonic_plugin"></a>tonic_plugin | Additional plugins to add to Tonic. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
| <a id="rust_prost_toolchain-tonic_plugin_flag"></a>tonic_plugin_flag | Tonic plugin flag format. (e.g. `--plugin=protoc-gen-tonic=%s`)) | String | optional | `"--plugin=protoc-gen-tonic=%s"` |
@ -434,14 +434,18 @@ This macro should be called immediately after the `rust_protobuf_dependencies` m
rust_proto_protobuf_dependencies(<a href="#rust_proto_protobuf_dependencies-bzlmod">bzlmod</a>)
</pre>
Sets up dependencies for rules_rust's proto support.
**PARAMETERS**
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="rust_proto_protobuf_dependencies-bzlmod"></a>bzlmod | <p align="center"> - </p> | `False` |
| <a id="rust_proto_protobuf_dependencies-bzlmod"></a>bzlmod | Whether this function is being called from a bzlmod context rather than a workspace context. | `False` |
**RETURNS**
A list of structs containing information about root module deps to report to bzlmod's extension_metadata.
<a id="rust_proto_protobuf_register_toolchains"></a>

View File

@ -11,6 +11,10 @@ bazel_dep(name = "bazel_skylib", version = "1.7.1")
# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")
local_path_override(
module_name = "rules_rust",
path = "../../..",
)
###############################################################################
# T O O L C H A I N S

View File

@ -8,6 +8,10 @@ module(
###############################################################################
# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")
local_path_override(
module_name = "rules_rust",
path = "../../..",
)
###############################################################################
# T O O L C H A I N S

View File

@ -5,6 +5,10 @@ module(
# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")
local_path_override(
module_name = "rules_rust",
path = "../../..",
)
# Rules for cross compilation
bazel_dep(name = "toolchains_musl", version = "0.1.16", dev_dependency = True)

View File

@ -8,6 +8,10 @@ module(
###############################################################################
# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")
local_path_override(
module_name = "rules_rust",
path = "../../..",
)
###############################################################################
# T O O L C H A I N S

View File

@ -8,6 +8,10 @@ module(
###############################################################################
# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")
local_path_override(
module_name = "rules_rust",
path = "../../..",
)
#
# Rules for protobuf / gRPC

View File

@ -21,7 +21,6 @@ rust_prost_toolchain(
prost_plugin = "@crates//:protoc-gen-prost__protoc-gen-prost",
prost_runtime = ":prost_runtime",
prost_types = "@crates//:prost-types",
proto_compiler = "@protobuf//:protoc",
tonic_plugin = "@crates//:protoc-gen-tonic__protoc-gen-tonic",
tonic_runtime = ":tonic_runtime",
)

View File

@ -0,0 +1,9 @@
# Required on windows
common --enable_platform_specific_config
startup --windows_enable_symlinks
build:windows --enable_runfiles
# Required for cargo_build_script support before Bazel 7
build --incompatible_merge_fixed_and_default_shell_env
common --incompatible_enable_proto_toolchain_resolution

View File

@ -0,0 +1 @@
../.bazelversion

View File

@ -0,0 +1,5 @@
/bazel-*
.DS_Store
/proto/.DS_Store
/proto/grpc_server/.DS_Store
/proto/proto_bindings/.DS_Store

View File

@ -0,0 +1,6 @@
config_setting(
name = "release",
values = {
"compilation_mode": "opt",
},
)

View File

@ -0,0 +1,42 @@
[workspace]
resolver = "2"
members = [
"proto_bindings",
"grpc_server",
"grpc_client",
]
[workspace.package]
edition = "2021"
rust-version = "1.78.0"
readme = "README.md"
[workspace.dependencies]
# Internal crates
proto_bindings = { path = "proto_bindings" }
# External crates
prost = { version = "0.12.6" }
prost-types = { version = "0.12.6", default-features = false }
tonic = { version = "0.11.0", features = ["transport"] }
tonic-build = "0.11.0"
tokio = { version = "1.38", default-features = false, features = ["macros", "net", "rt-multi-thread", "signal"] }
# Optimize all crates
[profile.release]
opt-level = 3
strip = true # Automatically strip debug symbols from the binary
lto = true # Enable Link Time Optimization (LTO)
codegen-units = 1 # Reduce Parallel Code Generation Units to Increase Optimization
# There's a Cargo feature named profile-overrides
# that lets you override the optimization level of dependencies.
# https://docs.rust-embedded.org/book/unsorted/speed-vs-size.html
[profile.release.package."*"]
opt-level = 3
strip = 'debuginfo' # Automatically strip debug infos from the binary to reduce size
codegen-units = 1 # Reduce Parallel Code Generation Units to Increase Optimization

View File

@ -0,0 +1,133 @@
module(
name = "grpc-client-server",
version = "0.0.0",
)
###############################################################################
# B A Z E L C E N T R A L R E G I S T R Y # https://registry.bazel.build/
###############################################################################
# https://github.com/bazelbuild/rules_rust/releases
bazel_dep(name = "rules_rust", version = "0.46.0")
local_path_override(
module_name = "rules_rust",
path = "../../..",
)
#
# Rules for protobuf / gRPC
# https://github.com/bazelbuild/rules_proto/releases
bazel_dep(name = "rules_proto", version = "6.0.2")
# https://github.com/aspect-build/toolchains_protoc/releases
bazel_dep(name = "toolchains_protoc", version = "0.3.1")
# https://registry.bazel.build/modules/protobuf
bazel_dep(name = "protobuf", version = "27.1")
# https://github.com/bazel-contrib/toolchains_llvm
bazel_dep(name = "toolchains_llvm", version = "1.0.0")
###############################################################################
# L L V M
# https://github.com/bazel-contrib/toolchains_llvm/blob/master/tests/MODULE.bazel
###############################################################################
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
# LLVM Versions and platforms
# https://github.com/bazel-contrib/toolchains_llvm/blob/master/toolchain/internal/llvm_distributions.bzl
LLVM_VERSIONS = {
"": "16.0.0",
"darwin-aarch64": "16.0.3",
"darwin-x86_64": "15.0.7",
}
# Host LLVM toolchain.
llvm.toolchain(
name = "llvm_toolchain",
llvm_versions = LLVM_VERSIONS,
)
use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm")
register_toolchains("@llvm_toolchain//:all")
###############################################################################
# T O O L C H A I N S
###############################################################################
# Rust toolchain
RUST_EDITION = "2021"
RUST_VERSION = "1.79.0"
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
edition = RUST_EDITION,
versions = [RUST_VERSION],
)
use_repo(rust, "rust_toolchains")
register_toolchains("@rust_toolchains//:all")
# Proto toolchain
register_toolchains("@rules_rust//proto/protobuf:default-proto-toolchain")
# Custom Prost toolchain
register_toolchains("@//build/prost_toolchain")
###############################################################################
# R U S T C R A T E S
###############################################################################
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
#
# protobuf / gRPC dependencies
crate.spec(
package = "prost",
version = "0.12",
)
crate.spec(
default_features = False,
package = "prost-types",
version = "0.12",
)
crate.spec(
features = ["transport"],
package = "tonic",
version = "0.11",
)
crate.spec(
package = "tonic-build",
version = "0.11",
)
crate.spec(
package = "protoc-gen-prost",
version = "0.3.1",
)
crate.annotation(
crate = "protoc-gen-prost",
gen_binaries = ["protoc-gen-prost"],
)
crate.spec(
package = "protoc-gen-tonic",
version = "0.4.0",
)
crate.annotation(
crate = "protoc-gen-tonic",
gen_binaries = ["protoc-gen-tonic"],
)
#
# External crates
crate.spec(
default_features = False,
features = [
"macros",
"net",
"rt-multi-thread",
"signal",
],
package = "tokio",
version = "1.38",
)
crate.from_specs()
use_repo(crate, "crates")

View File

@ -0,0 +1,221 @@
# gRPC Client & Server
This example shows how to build a gRPC server and client in Rust with Bazel.
There is a Cargo Workspace configuration and a Bazelmod configuration. Furthermore,
all binary targets apply optimization from the [compiler optimization example](../03-comp-opt).
To run the example with Cargo, open one terminal and start the server with:
`
cargo run --bin grpc_server
`
And, in a second terminal, to run the client:
`
cargo run --bin grpc_client
`
The equivalent Bazel targets are:
Server:
`bazel run //grpc_server:bin`
Client:
`bazel run //grpc_client:bin`
## Setup
The Prost and Tonic rules do not specify a default toolchain in order to avoid mismatched dependency issues.
While the Tonic toolchain works out of the box when its dependencies are matched, however,
Prost requires a custom toolchain that you have to define.
The setup requires three steps to complete:
1. Configure rules and dependencies in MODULE.bazel
2. Configure a custom Prost toolchain
3. Register custom Prost toolchain.
To keep the build hermetic, we use the LLVM Clang compiler to compile all C/C++ dependencies.
### 1) Configure rules and dependencies
In your MODULE.bazel, you add the following:
```starlark
# rules for proto
###############################################################################
# https://github.com/bazelbuild/rules_proto/releases
bazel_dep(name = "rules_proto", version = "6.0.2")
# https://github.com/aspect-build/toolchains_protoc/releases
bazel_dep(name = "toolchains_protoc", version = "0.3.1")
# https://registry.bazel.build/modules/protobuf
bazel_dep(name = "protobuf", version = "27.1")
# rules for LLVM
# https://github.com/bazel-contrib/toolchains_llvm
bazel_dep(name = "toolchains_llvm", version = "1.0.0")
# 1 Register LLVM
###############################################################################
# L L V M
# https://github.com/bazel-contrib/toolchains_llvm/blob/master/tests/MODULE.bazel
###############################################################################
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm")
LLVM_VERSIONS = { "": "16.0.0",}
# LLVM toolchain.
llvm.toolchain(
name = "llvm_toolchain",
llvm_versions = LLVM_VERSIONS,
)
use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm")
register_toolchains("@llvm_toolchain//:all")
# 2 Register Proto toolchain
###############################################################################
# Proto toolchain
register_toolchains("@rules_rust//proto/protobuf:default-proto-toolchain")
# Custom Prost toolchain will be added later. See next section
# 3 Register proto / prost / tonic crates
###############################################################################
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
# protobufs / gRPC
crate.spec(
package = "prost",
version = "0.12",
)
crate.spec(
default_features = False,
package = "prost-types",
version = "0.12",
)
crate.spec(
features = ["transport"],
package = "tonic",
version = "0.11",
)
crate.spec(
package = "tonic-build",
version = "0.11",
)
crate.spec(
package = "protoc-gen-prost",
version = "0.3.1",
)
crate.annotation(
crate = "protoc-gen-prost",
gen_binaries = ["protoc-gen-prost"],
)
crate.spec(
package = "protoc-gen-tonic",
version = "0.4.0",
)
crate.annotation(
crate = "protoc-gen-tonic",
gen_binaries = ["protoc-gen-tonic"],
)
# Other Rust dependencies ...
crate.from_specs()
use_repo(crate, "crates")
```
### 2) Configure a custom Prost toolchain
Configuring a custom Prost toolchain is straightforward, you create a new folder with an empty BUILD.bazl file, and add
the toolchain definition.
As your Bazel setup grows over time, it is a best practice to put all custom macros, rules, and toolchains in a
dedicated folder, for example: `build/`.
Suppose you have your BUILD.bazl file in `build/prost_toolchain/BUILD.bazel`, then add the following content:
```starlark
load("@rules_rust//proto/prost:defs.bzl", "rust_prost_toolchain")
load("@rules_rust//rust:defs.bzl", "rust_library_group")
rust_library_group(
name = "prost_runtime",
deps = [
"@crates//:prost",
],
)
rust_library_group(
name = "tonic_runtime",
deps = [
":prost_runtime",
"@crates//:tonic",
],
)
rust_prost_toolchain(
name = "prost_toolchain_impl",
prost_plugin = "@crates//:protoc-gen-prost__protoc-gen-prost",
prost_runtime = ":prost_runtime",
prost_types = "@crates//:prost-types",
proto_compiler = "@protobuf//:protoc",
tonic_plugin = "@crates//:protoc-gen-tonic__protoc-gen-tonic",
tonic_runtime = ":tonic_runtime",
)
toolchain(
name = "prost_toolchain",
toolchain = "prost_toolchain_impl",
toolchain_type = "@rules_rust//proto/prost:toolchain_type",
)
```
The Prost and Tonic dependencies are pulled from the previously configured
crate dependencies in the MODULE file. With this custom toolchain in place, the last step is to register it.
### 3. Register custom Prost toolchain.
In your MODULE.bazel file, locate your toolchains and add the following entry right below the proto toolchain.
```starlark
# 2 Register Proto toolchain
###############################################################################
# Proto toolchain
register_toolchains("@rules_rust//proto/protobuf:default-proto-toolchain")
# Custom Prost toolchain
register_toolchains("@//build/prost_toolchain")
```
Pay attention to the path, `build/prost_toolchain` because if your toolchain
is in a different folder, you have to update this path to make the build work.
## Usage
Once the setup has been completed, you use the proto & prost targets as you normally do. For example, to configure rust
bindings for a proto file, just add the target:
```starlark
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_rust//proto/prost:defs.bzl", "rust_prost_library")
# Build proto files
# https://bazelbuild.github.io/rules_rust/rust_proto.html#rust_proto_library
proto_library(
name = "proto_bindings",
srcs = [
"proto/helloworld.proto",
],
)
# Generate Rust bindings from the generated proto files
# https://bazelbuild.github.io/rules_rust/rust_proto.html#rust_prost_library
rust_prost_library(
name = "rust_proto",
proto = ":proto_bindings",
visibility = ["//visibility:public"],
)
```
From there, you
just [follow the target documentation](https://bazelbuild.github.io/rules_rust/rust_proto.html#rust_proto_library).

View File

@ -0,0 +1,32 @@
load("@rules_rust//proto/prost:defs.bzl", "rust_prost_toolchain")
load("@rules_rust//rust:defs.bzl", "rust_library_group")
rust_library_group(
name = "prost_runtime",
deps = [
"@crates//:prost",
],
)
rust_library_group(
name = "tonic_runtime",
deps = [
":prost_runtime",
"@crates//:tonic",
],
)
rust_prost_toolchain(
name = "prost_toolchain_impl",
prost_plugin = "@crates//:protoc-gen-prost__protoc-gen-prost",
prost_runtime = ":prost_runtime",
prost_types = "@crates//:prost-types",
tonic_plugin = "@crates//:protoc-gen-tonic__protoc-gen-tonic",
tonic_runtime = ":tonic_runtime",
)
toolchain(
name = "prost_toolchain",
toolchain = "prost_toolchain_impl",
toolchain_type = "@rules_rust//proto/prost:toolchain_type",
)

View File

@ -0,0 +1,47 @@
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_doc", "rust_doc_test")
# Build binary
# https://bazelbuild.github.io/rules_rust/defs.html#rust_binary
rust_binary(
name = "bin",
srcs = glob([
"src/*.rs",
]),
crate_root = "src/main.rs",
rustc_flags = select({
"//:release": [
"-Clto",
"-Ccodegen-units=1",
"-Cpanic=abort",
"-Copt-level=3",
"-Cstrip=symbols",
],
"//conditions:default": [
"-Copt-level=0",
],
}),
visibility = ["//visibility:public"],
deps = [
# Internal crates
"//proto_bindings:rust_proto",
# External crates
"@crates//:tokio",
"@crates//:tonic",
],
)
# Build documentation
# https://bazelbuild.github.io/rules_rust/rust_doc.html
rust_doc(
name = "client_doc",
crate = ":bin",
visibility = ["//visibility:public"],
)
# Test documentation
# https://bazelbuild.github.io/rules_rust/rust_doc.html#rust_doc_test
rust_doc_test(
name = "client_doc_test",
crate = ":bin",
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,19 @@
[package]
name = "grpc_client"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
readme.workspace = true
[[bin]]
name = "grpc_client"
path = "src/main.rs"
[dependencies]
# Internal crates
proto_bindings = { workspace = true }
# External crates
tokio = { workspace = true }
tonic = { workspace = true }

View File

@ -0,0 +1,23 @@
use proto_bindings::proto::greeter_client::GreeterClient;
use proto_bindings::proto::HelloRequest;
// https://github.com/hyperium/tonic/blob/master/examples/src/helloworld/client.rs
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = GreeterClient::connect("http://[::1]:5042")
.await
.expect("[Client]: Failed to connect to server.");
let request = tonic::Request::new(HelloRequest {
name: "Hello gRPC".into(),
});
let response = client
.say_hello(request)
.await
.expect("[Client]: Failed to get a response from the server");
println!("RESPONSE={:?}", response);
Ok(())
}

View File

@ -0,0 +1,61 @@
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_doc", "rust_doc_test", "rust_test_suite")
# Build binary
# https://bazelbuild.github.io/rules_rust/defs.html#rust_binary
rust_binary(
name = "bin",
srcs = glob([
"src/*.rs",
]),
crate_root = "src/main.rs",
rustc_flags = select({
"//:release": [
"-Clto",
"-Ccodegen-units=1",
"-Cpanic=abort",
"-Copt-level=3",
"-Cstrip=symbols",
],
"//conditions:default": [
"-Copt-level=0",
],
}),
visibility = ["//visibility:public"],
deps = [
# Internal crates
"//proto_bindings:rust_proto",
# External crates
"@crates//:tokio",
"@crates//:tonic",
],
)
# Build documentation
# https://bazelbuild.github.io/rules_rust/rust_doc.html
rust_doc(
name = "server_doc",
crate = ":bin",
visibility = ["//visibility:public"],
)
# Test documentation
# https://bazelbuild.github.io/rules_rust/rust_doc.html#rust_doc_test
rust_doc_test(
name = "server_doc_test",
crate = ":bin",
visibility = ["//visibility:public"],
)
rust_test_suite(
name = "demo_tests",
srcs = glob([
"tests/*_tests.rs",
]),
tags = ["unit"],
visibility = ["//visibility:public"],
deps = [
# Crate to test
"//proto_bindings:rust_proto",
# External crates
],
)

View File

@ -0,0 +1,19 @@
[package]
name = "grpc_server"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
readme.workspace = true
[[bin]]
name = "grpc_server"
path = "src/main.rs"
[dependencies]
# Internal crates
proto_bindings = { workspace = true }
# External crates
tokio = { workspace = true }
tonic = { workspace = true }

View File

@ -0,0 +1,40 @@
use std::error::Error;
use tonic::transport::Server;
use proto_bindings::proto::greeter_server::GreeterServer;
use crate::server::MyGreeter;
mod server;
mod shutdown_utils;
// https://github.com/hyperium/tonic/blob/master/examples/src/helloworld/server.rs
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let addr = "[::1]:5042"
.parse()
.expect("[Server]: Failed to parse socket address");
let grpc_svc = GreeterServer::new(MyGreeter::new());
// Shutdown signal handler
let signal = shutdown_utils::signal_handler("gRPC Greeter server");
let grpc_server = Server::builder()
.add_service(grpc_svc)
.serve_with_shutdown(addr, signal);
let grpc_handle = tokio::spawn(grpc_server);
println!("GreeterServer listening on {}", addr);
match tokio::try_join!(grpc_handle) {
Ok(_) => {}
Err(e) => {
println!("[Server]: Error: Failed to start gRPC Greeter server.");
println!("[Server]: Error: {:?}", e);
}
}
Ok(())
}

View File

@ -0,0 +1,28 @@
use tonic::{Request, Response, Status};
use proto_bindings::proto::greeter_server::Greeter;
use proto_bindings::proto::{HelloReply, HelloRequest};
#[derive(Copy, Clone)]
pub struct MyGreeter {}
impl MyGreeter {
pub fn new() -> Self {
Self {}
}
}
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(
&self,
request: Request<HelloRequest>,
) -> Result<Response<HelloReply>, Status> {
println!("Got a request from {:?}", request.remote_addr());
let reply = HelloReply {
message: format!("Hello {}!", request.into_inner().name),
};
Ok(Response::new(reply))
}
}

View File

@ -0,0 +1,54 @@
//
/// Registers a signal handler that waits for a signal that indicates a shutdown request.
// https://stackoverflow.com/questions/77585473/rust-tokio-how-to-handle-more-signals-than-just-sigint-i-e-sigquit?noredirect=1#comment136778587_77585473
pub async fn signal_handler(svc: &str) {
wait_for_signal_impl(svc).await
}
/// Waits for a signal that requests a graceful shutdown. Supports the following signals on unix:
/// * SIGTERM
/// * SIGINT (Ctrl-C)
/// * SIGQUIT
/// * SIGHUP
#[cfg(unix)]
async fn wait_for_signal_impl(svc: &str) {
use tokio::signal::unix::{signal, SignalKind};
// Docs: https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
let mut signal_terminate = signal(SignalKind::terminate()).unwrap();
let mut signal_interrupt = signal(SignalKind::interrupt()).unwrap();
let mut signal_quit = signal(SignalKind::quit()).unwrap();
let mut signal_hang = signal(SignalKind::hangup()).unwrap();
// https://docs.rs/tokio/latest/tokio/macro.select.html
tokio::select! {
_ = signal_terminate.recv() => println!("* {svc} received SIGTERM"),
_ = signal_interrupt.recv() => println!("* {svc} received SIGINT"),
_ = signal_quit.recv() => println!("* {svc} received SIGQUIT"),
_ = signal_hang.recv() => println!(" * {svc} received SIGHUP"),
}
}
/// Waits for a signal that requests a graceful shutdown. Supports the following signals on Windows:
/// * ctrl_c
/// * ctrl_break
/// * ctrl_close
/// * ctrl_shutdown
#[cfg(windows)]
async fn wait_for_signal_impl(svc: &str) {
use tokio::signal::windows;
// Docs: https://learn.microsoft.com/en-us/windows/console/handlerroutine
let mut signal_c = windows::ctrl_c().unwrap();
let mut signal_break = windows::ctrl_break().unwrap();
let mut signal_close = windows::ctrl_close().unwrap();
let mut signal_shutdown = windows::ctrl_shutdown().unwrap();
// https://docs.rs/tokio/latest/tokio/macro.select.html
tokio::select! {
_ = signal_c.recv() => println!("* {svc} received CTRL_C."),
_ = signal_break.recv() => println!("* {svc} received CTRL_BREAK."),
_ = signal_close.recv() => println!("* {svc} received CTRL_CLOSE."),
_ = signal_shutdown.recv() => println!("* {svc} received CTRL_SHUTDOWN."),
}
}

View File

@ -0,0 +1,4 @@
#[test]
fn demo_test() {
assert_eq!(4 + 4, 8);
}

View File

@ -0,0 +1,19 @@
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_rust//proto/prost:defs.bzl", "rust_prost_library")
# Build proto files
# https://bazelbuild.github.io/rules_rust/rust_proto.html#rust_proto_library
proto_library(
name = "proto_bindings",
srcs = [
"proto/helloworld.proto",
],
)
# Generate Rust bindings from the generated proto files
# https://bazelbuild.github.io/rules_rust/rust_proto.html#rust_prost_library
rust_prost_library(
name = "rust_proto",
proto = ":proto_bindings",
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "proto_bindings"
version = "0.1.0"

View File

@ -0,0 +1,21 @@
[package]
name = "proto_bindings"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
readme.workspace = true
[lib]
name = "proto_bindings"
path = "src/lib.rs"
[dependencies]
tonic = { workspace = true }
prost = { workspace = true }
[build-dependencies]
tonic-build = { workspace = true }

View File

@ -0,0 +1,6 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure()
.compile(&["proto/helloworld.proto"], &["proto"])
.expect("Failed to compile proto specification");
Ok(())
}

View File

@ -0,0 +1,34 @@
// Copyright 2015 gRPC 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
//
// http://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.
syntax = "proto3";
// https://github.com/hyperium/tonic/blob/master/examples/proto/helloworld/helloworld.proto
package proto;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello(HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

View File

@ -0,0 +1,3 @@
pub mod proto {
tonic::include_proto!("proto");
}

View File

@ -0,0 +1 @@
exports_files(["BUILD.zlib.bazel"])

View File

@ -0,0 +1,76 @@
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("@rules_cc//cc:defs.bzl", "cc_library")
_ZLIB_HEADERS = [
"crc32.h",
"deflate.h",
"gzguts.h",
"inffast.h",
"inffixed.h",
"inflate.h",
"inftrees.h",
"trees.h",
"zconf.h",
"zlib.h",
"zutil.h",
]
# In order to limit the damage from the `includes` propagation
# via `:zlib`, copy the public headers to a subdirectory and
# expose those.
_ZLIB_HEADER_PREFIX = "zlib/include"
_ZLIB_PREFIXED_HEADERS = ["{}/{}".format(_ZLIB_HEADER_PREFIX, hdr) for hdr in _ZLIB_HEADERS]
[
copy_file(
name = "{}.copy".format(hdr),
src = hdr,
out = "{}/{}".format(_ZLIB_HEADER_PREFIX, hdr),
)
for hdr in _ZLIB_HEADERS
]
_COMMON_COPTS = [
"-Wno-deprecated-non-prototype",
"-Wno-unused-variable",
"-Wno-implicit-function-declaration",
]
cc_library(
name = "zlib",
srcs = [
"adler32.c",
"compress.c",
"crc32.c",
"deflate.c",
"gzclose.c",
"gzlib.c",
"gzread.c",
"gzwrite.c",
"infback.c",
"inffast.c",
"inflate.c",
"inftrees.c",
"trees.c",
"uncompr.c",
"zutil.c",
# Include the un-prefixed headers in srcs to work
# around the fact that zlib isn't consistent in its
# choice of <> or "" delimiter when including itself.
] + _ZLIB_HEADERS,
hdrs = _ZLIB_PREFIXED_HEADERS,
copts = select({
"@platforms//os:linux": [
# Required for opt builds to avoid
# `libzlib.a(crc32.o): requires unsupported dynamic reloc 11; recompile with -fPIC`
"-fPIC",
# Silence all warnings
"-w",
] + _COMMON_COPTS,
"@platforms//os:windows": [],
"//conditions:default": _COMMON_COPTS,
}),
includes = ["zlib/include/"],
visibility = ["//visibility:public"],
)

View File

@ -55,7 +55,6 @@ rust_prost_toolchain(
prost_plugin_flag = "--plugin=protoc-gen-prost=%s",
prost_runtime = ":prost_runtime",
prost_types = "//proto/prost/private/3rdparty/crates:prost-types",
proto_compiler = "@com_google_protobuf//:protoc",
tonic_plugin = "//proto/prost/private/3rdparty/crates:protoc-gen-tonic__protoc-gen-tonic",
tonic_plugin_flag = "--plugin=protoc-gen-tonic=%s",
tonic_runtime = ":tonic_runtime",

View File

@ -1,6 +1,7 @@
"""Rules for building protos in Rust with Prost and Tonic."""
load("@rules_proto//proto:defs.bzl", "ProtoInfo", "proto_common")
load("@rules_proto//proto:proto_common.bzl", proto_toolchains = "toolchains")
load("//proto/prost:providers.bzl", "ProstProtoInfo")
load("//rust:defs.bzl", "rust_common")
@ -49,7 +50,7 @@ def _compile_proto(ctx, crate_name, proto_info, deps, prost_toolchain, rustfmt_t
package_info_file = ctx.actions.declare_file(ctx.label.name + ".prost_package_info")
lib_rs = ctx.actions.declare_file("{}.lib.rs".format(ctx.label.name))
proto_compiler = prost_toolchain.proto_compiler[DefaultInfo].files_to_run
proto_compiler = prost_toolchain.proto_compiler
tools = depset([proto_compiler.executable])
additional_args = ctx.actions.args()
@ -349,13 +350,23 @@ def _rust_prost_toolchain_impl(ctx):
if any(tonic_attrs) and not all(tonic_attrs):
fail("When one tonic attribute is added, all must be added")
if ctx.attr.proto_compiler:
# buildifier: disable=print
print("WARN: rust_prost_toolchain's proto_compiler attribute is deprecated. Make sure your rules_proto dependency is at least version 6.0.0 and stop setting proto_compiler")
proto_toolchain = proto_toolchains.find_toolchain(
ctx,
legacy_attr = "_legacy_proto_toolchain",
toolchain_type = "@rules_proto//proto:toolchain_type",
)
return [platform_common.ToolchainInfo(
prost_opts = ctx.attr.prost_opts,
prost_plugin = ctx.attr.prost_plugin,
prost_plugin_flag = ctx.attr.prost_plugin_flag,
prost_runtime = ctx.attr.prost_runtime,
prost_types = ctx.attr.prost_types,
proto_compiler = ctx.attr.proto_compiler,
proto_compiler = ctx.attr.proto_compiler or proto_toolchain.proto_compiler,
protoc_opts = ctx.fragments.proto.experimental_protoc_opts,
tonic_opts = ctx.attr.tonic_opts,
tonic_plugin = ctx.attr.tonic_plugin,
@ -367,7 +378,7 @@ rust_prost_toolchain = rule(
implementation = _rust_prost_toolchain_impl,
doc = "Rust Prost toolchain rule.",
fragments = ["proto"],
attrs = {
attrs = dict({
"prost_opts": attr.string_list(
doc = "Additional options to add to Prost.",
),
@ -392,10 +403,9 @@ rust_prost_toolchain = rule(
mandatory = True,
),
"proto_compiler": attr.label(
doc = "The protoc compiler to use.",
doc = "The protoc compiler to use. Note that this attribute is deprecated - prefer to use --incompatible_enable_proto_toolchain_resolution.",
cfg = "exec",
executable = True,
mandatory = True,
),
"tonic_opts": attr.string_list(
doc = "Additional options to add to Tonic.",
@ -413,7 +423,12 @@ rust_prost_toolchain = rule(
doc = "The Tonic runtime crates to use.",
providers = [[rust_common.crate_info], [rust_common.crate_group_info]],
),
},
}, **proto_toolchains.if_legacy_toolchain({
"_legacy_proto_toolchain": attr.label(
default = "//proto/protobuf:legacy_proto_toolchain",
),
})),
toolchains = proto_toolchains.use_toolchain("@rules_proto//proto:toolchain_type"),
)
def _current_prost_runtime_impl(ctx):

View File

@ -28,12 +28,9 @@ def rust_prost_dependencies(bzlmod = False):
maybe(
http_archive,
name = "rules_proto",
sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd",
strip_prefix = "rules_proto-5.3.0-21.7",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
],
sha256 = "6fb6767d1bef535310547e03247f7518b03487740c11b6c6adb7952033fe1295",
strip_prefix = "rules_proto-6.0.2",
url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.2/rules_proto-6.0.2.tar.gz",
)
maybe(

View File

@ -1,7 +1,6 @@
"""Definitions for loading transitive `@rules_rust//proto` dependencies"""
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
def rust_prost_transitive_repositories():
"""Load transitive dependencies of the `@rules_rust//proto` rules.
@ -9,7 +8,3 @@ def rust_prost_transitive_repositories():
This macro should be called immediately after the `rust_proto_dependencies` macro.
"""
rules_proto_dependencies()
rules_proto_toolchains()
protobuf_deps()

View File

@ -1,5 +1,6 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("//rust:defs.bzl", "rust_binary")
load(":legacy_proto_toolchain.bzl", "legacy_proto_toolchain")
load(":toolchain.bzl", "rust_proto_toolchain")
package(default_visibility = ["//visibility:public"])
@ -33,3 +34,8 @@ bzl_library(
"//proto/protobuf/3rdparty:bzl_lib",
],
)
legacy_proto_toolchain(
name = "legacy_proto_toolchain",
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,28 @@
"""Helper that wraps --proto_compiler into a ProtoLangToolchainInfo for backwards
compatibility with --noincompatible_enable_proto_toolchain_resolution.
Borrowed from https://github.com/bazelbuild/rules_go/pull/3919
"""
load(
"@rules_proto//proto:proto_common.bzl",
"ProtoLangToolchainInfo",
)
def _legacy_proto_toolchain_impl(ctx):
return [
ProtoLangToolchainInfo(
proto_compiler = ctx.attr._protoc.files_to_run,
),
]
legacy_proto_toolchain = rule(
implementation = _legacy_proto_toolchain_impl,
attrs = {
"_protoc": attr.label(
cfg = "exec",
default = configuration_field(fragment = "proto", name = "proto_compiler"),
),
},
fragments = ["proto"],
)

View File

@ -19,16 +19,22 @@ load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("//proto/protobuf/3rdparty/crates:defs.bzl", "crate_repositories")
def rust_proto_protobuf_dependencies(bzlmod = False):
"""Sets up dependencies for rules_rust's proto support.
Args:
bzlmod (bool): Whether this function is being called from a bzlmod context rather than a workspace context.
Returns:
A list of structs containing information about root module deps to report to bzlmod's extension_metadata.
"""
if not bzlmod:
maybe(
http_archive,
name = "rules_proto",
sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd",
strip_prefix = "rules_proto-5.3.0-21.7",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz",
],
sha256 = "6fb6767d1bef535310547e03247f7518b03487740c11b6c6adb7952033fe1295",
strip_prefix = "rules_proto-6.0.2",
url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.2/rules_proto-6.0.2.tar.gz",
)
maybe(
@ -46,6 +52,14 @@ def rust_proto_protobuf_dependencies(bzlmod = False):
],
)
maybe(
http_archive,
name = "bazel_features",
sha256 = "5d7e4eb0bb17aee392143cd667b67d9044c270a9345776a5e5a3cccbc44aa4b3",
strip_prefix = "bazel_features-1.13.0",
url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.13.0/bazel_features-v1.13.0.tar.gz",
)
return crate_repositories()
# buildifier: disable=unnamed-macro

View File

@ -14,6 +14,8 @@
"""Toolchain for compiling rust stubs from protobuf and gRPC."""
load("@rules_proto//proto:proto_common.bzl", proto_toolchains = "toolchains")
# buildifier: disable=bzl-visibility
load("//rust/private:utils.bzl", "name_to_crate_name")
@ -71,6 +73,10 @@ def rust_generate_proto(
outs = [ctx.actions.declare_file(path + ".rs") for path in paths]
output_directory = outs[0].dirname
# Throughout we use rules_rust as the name as the plugin, not rust, because rust is an unstable builtin language in protoc.
# If we use rust as the plugin name, it triggers protoc to try to use its in-built support, which is experimental.
# The naming here doesn't matter, it's arbitrary, just the plugin name and the out dir need to match, so we pick rules_rust.
if is_grpc:
# Add grpc stubs to the list of outputs
grpc_files = [ctx.actions.declare_file(path + "_grpc.rs") for path in paths]
@ -84,14 +90,14 @@ def rust_generate_proto(
args.add_all([
"--",
proto_toolchain.protoc,
"--plugin=protoc-gen-grpc-rust=" + proto_toolchain.grpc_plugin.path,
"--grpc-rust_out=" + output_directory,
"--plugin=protoc-gen-grpc-rules_rust=" + proto_toolchain.grpc_plugin.path,
"--grpc-rules_rust_out=" + output_directory,
])
executable = ctx.executable._optional_output_wrapper
args.add_all([
"--plugin=protoc-gen-rust=" + proto_toolchain.proto_plugin.path,
"--rust_out=" + output_directory,
"--plugin=protoc-gen-rules_rust=" + proto_toolchain.proto_plugin.path,
"--rules_rust_out=" + output_directory,
])
args.add_joined(
@ -118,13 +124,23 @@ def rust_generate_proto(
return outs
def _rust_proto_toolchain_impl(ctx):
if ctx.attr.protoc:
# buildifier: disable=print
print("WARN: rust_prost_toolchain's proto_compiler attribute is deprecated. Make sure your rules_proto dependency is at least version 6.0.0 and stop setting proto_compiler")
proto_toolchain = proto_toolchains.find_toolchain(
ctx,
legacy_attr = "_legacy_proto_toolchain",
toolchain_type = "@rules_proto//proto:toolchain_type",
)
return platform_common.ToolchainInfo(
edition = ctx.attr.edition,
grpc_compile_deps = ctx.attr.grpc_compile_deps,
grpc_plugin = ctx.file.grpc_plugin,
grpc_plugin = ctx.attr.protoc or ctx.file.grpc_plugin,
proto_compile_deps = ctx.attr.proto_compile_deps,
proto_plugin = ctx.file.proto_plugin,
protoc = ctx.executable.protoc,
protoc = ctx.executable.protoc or proto_toolchain.proto_compiler,
)
# Default dependencies needed to compile protobuf stubs.
@ -141,7 +157,7 @@ GRPC_COMPILE_DEPS = PROTO_COMPILE_DEPS + [
rust_proto_toolchain = rule(
implementation = _rust_proto_toolchain_impl,
attrs = {
attrs = dict({
"edition": attr.string(
doc = "The edition used by the generated rust source.",
),
@ -168,12 +184,15 @@ rust_proto_toolchain = rule(
default = Label("//proto/protobuf/3rdparty/crates:protobuf-codegen__protoc-gen-rust"),
),
"protoc": attr.label(
doc = "The location of the `protoc` binary. It should be an executable target.",
doc = "The location of the `protoc` binary. It should be an executable target. Note that this attribute is deprecated - prefer to use --incompatible_enable_proto_toolchain_resolution.",
executable = True,
cfg = "exec",
default = Label("@com_google_protobuf//:protoc"),
),
},
}, **proto_toolchains.if_legacy_toolchain({
"_legacy_proto_toolchain": attr.label(
default = "//proto/protobuf:legacy_proto_toolchain",
),
})),
doc = """\
Declares a Rust Proto toolchain for use.

View File

@ -1,7 +1,9 @@
"""Definitions for loading transitive `@rules_rust//proto/protobuf` dependencies"""
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
load("@bazel_features//:deps.bzl", "bazel_features_deps")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
def rust_proto_protobuf_transitive_repositories():
"""Load transitive dependencies of the `@rules_rust//proto/protobuf` rules.
@ -10,6 +12,16 @@ def rust_proto_protobuf_transitive_repositories():
"""
rules_proto_dependencies()
rules_proto_toolchains()
bazel_features_deps()
protobuf_deps()
maybe(
http_archive,
name = "zlib",
build_file = Label("//proto/private:BUILD.zlib.bazel"),
sha256 = "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1",
strip_prefix = "zlib-1.2.11",
urls = [
"https://zlib.net/zlib-1.2.11.tar.gz",
"https://storage.googleapis.com/mirror.tensorflow.org/zlib.net/zlib-1.2.11.tar.gz",
],
)

View File

@ -63,10 +63,19 @@ def rules_rust_test_deps():
sha256 = "b8c487191eb942361af905e40172644eab490190e717c3d09bf83e87f3994fff",
)
maybe(
http_archive,
name = "rules_python",
sha256 = "778aaeab3e6cfd56d681c89f5c10d7ad6bf8d2f1a72de9de55b23081b2d31618",
strip_prefix = "rules_python-0.34.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.34.0/rules_python-0.34.0.tar.gz",
)
direct_deps.extend([
struct(repo = "libc", is_dev_dep = True),
struct(repo = "rules_rust_toolchain_test_target_json", is_dev_dep = True),
struct(repo = "com_google_googleapis", is_dev_dep = True),
struct(repo = "rules_python", is_dev_dep = True),
])
return direct_deps

View File

@ -1,8 +1,11 @@
"""Rules rust test dependencies transitive dependencies."""
load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
load("@rules_python//python:repositories.bzl", "py_repositories")
def rules_rust_test_deps_transitive():
py_repositories()
switched_rules_by_language(
name = "com_google_googleapis_imports",
cc = False,