Tonic: Multiple build.rs files

I have a workspace-based project. I am using tonic in one of the workspace members with the standard setup; it works fine.

So, in that project, I have a build.rs like

fn main() -> Result<(), Box<dyn std::error::Error>> {
    tonic_build::compile_protos("protos/one.proto")?;
    Ok(())
}

Using the generated coe in the usual way:

mod grpc {
    tonic::include_proto!("one");
}

If I try something completely analogous in another workspace member project, with the second proto in that project called "two" and the file that uses tonic::include_proto! called "test.rs," hundreds of errors of this form result:

error[E0433]: failed to resolve: could not find `result` in `core`
 --> /Users/me/dev/test/target/debug/build/services-2119dfa8d04d262d/out/two.rs:2:28
  |
2 | #[derive(Clone, PartialEq, ::prost::Message)]
  |                            ^^^^^^^^^^^^^^^^ could not find `result` in `core`
  |
  = note: this error originates in the derive macro `::prost::Message` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing this module
 --> services/src/test.rs:10:5
  |
10+     use std::result;
  |

So the two invocations of build.rs are interfering with each other - not terribly surprising since workspace projects use a single target directory.

Putting all of the grpc stuff into one member project is certainly doable, but very ugly. What's a good workaround for this?

1 Like

It sounds like you have a crate called "core" in your project. Don't use that name, because part of the standard library is called "core".

6 Likes

Holy cow, you were right! It didn't occur to me because the core module is completely empty - but the 2nd workspace member, the one I added the second build.rs & proto to, has it as a dependency

core = { path = "../core" }

Once again I feel like a dolt.