Cargo run --bin on subcrate

It is possible to use cargo run to run binaries in a subcrate of a workspace, with the bin target.

My project is organised like so:

horned-owl
    - cargo.toml
    - src/.....
    horned-bin
          - src/bin 

There are multiple binaries in horned-bin.

Typing cargo run in the top level directory gives me:

error: a bin target must be available for `cargo run`

While cargo run --bin horned-round gives me

error: no bin target named `horned-parse`.

I can move into the horned-bin directory and launch from there which works.

So, I need a way to say "use this crate of the workspace" or "look for the binary anywhere"; for me the latter would be the most intuitive behaviour.

Does cargo run -p horned-bin --bin horned-round work for you? (it's the former of your two suggested solutions, i.e. -p tells cargo to use the horned-bin package as context)

Ah, yes, it does.

I am a bit confused by the documentation, since I don't use the term "package" very often in Rust, and as far as I can see it is not a package that I want to run, but a specific crate, which is in the current package.

That's correct. You have your workspace that contains packages. A package has a Cargo.toml manifest file and contains crates. Binary crates can be executed with cargo run. So in your case you have the horned-owl workspace containing the horned-bin package with the horned-round binary crate.

Ah, okay. And is each binary in a single package an independent crate, or are they all in the same crate?

Just trying to sort the terminology out in my head.

Every binary is its own crate. A crate is basically the atomic unit of a Cargo project, there is nothing "smaller". Only crates are compiled, a package and a workspace are just organisational units that allow you to better structure your project and to re-use build artefacts more efficiently.

Thank you for explanation!

If you set workspace.default-members to include "horned-bin", then you won't need the -p option. This also makes commands like cargo check and cargo fmt include both packages by default.

("Virtual manifest" workspaces, which don't have any package at the top level, get this by default.)

Ah, that explains both how to do it, and why it doesn't work by default.

I choose to keep my library in top level, and binaries in a sub-directory because it involved moving less files. Perhaps not the right decision.

Well, you get the same behavior, forever, if you set default-members. It's just the default if you don't do that that's different.

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.