I am a little confused as to the exact things hosted on crates.io (is a 'crate' the proper way to refer to those)? My understanding is that a crate is a unit of compilation in Rust, but then what is the mapping between crates and what is on crates.io? For instance, The Rust Programming Language appendix on macros says that since there can only be one procedural macro per crate:
Our two crates are tightly related, so we create the procedural macro crate within the directory of our
hello_macro
crate. If we change the trait definition inhello_macro
, we’ll have to change the implementation of the procedural macro inhello_macro_derive
as well. The two crates will need to be published separately, and programmers using these crates will need to add both as dependencies and bring them both into scope. We could instead have the hello_macro crate usehello_macro_derive
as a dependency and reexport the procedural macro code. But the way we’ve structured the project makes it possible for programmers to usehello_macro
even if they don’t want thederive
functionality.
It has to be published separately on crates.io. This seems pretty clear: a crate on crates.io is the same as a local crate, and the mapping is one-to-one.
However, when discussing projects with both an executable and a library, it implies that they are separate crates but needn't be published separately. For instance, the sccache repo has both main.rs and lib.rs. Is the separate binary crate not actually stored on crates.io and resides in the repo only? Then how does cargo install figure out what to install?
What is a "package"?
I tried to run cargo package
with a sample project that contains both binary and library targets. And both were added to the .cargo file (by the way, is the exact format of .cargo archives documented anywhere?). This still leaves me confused. Can we publish multiple crates as a part of one package? Should we then refer to what is stored on crates.io as packages? Am I right to assume that each package can contain multiple binary crates but only one library crate? This is my current understanding.
The exact things hosted on crates.io are crates inside packages.
A crate is the output artifact of the compiler.
From Rust Reference Manual:
The compilation model centers on artifacts called crates. Each compilation processes a single crate in source form, and if successful, produces a single crate in binary form: either an executable or some sort of library.
A package is an artifact managed by Cargo, the Rust package manager.
Cargo.toml
manifest file defines the package with the syntax:
[package]
name = "hello_world"
version = "0.1.0"
authors = ["Your Name <[email protected]>"]
A package may contain one or more crates, for example one library crate, named as the package name and zero or more executable crates, each defined explicitly within a [[bin]]
section of the manifest file or implicitly if located inside the src/bin
directory of the package.
The Cargo book uses the term crate as an alias for package. Consider the following statement to try to get out some sense:
Generally* the main artifact of a package is a library crate, and since it is identified with the package name, it is customary to treat package and crate as synonyms.
*: A package may contains only a binary, see for example ripgrep
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With