Workspaces: How to build c library and use it in local project

I have a Cargo workspace with several packages, including a bin project that creates three binaries: a main Rust application and two helper binaries implemented in c. The c binaries are built using a script.

The two helpers communicate with the main Rust application over stdio using serialized data structures. I wanted to be able to use Serde for the serialization in the c helper programs. So I created another package in the workspace that exposed a c abi and generated a .so library.

Overall here's what it looks like:

  • Cargo Workspace
    • exopticon package
      • exopticon binary, main Rust application
      • captureworker binary
        • implemented in c
        • built by
        • depends on
      • playbackworker binary
        • implemented in c
        • built by
        • depends on
    • exserial package
      • generates

It basically works now for dev builds but Cargo doesn't really understand the dependency and the paths are hardcoded so release builds and "cargo clippy" don't work. Here's a failing build log:

How can I depend on the .so library generated by the exserial package, in the exopticon package?

Or what's a better way to structure workspace?

Or maybe is there a way to tell Cargo about non-rust artifact dependencies?

You can view the repository here:

Thanks !

Try user-defined metadata

First add a to your exserial package, in which use std::env::var("OUT_DIR") to get path, and call println!("cargo:root={}", path); ,also add a "links" property in [package] with some dummy value in order to make it works, see cargo#3544

Finally in exopticon, retrieve it by environment DEP_<YOUR_DUMMY>_ROOT, then you could get correct path of and pass it to make to get ld works.

In case you're using workspace, both exopticon and exserial OUT_DIR should be same and may could needn't user-defined metadata.