6

I'd like to create a rust package with two binary crates and a library which contains the shared code. I know how do do this for a simple program by putting the source files for the binaries in a src/bin/ subdirectory (e.g. src/bin/firstbin.rs and src/bin/secondbin.rs) and the library code either in src/ or in src/lib/.

However, if the binaries have a substantial amount of non-shared code which does not belong in the library, and I want to split their source into multiple files, I'm not sure of how to lay out the source files. I'm thinking something along the lines of having src/bin/firstbin/ for the files which belong only to the first binary, and src/bin/secondbin/ for the second binary. However, I'm not sure how to reference these files from firstbin.rs and secondbin.rs.

So is this the right approach and if so how do I reference the files? If not, what's the best layout?

starblue
  • 55,348
  • 14
  • 97
  • 151
Bob
  • 1,037
  • 1
  • 9
  • 14
  • Is only one package mandatory? I would use different crates if I were you. – Boiethios Apr 19 '19 at 07:51
  • I'm new to rust so still figuring out the best approach. Splitting this into multiple packages seems overkill though.The code is closely related and I'd expect it to be kept together. For example, I'd expect it all to be in a single git repository. There is obviously some expectation of multiple binaries in one package - hence the support for multiple source files in the src/bin directory - but if they are only single files that seems very limiting unless you have very large files. I prefer to keep source files to no more than 100 to 200 lines if possible. – Bob Apr 19 '19 at 07:57
  • You can have several crates (packages) in one project: https://github.com/amethyst/amethyst/blob/master/Cargo.toml#L79 IMO, the mix of a library and a binary in one crate is useful when the only function of your binary is to call your library, when all the work is done. For a more complex project, it is better to split that in different crates. – Boiethios Apr 19 '19 at 08:00
  • Wow! That's a bit over my head - my Cargo.toml files are all less than 10 lines long! By splitting into different crates, do you mean different packages? – Bob Apr 19 '19 at 08:05
  • If you go for several crates, check out workspaces: https://doc.rust-lang.org/cargo/reference/manifest.html#the-workspace-section – starblue Apr 19 '19 at 08:20
  • @Bob A package in Rust is named a "crate". – Boiethios Apr 19 '19 at 08:32
  • @French I don't think that's quite right. https://doc.rust-lang.org/book/ch07-01-packages-and-crates-for-making-libraries-and-executables.html says "A package has a Cargo.toml that describes how to build one or more crates. At most one crate in a package can be a library." – Bob Apr 19 '19 at 12:00
  • @Bob Oh, ok, thanks! TIL. – Boiethios Apr 19 '19 at 12:48
  • Please note: Shepmaster has marked this as a duplicate, but the questions referenced as duplicates do not (quite) address the question I was asking. However, starblue's answer below does. – Bob Apr 20 '19 at 07:34

1 Answers1

5

You can put your fn main() into src/bin/firstbin/main.rs and add more files for submodules in the same directory. This is documented in this section of the Cargo manual (in the text, the gray box is wrong).

starblue
  • 55,348
  • 14
  • 97
  • 151
  • Thanks - that is exactly what I was looking for. – Bob Apr 19 '19 at 12:02
  • Can I ask why you edited the title of my question? I think it's not quite right as I was specifically asking about three crates in one package: a library crate and two binary crates. The executables are not in the library crate - they are crates within the package. – Bob Apr 20 '19 at 07:36
  • Don't be too nitpicky about crate vs package, most people will always use crate. I'll have to check when that disctinction was added in the manual, it feels recent to me (but I might be wrong). – starblue Apr 20 '19 at 09:45