Cargo.lock, workspaces with binaries and crates.io

I have a crate (https://github.com/abetterinternet/libprio-rs) that I publish to crates.io. Thus far, it only has a library target, which makes things simple. Per the recommendations in documentation and books (1, 2), I put Cargo.lock in .gitignore.

Now, I want to add a binary target to the crate. I could just add a binary target to the existing Cargo.toml, but I want the binary to pull in some dependencies that the library doesn't need (like color-eyre). A workspace and a distinct Cargo.toml for the binary seems like the best way to manage dependencies without having to do tricky things with optional dependencies and requiring features when building the binaries.

What's not clear to me is what I should do about Cargo.lock. The book tells me that all crates in a workspace share Cargo.lock (https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html). And that now that I've got a binary target, checking in Cargo.lock seems appropriate. But I also don't want to make life harder for users of my library.

  • So what's the right thing to do with Cargo.lock for a workspace that contains one or more binary targets and a library target that gets published to crates.io?
  • Will Cargo.lock automatically be ignored or omitted when I release the workspace's library crate to crates.io?
  • What if a client pulls in my crate using a dependency in their Cargo.toml like prio = { git = "https://github.com/abetterinternet/libprio-rs" }? Will their cargo ignore the Cargo.lock checked into my GitHub repository?

(I apologize for enclosing all the URLs in ``; Discourse limits new users like me to two links per post!)

As far as I know, the Cargo.lock is ignored for dependencies.

Though, did you consider releasing the executable as a separate crate to avoid this entire question altogether? Then anyone with a dependency on your crate does not need to download and compile your binary as well.

The Cargo.lock file will just be ignored for all users of the library. See "Why do binaries have Cargo.lock in version control, but not libraries?" in the docs.

You're right, I should have paid more attention to this sentence:

Users dependent on the library will not inspect the library’s Cargo.lock (even if it exists). This is precisely because a library should not be deterministically recompiled for all users of the library.

Thank you!

That's a good point, but if both are in the same workspace, then it's much easier for me to update them in lockstep.

You can still keep them in the same workspace. For example, check out how Tokio organizes its repository. It has a single workspace with folders for various crates.

I understand now. FWIW I believe I did wind up doing roughly what you suggest, which is that the library is in the root crate where I declare a workspace, and now I build the binaries from a separate crate in the workspace. It'd arguably be even cleaner to have the library and binaries be peers, but I prefer to avoid moving the files to preserve the commit history. Thanks again for your swift and helpful answers!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.