Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly is a 'crate' in the Cargo ecosystem and what is the mapping to what is on crates.io?

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 in hello_macro, we’ll have to change the implementation of the procedural macro in hello_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 use hello_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 use hello_macro even if they don’t want the derive 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.

like image 839
nromaniv Avatar asked Aug 26 '18 07:08

nromaniv


1 Answers

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

like image 177
attdona Avatar answered Oct 26 '22 19:10

attdona