Why are bin and lib roots placed in the same src directory?

I want to create a crate with both a library and a binary that provides a cli for the library. Looking at the documentation, it recommends creating files src/lib.rs and src/main.rs. Or, if there are more binaries or a binary has submodules, then it recommends creating the binary root as src/bin/main.rs. The documentation does not explain why though.

When I tried to solve the issue of how to organise the files in such a crate I came up with a different solution. I would create the lib root as src-lib/lib.rs and the binary root as src-bin/main.rs. I designed it like this because this way, the library and the binary cannot accidentally share module files. And to a reader of the code it is immediately clear which modules belong to the binary, and which to the library.

Arguably, having a src/bin/main.rs file also separates binary modules from library modules, but to an uninformed reader it may seem like files in src/bin/ could be submodules of src/lib.rs.

I somehow can't find arguments for putting binary roots and library roots into a common src folder rather than putting them into separate src-bin and src-lib folders. Is there something I am not seeing?

1 Like

Personally, I agree that having bin and lib sources mixed together in the same directory can lead to errors and confusion. I’ve especially seen a lot of newcomers to Rust get caught up by this.

Why does Cargo look for both files in the same directory by default? I don’t really know, but I guess it does make things easy in some simple cases, like where there is only one target (bin or lib, but not both), or where one or both targets has just a single source file.

4 Likes

It's most likely for convenience for library-only or binary-only crates, which should be most crates. They also share the same build scripts, dependencies, other Cargo.toml settings, and crates.io page when published. And the library is always added as a dependency to the binary. If you want more separation, you can always split it into a workspace.

3 Likes

Not sure, to be honest. "Binary as a thin wrapper around library" is a fairly common pattern, AFAIK.

6 Likes

Thanks for your thoughts everyone!

I now ended up using two separate crates, one for bin and one for lib. Because I realised that also dependencies are hard to separate between binary and lib within a single crate.

Aren’t all crates either library-only or binary-only?

No.

My understanding was even a thin binary would be considered a separate crate to its associated library (but perhaps there is another level to this I’m missing?)

Yes.

What you have here is not a crate but a package that contains two crates.

2 Likes

Yeah this was my understanding, I wasn’t sure if I was wrong or if the terminology in this thread was wrong!

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.