bazelbuild / bazelbuild/rules_rust
Prost: transitive dependencies in the same package are duplicated
- Dominant language
- Starlark
- Stars
- 843
- Forks
- 651
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 15
Description
I have a setup with several protobuf files in the same package split across different `proto_library` targets. For example, `C` -> `B` -> `A`, and all are in the same package. I find that `A` and `B` get generated properly, but `C` ends up with an extra copy of `A` inside it. That type doesn't get used, but it can fail to compile if `A` depends on another type from a different package.
To illustrate see this [gist](https://gist.github.com/william-smith-skydio/5168780cb707a077d180971a7f9d9df5). I added these files in `proto/prost/private/tests/transitive_same_package`.
With `bazel build //proto/prost/private/tests/transitive_same_package:all` I get this error:
```
ERROR: /home/williamsmith/others/rules_rust/proto/prost/private/tests/transitive_same_package/BUILD.bazel:39:14: Compiling Rust rlib c_proto (1 files) failed: (Exit 1): process_wrapper failed: error executing command (from target //proto/prost/private/tests/transitive_same_package:c_proto) bazel-out/k8-opt-exec-2B5CBBC6/bin/util/process_wrapper/process_wrapper --arg-file bazel-out/k8-fastbuild/bin/external/rules_rust_prost__axum-0.6.18/axum_build_script.linksearchpaths --arg-file ... (remaining 117 arguments skipped)
Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
error[E0433]: failed to resolve: could not find `external` in the crate root
--> bazel-out/k8-fastbuild/bin/proto/prost/private/tests/transitive_same_package/c_proto.lib.rs:9:51
|
9 | pub foobar: ::core::option::Option,
| ^^^^^^^^ could not find `external` in the crate root
error: aborting due to previous error
For more information about this error, try `rustc --explain E0433`.
```
This is because the generated `bazel-out/k8-fastbuild/bin/proto/prost/private/tests/stuff/c_proto.lib.rs` contains a copy of `A` that is incorrect:
```rust
// @generated
pub mod stuff {
// @generated
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct A {
#[prost(message, optional, tag = "1")]
pub foobar: ::core::option::Option,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct C {
#[prost(message, optional, tag = "1")]
pub b: ::core::option::Option<::b_proto::stuff::B>,
}
// @@protoc_insertion_point(module)
}
```
So it seems that the direct dependencies of types in the same package get excluded because they are listed in `--prost_opt=extern_path`. But transitive dependencies aren't listed there, and prost-build assumes that all types in the same package should be generated in the same file. And it assumes that `foobar::Foobar` is defined in `super`, since there was no `extern_path` specified for it.
Some options that come to mind:
1. Specify `extern_path` for all transitive dependencies
2. Patch prost-build to not generate all transitive dependencies
But neither seems particularly good. Perhaps I am missing something obvious. I will keep looking into this but I thought I would post an issue in case someone else has insights.
Contributor guide
Assessment
This issue has not been assessed yet.