I would like to make a Rust package that contains both a reusable library (where most of the program is implemented), and also an executable that uses it.
Assuming I have not confused any semantics in the Rust module system, what should my Cargo.toml
file look like?
You can put
lib.rs
andmain.rs
to sources folder together. There is no conflict and cargo will build both things.To resolve documentaion conflict add to your
Cargo.toml
:Cargo.toml:
src/lib.rs:
src/bin.rs:
You can also just put binary sources in
src/bin
and the rest of your sources insrc
. You can see an example in my project. You do not need to modify yourCargo.toml
at all, and each source file will be compiled to a binary of the same name.The other answer’s configuration is then replaced by:
Cargo.toml
src/lib.rs
src/bin/mybin.rs
And execute it:
Additionally, you can just create a
src/main.rs
that will be used as the defacto executable. Unfortunately, this conflicts with thecargo doc
command:An alternate solution is to not actually try to cram both things into one package. For slightly larger projects with a friendly executable, I've found it very nice to use a workspace
We create a binary project that includes a library inside of it:
Cargo.toml
This uses the
[workspace]
key and depends on the library:src/main.rs
mylibrary/src/lib.rs
And execute it:
There are two big benefits to this scheme:
The binary can now use dependencies that only apply to it. For example, you can include lots of crates to improve the user experience, such as command line parsers or terminal formatting. None of these will "infect" the library.
The workspace prevents redundant builds of each component. If we run
cargo build
in both themylibrary
andthe-binary
directory, the library will not be built both times — it's shared between both projects.