30

According to its manual, Cargo packages can have multiple executable targets, but only one library target is allowed.

A package can contain zero or one library crates and as many binary crates as you’d like. There must be at least one crate (either a library or a binary) in a package.

Why is it limited to one? What are the reasons and benefits?

Francis Gagné
  • 60,274
  • 7
  • 180
  • 155
eonil
  • 83,476
  • 81
  • 317
  • 516

3 Answers3

28

Cargo is primarily a package manager. Thus, the primary role of a package is to define a library.

When we use a crate as a dependency, we only specify the package name in our Cargo.toml. Since there can be at most one library, Cargo doesn't need you to specify which one to use. If it were allowed to define multiple libraries in the same package, then we'd need to specify a way to define dependencies between them, so we'd have two ways to declare dependencies (external packages vs. internal crates), making the system more complex.

On the other hand, adding a dependency that doesn't provide a library doesn't make sense, at least not with Cargo, since Cargo only cares about the library target in that context. Thus, there is no reason to limit the other types of targets (binaries, examples, tests, etc.) to one each.

Cargo workspaces are the tool that Cargo provides for working with multiple packages together.

Francis Gagné
  • 60,274
  • 7
  • 180
  • 155
  • it make sense for a default `rlib` crates, that are rust bricks for composition. but why don't allow to produce multiple `cdylib` as multiple `bin` are allowed? they have the same entry-point semantic as `bin`s with the only idfference they are used by applications directly instead of http, ui or cli. – kkolyan Jul 27 '23 at 20:58
2

I would expect that a cargo package can only have one library target because a library crate is by definition a collection of items (functions, types, traits, macros, values, etc.) while a binary crate has only one externally visible thing, a main entry point. Consequently, while the library crate's name is merely the root module within an hierarchy, the binary crate's name is the only thing.

George
  • 2,451
  • 27
  • 37
0

When the Rust doc says that a crate can only have a library and a binary, this refers to the output produced by each crate definition.

For example, if you produce some code, you can have a single executable to run, and/or a single library for other code to link to.

You can split the library product (output) into modules, so that you can develop each of those modules separately and produce one final bundled library at the end.

Modules are sort of like internal libraries which will be bundled together to produce either one big external library at the end, or indeed a whole binary executable.

Think of Crates as finished products which others can use, while modules are components. The standard library is one crate, made of many different modules. You can also have sub-modules, and have as many as you like. But they are compiled into one final (output) library by Cargo.

You can also include as many crates in a package as you like, but your crate only usually results in one executable (most cases) or a single library.

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225