I definitely agree that we should solve private libraries problem! It is an unfortunate restriction that, as soon as you split your code into crates, the split itself becomes a public API. As for the approach to solve this, I kind of like the “private path dependencies” of the postponed RFC more. In a nutshell, the approach is roughly “if you omit version field from the [package] section of workspace member, it becomes a “private dependency” and is packaged into .crate file with your main package”
In the rest of the post, I’d like to just discuss package/crate separation in detail.
Cargo has a concept of a “package”, and I’ve always had a love-hate relationship with it. In reality, all Rust code is a set of compilation units/crates, which form a DAG. The “package” concept is a Cargo-specific addition, which, in theory, could have not existed.
In practice a package as a way to add “supporting” crates to the main library crate is really, really useful. It feels very appropriate that examples, tests and build scripts are implemented as special-cased built-ins.
One of the more problematic aspects of the package concept is dependency management. Because package has at most single library crate, depending on package, and not on the individual crate, works perfect. However, the fact that you specify dependencies per-package is less than ideal: a common requests is to add binary specific dependencies.
In broad stokes, it seems that the way forward is either to stick with the “package as a unit of dependency” model and make package creation more light weight (postponed RFC), or to expose the underling crate concept more (current proposal).
Without examining the tradeoffs to closely, I’d expect the “lightweight package” route more promising, for two reasons:
- It reuses an existing mechanism for specifying dependencies, which makes Cargo’s interface simpler.
- It does not abandon the existing benefits of the packages (you can have dedicated tests and build-scripts for the private libraries)
- It makes transition from “private library” to “stand-alone package” more straightforward.