- Mastering Rust
- Rahul Sharma Vesa Kaihlavirta
- 820字
- 2021-07-02 13:35:22
Exploring the manifest file – Cargo.toml
Cargo heavily depends on the project's manifest file, the Cargo.toml file, to get all sorts of information for the project. Let's take a closer look at the structure of this file and what items it can contain. As you saw earlier, cargo new creates an almost empty manifest file, filled with just the necessary fields so that a project can be built. Every manifest file is divided into sections that specify the different properties of a project. We will take a look at the sections that are typically found in a moderate sized Cargo project's manifest file. Here's an imaginary Cargo.toml file from a larger application:
# cargo_manifest_example/Cargo.toml
# We can write comments with `#` within a manifest file
[package]
name = "cargo-metadata-example"
version = "1.2.3"
description = "An example of Cargo metadata"
documentation = "https://docs.rs/dummy_crate"
license = "MIT"
readme = "README.md"
keywords = ["example", "cargo", "mastering"]
authors = ["Jack Daniels <jack@danie.ls>", "Iddie Ezzard <iddie@ezzy>"]
build = "build.rs"
edition = "2018"
[package.metadata.settings]
default-data-path = "/var/lib/example"
[features]
default=["mysql"]
[build-dependencies]
syntex = "^0.58"
[dependencies]
serde = "1.0"
serde_json = "1.0"
time = { git = "https://github.com/rust-lang/time", branch = "master" }
mysql = { version = "1.2", optional = true }
sqlite = { version = "2.5", optional = true }
Let's go through the parts that we haven't explained yet, starting from the [package] section:
- description: It contains a longer, free-form text field about the project.
- license: It contains software license identifiers, as listed in http://spdx.org/licenses/.
- readme: It allows you to link to a file in your project's repository. This should be shown as the entry point to the project's introduction.
- documentation: It contains the link to the crate's documentation if it's a library crate.
- keywords: It is a list of single words that helps in discovering your project either through search engines or through the crates.io website.
- authors: It lists the project's key authors.
- build: It defines a piece of Rust code (typically build.rs) that is compiled and run before the rest of the program is compiled. This is often used to generate code or to build native libraries that the crate depends on.
- edition: This key specifies which edition to use when compiling your project. In our case, we are using the 2018 edition. The previous edition was 2015, which is assumed to be the default if no edition key exists. Note: projects created with the 2018 edition are backward compatible, which means that they can use 2015 crates as dependencies too.
Next is [package.metadata.settings]. Typically, Cargo complains about all of the keys and sections that it doesn't know about, but the sections with metadata in them are an exception. They are ignored by Cargo, so they can be used for any configurable key/value pairs you need for your project.
The [features], [dependencies], and [build-dependencies] sections tie in together. A dependency can be declared by version number, as stated in SemVer's guidelines:
serde = "1.0"
This means that serde is a mandatory dependency and that we want the newest version, 1.0.*. The actual version will be fixed in Cargo.lock.
Using the caret symbol broadens the version ranges that Cargo is allowed to look for:
syntex = "^0.58"
Here, we're saying that we want the latest major version, 0.*.*, which must be at least 0.58.*.
Cargo also allows you to specify dependencies directly to a Git repository, provided that the repository is a project that was created by Cargo and follows the directory structure that Cargo expects. We can specify the dependency from GitHub like so:
time = { git = "https://github.com/rust-lang/time", branch = "master" }
This also works for other online Git repositories such as GitLab. Again, the actual version (or in the case of Git, changeset revision) will be fixed in Cargo.lock by the cargo update command.
The manifest also has two optional dependencies, mysql and sqlite:
mysql = { version = "1.2", optional = true }
sqlite = { version = "2.5", optional = true }
This means that the program can be built without depending on either. The [features] section contains a list of the default features:
default = ["mysql"]
This means that if you do not manually override the feature set when building your program, only mysql, and not sqlite, will be pulled in. An example use of features is when your library has certain optimization tweaks. However, this would be costly on an embedded platform, so the library author can release them as features, which will only be available on capable systems. Another example is when you are building a command-line application and also provide a GUI frontend as an extra feature.
That was a quick brief tour on how to describe a Cargo project using the Cargo.toml manifest file. There's quite a lot more to explore on how to configure your project with Cargo. Take a look at https://doc.rust-lang.org/cargo/reference/manifest.html for more information.