rust-protobuf: protoc-gen-rust does not follow common file placement conventions

Instead of outputting *.rs files to the “conventional” (per cpp, go, and python) directories – relative to the source proto files – the generated files are placed relative to the command invocation site.

When I run the following example command:

protoc --rust_out . ./first/second/example.proto

Instead of

./first/second/example.rs

We see

./example.rs

A more complete example with several generators:

> protoc --rust_out . ./first/second/example.proto
> protoc --cpp_out . ./first/second/example.proto
> protoc --go_out . ./first/second/example.proto
> protoc --python_out . ./first/second/example.proto
> protoc --java_out . ./first/second/example.proto
> tree
├── example.rs                             # Rust
├── first
│   └── second
│       ├── example_pb2.py                 # Python
│       ├── example.pb.cc                  # Cpp
│       ├── example.pb.go                  # Go
│       ├── example.pb.h                   # Cpp
│       └── example.proto                  # Proto
└── org
    └── pubref
        └── rules_protobuf
            └── examples
                └── CommonProto.java       # Java

It appears that only we and the Java rules break from “convention”.

I understand this change would likely break many existing users, so I’d understand if this change was rejected for that reason. Example short change diff

EDIT:

To clarify, the primary reason this is an issue for me (and hasn’t been for anyone else yet presumably) is because I’m using this protoc extension with bazel instead of cargo+build.rs file, specifically the rules_protobuf “library”. That library has an expectation built in that generated source files are placed in a directory structure adjacent to the underlying proto files. It seems that assumption holds for all protoc-gen-* except us and java.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 8
  • Comments: 25 (10 by maintainers)

Most upvoted comments

@acmcarther

Ah this is news to me! I use the protoc_gen_rust binary directly with protoc to generate my rust and haven’t noticed any issues. Are you planning to deprecate this usage?

Probably not, because this is the way Google recommends using protobuf.

However, readme of rust-protobuf project recommends using protoc-rust crate and build.rs (since several months ago).

Regarding passing data directly through protoc: Apparently there is a parameter convention used with the --rust_out flag, of the form --rust_flag=${parameters}:OUT_DIR

I don’t recall if any protobuf implementation for other languages uses this mechanism, and this is probably inconvenient, but yes, this also works.

So, I think, there shoud be three ways of passing parameters to code generator:

  • rustproto.proto
  • --rust_out=OPTIONS:OUT_DIR
  • with protoc-rust crate and function parameters

And all three alternatives should support exactly the same set of options.

I mean that I have three totally separate generated crates – proto_dep_1, proto_dep_2 and proto_dep_3. proto_dep_1 is my actual target, but it transitively depends on proto_dep_3 twice: once for itself, and once through proto_dep_2.

This causes a namespace collision when the contents of proto_dep_3 are resolved within proto_dep_1: a given proto_dep_3::Proto could come in via proto_dep_2:😗 or from proto_dep_3:😗. Let me furnish a real world example.