I'd like to make a project with a daemon
and a client
, connecting through a unix socket.
A client
and a daemon
requires two binaries, so how do I tell Cargo
to build two targets from two different sources?
To add a bit of fantasy, I'd like to have a library
for the main part of the daemon
, and just have a binary to wrap around it and communicate through sockets.
So, we have this kind of tree architecture:
├── Cargo.toml
├── target
| └── debug
| ├── daemon
│ └── client
└── src
├── daemon
│ ├── bin
│ │ └── main.rs
│ └── lib
│ └── lib.rs
└── client
└── bin
└── main.rs
I could make one executable which manages both concerns, but that's not what I want to do, unless it's very good practice.
You can specify multiple binaries using [[bin]]
, as mentioned here:
[[bin]]
name = "daemon"
path = "src/daemon/bin/main.rs"
[[bin]]
name = "client"
path = "src/client/bin/main.rs"
Tip: If you instead put these files in src/bin/daemon.rs
and src/bin/client.rs
, you'll get two executables named daemon
and client
as Cargo compiles all files in src/bin
into executables with the same name automatically. You need to specify names and paths like in the snippet above only if you don't follow this convention.
Another way is to use the workspace feature. This will provide more flexibility due to the fact that we can have more than one library. Example project structure:
.
├── Cargo.toml
├── cli
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── core
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── daemon
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── gui
│ ├── Cargo.toml
│ └── src
│ └── main.rs
└── rpc
├── Cargo.toml
└── src
└── lib.rs
Contents of the root Cargo.toml
:
[workspace]
members = ["cli", "core", "daemon", "gui", "rpc"]
[[bin]]
. Could you give more details about what you did to get this to work? I was getting the following error: use ::engine::RuleEngine;
could not find engine in {{root}}
Another format could be to replicate what the Crates.io source code has done, if you have a massive project, something like:
Main Library in src, with a Bin folder with your executables. Then make calls to your main library crate from your executables.
That way you library is centralized so easier to find things as it's cached.
Success story sharing
target/debug/$name
where$name
is thename
you specify in Cargo.toml.[[bin]]
s usesrequired-features
. For that it seems likecargo workspace
is the only solution?