From ce140840e930ea043cca18131a2bff8ec2a13823 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Fri, 30 Aug 2024 10:38:15 +0200 Subject: [PATCH] update cargo --- technology/applications/development/cargo.md | 1014 +++++++++++++++++- 1 file changed, 966 insertions(+), 48 deletions(-) diff --git a/technology/applications/development/cargo.md b/technology/applications/development/cargo.md index 4e5cf81..3617309 100644 --- a/technology/applications/development/cargo.md +++ b/technology/applications/development/cargo.md @@ -1,5 +1,7 @@ --- obj: application +repo: https://github.com/rust-lang/cargo +rev: 2024-08-30 --- # cargo @@ -223,56 +225,973 @@ Remove a [Rust](../../dev/programming/languages/Rust.md) binary Update dependencies as recorded in the local lock file Usage: `cargo update [--dry-run]` +## `cargo flamegraph` +You can generate flamegraphs for your rust project with this [project](https://github.com/flamegraph-rs/flamegraph). + +Install with `cargo install flamegraph`. + +If you use [`mold`](mold.md) or ldd, you have to add this: +**lld**: +```toml +[target.x86_64-unknown-linux-gnu] +linker = "/usr/bin/clang" +rustflags = ["-Clink-arg=-fuse-ld=lld", "-Clink-arg=-Wl,--no-rosegment"] +``` + +**mold**: +```toml +[target.x86_64-unknown-linux-gnu] +linker = "clang" +rustflags = ["-Clink-arg=-fuse-ld=/usr/local/bin/mold", "-Clink-arg=-Wl,--no-rosegment"] +``` + +Usage: `cargo flamegraph [OPTIONS] [-- ...]` + +### Options + +| Option | Description | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--dev` | Build with the dev profile | +| `--profile ` | Build with the specified profile | +| `-p, --package ` | package with the binary to run | +| `-b, --bin ` | Binary to run | +| `--example ` | Example to run | +| `--test ` | Test binary to run (currently profiles the test harness and all tests in the binary) | +| `--unit-test []` | Crate target to unit test, may be omitted if crate only has one target (currently profiles the test harness and all tests in the binary; test selection can be passed as trailing arguments after `--` as separator) | +| `--bench ` | Benchmark to run | +| `--manifest-path ` | Path to Cargo.toml | +| `-f, --features ` | Build features to enable | +| `--no-default-features` | Disable default features | +| `-r, --release` | No-op. For compatibility with `cargo run --release` | +| `-o, --output ` | Output file [default: flamegraph.svg] | +| `--open` | Open the output .svg file with default program | +| `--root` | Run with root privileges (using `sudo`) | +| `-F, --freq ` | Sampling frequency in Hz [default: 997] | +| `-c, --cmd ` | Custom command for invoking perf/dtrace | +| `--deterministic` | Colors are selected such that the color of a function does not change between runs | +| `-i, --inverted` | Plot the flame graph up-side-down | +| `--reverse` | Generate stack-reversed flame graph | +| `--notes ` | Set embedded notes in SVG | +| `--min-width ` | Omit functions smaller than pixels [default: 0.01] | +| `--image-width ` | Image width in pixels | +| `--palette ` | Color palette [possible values: hot, mem, io, red, green, blue, aqua, yellow, purple, orange, wakeup, java, perl, js, rust] | +| `--skip-after ` | Cut off stack frames below ; may be repeated | +| `--flamechart` | Produce a flame chart (sort by time, do not merge stacks) | +| `--ignore-status` | Ignores perf's exit code | +| `--no-inline` | Disable inlining for perf script because of performance issues | +| `--post-process ` | Run a command to process the folded stacks, taking the input from stdin and outputting to stdout | + ## Manifest The `Cargo.toml` file for each package is called its manifest. It is written in the [TOML](../../files/TOML.md) format. It contains metadata that is needed to compile the package. -Every manifest file consists of the following sections: -- [`cargo-features`](https://doc.rust-lang.org/cargo/reference/unstable.html) — Unstable, nightly-only features. -- [`[package]`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-package-section) — Defines a package. - - [`name`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field) — The name of the package. - - [`version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field) — The version of the package. - - [`authors`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field) — The authors of the package. - - [`edition`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-edition-field) — The [Rust](../../dev/programming/languages/Rust.md) edition. - - [`rust-version`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field) — The minimal supported [Rust](../../dev/programming/languages/Rust.md) version. - - [`description`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-description-field) — A description of the package. - - [`documentation`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-documentation-field) — [URL](../../internet/URL.md) of the package documentation. - - [`readme`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-readme-field) — Path to the package’s README file. - - [`homepage`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-homepage-field) — [URL](../../internet/URL.md) of the package homepage. - - [`repository`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-repository-field) — [URL](../../internet/URL.md) of the package source repository. - - [`license`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-license-and-license-file-fields) — The package license. - - [`license-file`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-license-and-license-file-fields) — Path to the text of the license. - - [`keywords`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-keywords-field) — Keywords for the package. - - [`categories`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-categories-field) — Categories of the package. - - [`workspace`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-workspace-field) — Path to the workspace for the package. - - [`build`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-build-field) — Path to the package build script. - - [`links`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-links-field) — Name of the native library the package links with. - - [`exclude`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields) — Files to exclude when publishing. - - [`include`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields) — Files to include when publishing. - - [`publish`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field) — Can be used to prevent publishing the package. - - [`metadata`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-metadata-table) — Extra settings for external tools. - - [`default-run`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-default-run-field) — The default binary to run by [`cargo run`](https://doc.rust-lang.org/cargo/commands/cargo-run.html). - - [`autobins`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery) — Disables binary auto discovery. - - [`autoexamples`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery) — Disables example auto discovery. - - [`autotests`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery) — Disables test auto discovery. - - [`autobenches`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery) — Disables bench auto discovery. - - [`resolver`](https://doc.rust-lang.org/cargo/reference/resolver.html#resolver-versions) — Sets the dependency resolver to use. -- Target tables: (see [configuration](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#configuring-a-target) for settings) - - [`[lib]`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#library) — Library target settings. - - [`[[bin]]`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries) — Binary target settings. - - [`[[example]]`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#examples) — Example target settings. - - [`[[test]]`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#tests) — Test target settings. - - [`[[bench]]`](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#benchmarks) — Benchmark target settings. -- Dependency tables: - - [`[dependencies]`](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) — Package library dependencies. - - [`[dev-dependencies]`](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies) — Dependencies for examples, tests, and benchmarks. - - [`[build-dependencies]`](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#build-dependencies) — Dependencies for build scripts. - - [`[target]`](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies) — Platform-specific dependencies. -- [`[badges]`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-badges-section) — Badges to display on a registry. -- [`[features]`](https://doc.rust-lang.org/cargo/reference/features.html) — Conditional compilation features. -- [`[lints]`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section) — Configure linters for this package. -- [`[patch]`](https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html#the-patch-section) — Override dependencies. -- [`[profile]`](https://doc.rust-lang.org/cargo/reference/profiles.html) — Compiler settings and optimizations. -- [`[workspace]`](https://doc.rust-lang.org/cargo/reference/workspaces.html) — The workspace definition. +### The `[package]` section +The first section in a Cargo.toml is [package]. + +```toml +[package] +name = "hello_world" # the name of the package +version = "0.1.0" # the current version, obeying semver +authors = ["Alice ", "Bob "] +``` + +#### The `name` field +The package name is an identifier used to refer to the package. It is used when listed as a dependency in another package, and as the default name of inferred lib and bin targets. + +#### The `version` field +Cargo bakes in the concept of Semantic Versioning, so make sure you follow some basic rules: +- Before you reach `1.0.0`, anything goes, but if you make breaking changes, increment the minor version. In Rust, breaking changes include adding fields to structs or variants to enums. +- After `1.0.0`, only make breaking changes when you increment the major version. Don’t break the build. +- After `1.0.0`, don’t add any new public API (no new pub anything) in patch-level versions. Always increment the minor version if you add any new pub structs, traits, fields, types, functions, methods or anything else. +- Use version numbers with three numeric parts such as `1.0.0` rather than `1.0`. + + +This field is optional and defaults to `0.0.0`. The field is required for publishing packages. + +#### The `authors` field +The optional authors field lists in an array the people or organizations that are considered the “authors” of the package. The exact meaning is open to interpretation — it may list the original or primary authors, current maintainers, or owners of the package. An optional email address may be included within angled brackets at the end of each author entry. + +```toml +[package] +# ... +authors = ["Graydon Hoare", "Fnu Lnu "] +``` + +This field is only surfaced in package metadata and in the `$CARGO_PKG_AUTHORS` environment variable within `build.rs`. It is not displayed in the crates.io user interface. + +> **Warning**: Package manifests cannot be changed once published, so this field cannot be changed or removed in already-published versions of a package. + +#### The `edition` field +The edition key is an optional key that affects which Rust Edition your package is compiled with. Setting the edition key in `[package]` will affect all targets/crates in the package, including test suites, benchmarks, binaries, examples, etc. + +```toml +[package] +# ... +edition = '2021' +``` + +Most manifests have the edition field filled in automatically by `cargo new` with the latest stable edition. By default `cargo new` creates a manifest with the 2021 edition currently. + +If the edition field is not present in `Cargo.toml`, then the 2015 edition is assumed for backwards compatibility. Note that all manifests created with `cargo new` will not use this historical fallback because they will have edition explicitly specified to a newer value. + +#### The `description` field +The description is a short blurb about the package. crates.io will display this with your package. This should be plain text (not Markdown). + +```toml +[package] +# ... +description = "A short description of my package" +``` + +> **Note**: crates.io requires the description to be set. + +#### The `documentation` field +The documentation field specifies a URL to a website hosting the crate’s documentation. If no URL is specified in the manifest file, crates.io will automatically link your crate to the corresponding docs.rs page when the documentation has been built and is available. + +```toml +[package] +# ... +documentation = "https://docs.rs/bitflags" +``` + +#### The `readme` field +The readme field should be the path to a file in the package root (relative to this `Cargo.toml`) that contains general information about the package. This file will be transferred to the registry when you publish. crates.io will interpret it as Markdown and render it on the crate’s page. + +```toml +[package] +# ... +readme = "README.md" +``` + +If no value is specified for this field, and a file named `README.md`, `README.txt` or `README` exists in the package root, then the name of that file will be used. You can suppress this behavior by setting this field to false. If the field is set to true, a default value of `README.md` will be assumed. + +#### The `homepage` field +The homepage field should be a URL to a site that is the home page for your package. + +```toml +[package] +# ... +homepage = "https://serde.rs" +``` + +A value should only be set for homepage if there is a dedicated website for the crate other than the source repository or API documentation. Do not make homepage redundant with either the documentation or repository values. + +#### The `repository` field +The repository field should be a URL to the source repository for your package. + +```toml +[package] +# ... +repository = "https://github.com/rust-lang/cargo" +``` + +#### The `license` and `license-file` fields +The license field contains the name of the software license that the package is released under. The license-file field contains the path to a file containing the text of the license (relative to this `Cargo.toml`). + +crates.io interprets the license field as an SPDX 2.3 license expression. The name must be a known license from the SPDX license list 3.20. See the SPDX site for more information. + +SPDX license expressions support AND and OR operators to combine multiple licenses. + +```toml +[package] +# ... +license = "MIT OR Apache-2.0" +``` + +Using OR indicates the user may choose either license. Using AND indicates the user must comply with both licenses simultaneously. The WITH operator indicates a license with a special exception. Some examples: +- MIT OR Apache-2.0 +- LGPL-2.1-only AND MIT AND BSD-2-Clause +- GPL-2.0-or-later WITH Bison-exception-2.2 + +If a package is using a nonstandard license, then the license-file field may be specified in lieu of the license field. + +```toml +[package] +# ... +license-file = "LICENSE.txt" +``` + +> **Note**: crates.io requires either `license` or `license-file` to be set. + +#### The `keywords` field +The keywords field is an array of strings that describe this package. This can help when searching for the package on a registry, and you may choose any words that would help someone find this crate. + +```toml +[package] +# ... +keywords = ["gamedev", "graphics"] +``` + +> **Note**: crates.io allows a maximum of 5 keywords. Each keyword must be ASCII text, have at most 20 characters, start with an alphanumeric character, and only contain letters, numbers, _, - or +. + +#### The `categories` field +The categories field is an array of strings of the categories this package belongs to. + +```toml +categories = ["command-line-utilities", "development-tools::cargo-plugins"] +``` + +> **Note**: crates.io has a maximum of 5 categories. Each category should match one of the strings available at https://crates.io/category_slugs, and must match exactly. + +#### The `workspace` field +The workspace field can be used to configure the workspace that this package will be a member of. If not specified this will be inferred as the first `Cargo.toml` with `[workspace]` upwards in the filesystem. Setting this is useful if the member is not inside a subdirectory of the workspace root. + +```toml +[package] +# ... +workspace = "path/to/workspace/root" +``` + +This field cannot be specified if the manifest already has a `[workspace]` table defined. That is, a crate cannot both be a root crate in a workspace (contain `[workspace]`) and also be a member crate of another workspace (contain `package.workspace`). + +#### The `build` field +The build field specifies a file in the package root which is a build script for building native code. + +```toml +[package] +# ... +build = "build.rs" +``` + +The default is `build.rs`, which loads the script from a file named `build.rs` in the root of the package. Use `build = "custom_build_name.rs"` to specify a path to a different file or build = false to disable automatic detection of the build script. + +#### The `links` field +The links field specifies the name of a native library that is being linked to. +For example, a crate that links a native library called “git2” (e.g. `libgit2.a` on Linux) may specify: + +```toml +[package] +# ... +links = "git2" +``` + +#### The `exclude` and `include` fields +The exclude and include fields can be used to explicitly specify which files are included when packaging a project to be published, and certain kinds of change tracking. The patterns specified in the exclude field identify a set of files that are not included, and the patterns in include specify files that are explicitly included. You may run `cargo package --list` to verify which files will be included in the package. + +```toml +[package] +# ... +exclude = ["/ci", "images/", ".*"] + +[package] +# ... +include = ["/src", "COPYRIGHT", "/examples", "!/examples/big_example"] +``` + +#### The `publish` field +The publish field can be used to control which registries names the package may be published to: + +```toml +[package] +# ... +publish = ["some-registry-name"] +``` + +To prevent a package from being published to a registry (like crates.io) by mistake, for instance to keep a package private in a company, you can omit the version field. If you’d like to be more explicit, you can disable publishing: + +```toml +[package] +# ... +publish = false +``` + +If publish array contains a single registry, `cargo publish` command will use it when `--registry` flag is not specified. + +#### The `metadata` table +Cargo by default will warn about unused keys in `Cargo.toml` to assist in detecting typos and such. The `package.metadata` table, however, is completely ignored by Cargo and will not be warned about. This section can be used for tools which would like to store package configuration in `Cargo.toml`. For example: + +```toml +[package] +name = "..." +# ... + +# Metadata used when generating an Android APK, for example. +[package.metadata.android] +package-name = "my-awesome-android-app" +assets = "path/to/static" +``` + +### Dependencies +Your crates can depend on other libraries from crates.io or other registries, git repositories, or subdirectories on your local file system. + +Cargo is configured to look for dependencies on crates.io by default. Only the name and a version string are required in this case: +```toml +[dependencies] +time = "0.1.12" +``` + +The string `0.1.12` is a version requirement. Although it looks like a specific version of the time crate, it actually specifies a range of versions and allows SemVer compatible updates. An update is allowed if the new version number does not modify the left-most non-zero number in the major, minor, patch grouping. In this case, if we ran `cargo update time`, cargo should update us to version `0.1.13` if it is the latest `0.1.z` release, but would not update us to `0.2.0`. If instead we had specified the version string as `1.0`, cargo should update to `1.1` if it is the latest `1.y` release, but not `2.0`. The version `0.0.x` is not considered compatible with any other version. + +#### Specifying dependencies from other registries +To specify a dependency from a registry other than crates.io set the registry key to the name of the registry to use: +```toml +[dependencies] +some-crate = { version = "1.0", registry = "my-registry" } +``` + +where `my-registry` is the registry name configured in `.cargo/config.toml` file. + +> **Note**: crates.io does not allow packages to be published with dependencies on code published outside of crates.io. + +#### Specifying dependencies from git repositories +To depend on a library located in a git repository, the minimum information you need to specify is the location of the repository with the git key: +```toml +[dependencies] +regex = { git = "https://github.com/rust-lang/regex.git" } +``` + +Cargo fetches the git repository at that location and traverses the file tree to find `Cargo.toml` file for the requested crate anywhere inside the git repository. For example, regex-lite and regex-syntax are members of rust-lang/regex repo and can be referred to by the repo’s root URL (https://github.com/rust-lang/regex.git) regardless of where in the file tree they reside. +```toml +regex-lite = { git = "https://github.com/rust-lang/regex.git" } +regex-syntax = { git = "https://github.com/rust-lang/regex.git" } +``` + +##### Choice of commit +Cargo assumes that we intend to use the latest commit on the default branch to build our package if we only specify the repo URL, as in the examples above. + +You can combine the `git` key with the `rev`, `tag`, or `branch` keys to be more specific about which commit to use. Here’s an example of using the latest commit on a branch named next: +```toml +[dependencies] +regex = { git = "https://github.com/rust-lang/regex.git", branch = "next" } +``` + +Anything that is not a branch or a tag falls under rev key. This can be a commit hash like `rev = "4c59b707"`, or a named reference exposed by the remote repository such as `rev = "refs/pull/493/head"`. + +What references are available for the `rev` key varies by where the repo is hosted. + +More git dependency examples: +```toml +# .git suffix can be omitted if the host accepts such URLs - both examples work the same +regex = { git = "https://github.com/rust-lang/regex" } +regex = { git = "https://github.com/rust-lang/regex.git" } + +# a commit with a particular tag +regex = { git = "https://github.com/rust-lang/regex.git", tag = "1.10.3" } + +# a commit by its SHA1 hash +regex = { git = "https://github.com/rust-lang/regex.git", rev = "0c0990399270277832fbb5b91a1fa118e6f63dba" } + +# HEAD commit of PR 493 +regex = { git = "https://github.com/rust-lang/regex.git", rev = "refs/pull/493/head" } + +# INVALID EXAMPLES + +# specifying the commit after # ignores the commit ID and generates a warning +regex = { git = "https://github.com/rust-lang/regex.git#4c59b70" } + +# git and path cannot be used at the same time +regex = { git = "https://github.com/rust-lang/regex.git#4c59b70", path = "../regex" } +``` + +Cargo locks the commits of git dependencies in `Cargo.lock` file at the time of their addition and checks for updates only when you run `cargo update` command. + +##### The role of the version key +The `version` key always implies that the package is available in a registry, regardless of the presence of `git` or `path` keys. + +The `version` key does not affect which commit is used when Cargo retrieves the git dependency, but Cargo checks the version information in the dependency’s `Cargo.toml` file against the `version` key and raises an error if the check fails. + +In this example, Cargo retrieves the HEAD commit of the branch called next from Git and checks if the crate’s version is compatible with `version = "1.10.3"`: +```toml +[dependencies] +regex = { version = "1.10.3", git = "https://github.com/rust-lang/regex.git", branch = "next" } +``` + +`version`, `git`, and `path` keys are considered separate locations for resolving the dependency. + +#### Specifying path dependencies +Cargo supports path dependencies which are typically sub-crates that live within one repository. +```toml +[dependencies] +hello_utils = { path = "hello_utils" } +``` + +This tells Cargo that we depend on a crate called `hello_utils` which is found in the `hello_utils` folder, relative to the `Cargo.toml` file it’s written in. + +The next `cargo build` will automatically build `hello_utils` and all of its dependencies. + +The local paths must point to the exact folder with the dependency’s Cargo.toml. Unlike with git dependencies, Cargo does not traverse local paths. For example, if regex-lite and regex-syntax are members of a locally cloned rust-lang/regex repo, they have to be referred to by the full path: +```toml +# git key accepts the repo root URL and Cargo traverses the tree to find the crate +[dependencies] +regex-lite = { git = "https://github.com/rust-lang/regex.git" } +regex-syntax = { git = "https://github.com/rust-lang/regex.git" } + +# path key requires the member name to be included in the local path +[dependencies] +regex-lite = { path = "../regex/regex-lite" } +regex-syntax = { path = "../regex/regex-syntax" } +``` + +Local paths in published crates + +Crates that use dependencies specified with only a path are not permitted on crates.io. + +#### Multiple locations +It is possible to specify both a registry version and a git or path location. The git or path dependency will be used locally (in which case the version is checked against the local copy), and when published to a registry like crates.io, it will use the registry version. Other combinations are not allowed. Examples: +```toml +[dependencies] +# Uses `my-bitflags` when used locally, and uses +# version 1.0 from crates.io when published. +bitflags = { path = "my-bitflags", version = "1.0" } + +# Uses the given git repo when used locally, and uses +# version 1.0 from crates.io when published. +smallvec = { git = "https://github.com/servo/rust-smallvec.git", version = "1.0" } +``` + +#### Platform specific dependencies +Platform-specific dependencies take the same format, but are listed under a target section. Normally Rust-like `#[cfg]` syntax will be used to define these sections: + +```toml +[target.'cfg(windows)'.dependencies] +winhttp = "0.4.0" + +[target.'cfg(unix)'.dependencies] +openssl = "1.0.1" + +[target.'cfg(target_arch = "x86")'.dependencies] +native-i686 = { path = "native/i686" } + +[target.'cfg(target_arch = "x86_64")'.dependencies] +native-x86_64 = { path = "native/x86_64" } +``` + +Like with Rust, the syntax here supports the `not`, `any`, and `all` operators to combine various `cfg` name/value pairs. + +If you want to know which cfg targets are available on your platform, run `rustc --print=cfg` from the command line. If you want to know which cfg targets are available for another platform, such as 64-bit Windows, run `rustc --print=cfg --target=x86_64-pc-windows-msvc`. + +Unlike in your Rust source code, you cannot use `[target.'cfg(feature = "fancy-feature")'.dependencies]` to add dependencies based on optional features. Use the `[features]` section instead: +```toml +[dependencies] +foo = { version = "1.0", optional = true } +bar = { version = "1.0", optional = true } + +[features] +fancy-feature = ["foo", "bar"] +``` + +The same applies to `cfg(debug_assertions)`, `cfg(test)` and `cfg(proc_macro)`. These values will not work as expected and will always have the default value returned by `rustc --print=cfg`. There is currently no way to add dependencies based on these configuration values. + +In addition to `#[cfg]` syntax, Cargo also supports listing out the full target the dependencies would apply to: +```toml +[target.x86_64-pc-windows-gnu.dependencies] +winhttp = "0.4.0" + +[target.i686-unknown-linux-gnu.dependencies] +openssl = "1.0.1" +``` + +#### Custom target specifications +If you’re using a custom target specification (such as `--target foo/bar.json`), use the base filename without the .json extension: + +```toml +[target.bar.dependencies] +winhttp = "0.4.0" + +[target.my-special-i686-platform.dependencies] +openssl = "1.0.1" +native = { path = "native/i686" } +``` + +#### Development dependencies +You can add a `[dev-dependencies]` section to your `Cargo.toml` whose format is equivalent to `[dependencies]`: +```toml +[dev-dependencies] +tempdir = "0.3" +``` + +Dev-dependencies are not used when compiling a package for building, but are used for compiling tests, examples, and benchmarks. + +These dependencies are not propagated to other packages which depend on this package. + +You can also have target-specific development dependencies by using dev-dependencies in the target section header instead of dependencies. For example: +```toml +[target.'cfg(unix)'.dev-dependencies] +mio = "0.0.1" +``` + +#### Build dependencies +You can depend on other Cargo-based crates for use in your build scripts. Dependencies are declared through the `build-dependencies` section of the manifest: +```toml +[build-dependencies] +cc = "1.0.3" +``` + +You can also have target-specific build dependencies by using build-dependencies in the target section header instead of dependencies. For example: +```toml +[target.'cfg(unix)'.build-dependencies] +cc = "1.0.3" +``` + +In this case, the dependency will only be built when the host platform matches the specified target. + +The build script does not have access to the dependencies listed in the `dependencies` or `dev-dependencies` section. Build dependencies will likewise not be available to the package itself unless listed under the dependencies section as well. A package itself and its build script are built separately, so their dependencies need not coincide. Cargo is kept simpler and cleaner by using independent dependencies for independent purposes. + +#### Choosing features +If a package you depend on offers conditional features, you can specify which to use: +```toml +[dependencies.awesome] +version = "1.3.5" +default-features = false # do not include the default features, and optionally + # cherry-pick individual features +features = ["secure-password", "civet"] +``` + +#### Renaming dependencies in Cargo.toml +When writing a `[dependencies]` section in `Cargo.toml` the key you write for a dependency typically matches up to the name of the crate you import from in the code. For some projects, though, you may wish to reference the crate with a different name in the code regardless of how it’s published on crates.io. For example you may wish to: +- Avoid the need to `use foo as bar` in Rust source. +- Depend on multiple versions of a crate. +- Depend on crates with the same name from different registries. + +To support this Cargo supports a package key in the `[dependencies]` section of which package should be depended on: +```toml +[package] +name = "mypackage" +version = "0.0.1" + +[dependencies] +foo = "0.1" +bar = { git = "https://github.com/example/project.git", package = "foo" } +baz = { version = "0.1", registry = "custom", package = "foo" } +``` + +In this example, three crates are now available in your Rust code: +```rust +extern crate foo; // crates.io +extern crate bar; // git repository +extern crate baz; // registry `custom` +``` + +All three of these crates have the package name of foo in their own `Cargo.toml`, so we’re explicitly using the package key to inform Cargo that we want the foo package even though we’re calling it something else locally. The package key, if not specified, defaults to the name of the dependency being requested. + +Note that if you have an optional dependency like: +```toml +[dependencies] +bar = { version = "0.1", package = 'foo', optional = true } +``` + +you’re depending on the crate foo from crates.io, but your crate has a bar feature instead of a foo feature. That is, names of features take after the name of the dependency, not the package name, when renamed. + +Enabling transitive dependencies works similarly, for example we could add the following to the above manifest: +```toml +[features] +log-debug = ['bar/log-debug'] # using 'foo/log-debug' would be an error! +``` + +### The `[lints]` section +Override the default level of lints from different tools by assigning them to a new level in a table, for example: +```toml +[lints.rust] +unsafe_code = "forbid" +``` + +This is short-hand for: +```toml +[lints.rust] +unsafe_code = { level = "forbid", priority = 0 } +``` + +level corresponds to the lint levels in rustc: +- `forbid` +- `deny` +- `warn` +- `allow` + +priority is a signed integer that controls which lints or lint groups override other lint groups. lower (particularly negative) numbers have lower priority, being overridden by higher numbers, and show up first on the command-line to tools like rustc + +To know which table under `[lints]` a particular lint belongs under, it is the part before `::` in the lint name. If there isn’t a `::`, then the tool is `rust`. For example a warning about `unsafe_code` would be `lints.rust.unsafe_code` but a lint about `clippy::enum_glob_use` would be `lints.clippy.enum_glob_use`. + +For example: +```toml +[lints.rust] +unsafe_code = "forbid" + +[lints.clippy] +enum_glob_use = "deny" +``` + +### Cargo Targets +Cargo packages consist of targets which correspond to source files which can be compiled into a crate. Packages can have library, binary, example, test, and benchmark targets. The list of targets can be configured in the `Cargo.toml` manifest, often inferred automatically by the directory layout of the source files. + +#### Library +The library target defines a “library” that can be used and linked by other libraries and executables. The filename defaults to `src/lib.rs`, and the name of the library defaults to the name of the package, with any dashes replaced with underscores. A package can have only one library. The settings for the library can be customized in the `[lib]` table in `Cargo.toml`. +```toml +# Example of customizing the library in Cargo.toml. +[lib] +crate-type = ["cdylib"] +bench = false +``` + +#### Binaries +Binary targets are executable programs that can be run after being compiled. The default binary filename is `src/main.rs`, which defaults to the name of the package. Additional binaries are stored in the `src/bin/` directory. The settings for each binary can be customized in the `[[bin]]` tables in `Cargo.toml`. + +Binaries can use the public API of the package’s library. They are also linked with the `[dependencies]` defined in `Cargo.toml`. + +You can run individual binaries with the `cargo run` command with the `--bin ` option. `cargo install` can be used to copy the executable to a common location. +```toml +# Example of customizing binaries in Cargo.toml. +[[bin]] +name = "cool-tool" +test = false +bench = false + +[[bin]] +name = "frobnicator" +required-features = ["frobnicate"] +``` + +#### Examples +Files located under the examples directory are example uses of the functionality provided by the library. When compiled, they are placed in the `target/debug/examples` directory. + +Examples can use the public API of the package’s library. They are also linked with the `[dependencies]` and `[dev-dependencies]` defined in `Cargo.toml`. + +By default, examples are executable binaries (with a `main()` function). You can specify the crate-type field to make an example be compiled as a library: +```toml +[[example]] +name = "foo" +crate-type = ["staticlib"] +``` + +You can run individual executable examples with the `cargo run` command with the `--example ` option. Library examples can be built with `cargo build` with the `--example ` option. `cargo install` with the `--example ` option can be used to copy executable binaries to a common location. Examples are compiled by `cargo test` by default to protect them from bit-rotting. Set the test field to true if you have `#[test]` functions in the example that you want to run with `cargo test`. + +#### Tests +There are two styles of tests within a Cargo project: +- Unit tests which are functions marked with the `#[test]` attribute located within your library or binaries (or any target enabled with the test field). These tests have access to private APIs located within the target they are defined in. +- Integration tests which is a separate executable binary, also containing `#[test]` functions, which is linked with the project’s library and has access to its public API. + +Tests are run with the `cargo test` command. By default, Cargo and rustc use the libtest harness which is responsible for collecting functions annotated with the `#[test]` attribute and executing them in parallel, reporting the success and failure of each test. See the harness field if you want to use a different harness or test strategy. + +> **Note**: There is another special style of test in Cargo: documentation tests. They are handled by rustdoc and have a slightly different execution model. + +##### Integration tests +Files located under the `tests` directory are integration tests. When you run `cargo test`, Cargo will compile each of these files as a separate crate, and execute them. + +Integration tests can use the public API of the package’s library. They are also linked with the `[dependencies]` and `[dev-dependencies]` defined in `Cargo.toml`. + +If you want to share code among multiple integration tests, you can place it in a separate module such as `tests/common/mod.rs` and then put `mod common`; in each test to import it. + +Each integration test results in a separate executable binary, and `cargo test` will run them serially. In some cases this can be inefficient, as it can take longer to compile, and may not make full use of multiple CPUs when running the tests. If you have a lot of integration tests, you may want to consider creating a single integration test, and split the tests into multiple modules. The libtest harness will automatically find all of the `#[test]` annotated functions and run them in parallel. You can pass module names to `cargo test` to only run the tests within that module. + +#### Benchmarks +Benchmarks provide a way to test the performance of your code using the `cargo bench` command. They follow the same structure as tests, with each benchmark function annotated with the `#[bench]` attribute. Similarly to tests: +- Benchmarks are placed in the `benches` directory. +- Benchmark functions defined in libraries and binaries have access to the private API within the target they are defined in. Benchmarks in the benches directory may use the public API. +- The bench field can be used to define which targets are benchmarked by default. +- The harness field can be used to disable the built-in harness. + +> **Note**: The `#[bench]` attribute is currently unstable and only available on the nightly channel. There are some packages available on crates.io that may help with running benchmarks on the stable channel, such as Criterion. + +#### Configuring a target +All of the `[lib]`, `[[bin]]`, `[[example]]`, `[[test]]`, and `[[bench]]` sections in `Cargo.toml` support similar configuration for specifying how a target should be built. The double-bracket sections like `[[bin]]` are array-of-table of TOML, which means you can write more than one `[[bin]]` section to make several executables in your crate. You can only specify one library, so `[lib]` is a normal TOML table. + +The following is an overview of the TOML settings for each target. +```toml +[lib] +name = "foo" # The name of the target. +path = "src/lib.rs" # The source file of the target. +test = true # Is tested by default. +doctest = true # Documentation examples are tested by default. +bench = true # Is benchmarked by default. +doc = true # Is documented by default. +plugin = false # Used as a compiler plugin (deprecated). +proc-macro = false # Set to `true` for a proc-macro library. +harness = true # Use libtest harness. +edition = "2015" # The edition of the target. +crate-type = ["lib"] # The crate types to generate. +required-features = [] # Features required to build this target (N/A for lib). +``` + +### Features +Cargo “features” provide a mechanism to express conditional compilation and optional dependencies. A package defines a set of named features in the `[features]` table of `Cargo.toml`, and each feature can either be enabled or disabled. Features for the package being built can be enabled on the command-line with flags such as `--features`. Features for dependencies can be enabled in the dependency declaration in `Cargo.toml`. + +#### The `[features]` section +Features are defined in the `[features]` table in Cargo.toml. Each feature specifies an array of other features or optional dependencies that it enables. The following examples illustrate how features could be used for a 2D image processing library where support for different image formats can be optionally included: + +```toml +[features] +# Defines a feature named `webp` that does not enable any other features. +webp = [] +``` + +With this feature defined, `cfg` expressions can be used to conditionally include code to support the requested feature at compile time. For example, inside `lib.rs` of the package could include this: + +```rust +// This conditionally includes a module which implements WEBP support. +#[cfg(feature = "webp")] +pub mod webp; +``` + +Cargo sets features in the package using the rustc `--cfg` flag, and code can test for their presence with the `cfg` attribute or the `cfg` macro. + +Features can list other features to enable. For example, the ICO image format can contain BMP and PNG images, so when it is enabled, it should make sure those other features are enabled, too: +```toml +[features] +bmp = [] +png = [] +ico = ["bmp", "png"] +webp = [] +``` + +#### The default feature +By default, all features are disabled unless explicitly enabled. This can be changed by specifying the default feature: + +```toml +[features] +default = ["ico", "webp"] +bmp = [] +png = [] +ico = ["bmp", "png"] +webp = [] +``` + +When the package is built, the default feature is enabled which in turn enables the listed features. This behavior can be changed by: +- The `--no-default-features` command-line flag disables the default features of the package. +- The `default-features = false` option can be specified in a dependency declaration. + +> **Note**: Be careful about choosing the default feature set. The default features are a convenience that make it easier to use a package without forcing the user to carefully select which features to enable for common use, but there are some drawbacks. Dependencies automatically enable default features unless default-features = false is specified. This can make it difficult to ensure that the default features are not enabled, especially for a dependency that appears multiple times in the dependency graph. Every package must ensure that `default-features = false` is specified to avoid enabling them. + +#### Optional dependencies +Dependencies can be marked “optional”, which means they will not be compiled by default. For example, let’s say that our 2D image processing library uses an external package to handle GIF images. This can be expressed like this: +```toml +[dependencies] +gif = { version = "0.11.1", optional = true } +``` + +By default, this optional dependency implicitly defines a feature that looks like this: + +```toml +[features] +gif = ["dep:gif"] +``` + +This means that this dependency will only be included if the gif feature is enabled. The same `cfg(feature = "gif")` syntax can be used in the code, and the dependency can be enabled just like any feature such as `--features gif`. + +In some cases, you may not want to expose a feature that has the same name as the optional dependency. For example, perhaps the optional dependency is an internal detail, or you want to group multiple optional dependencies together, or you just want to use a better name. If you specify the optional dependency with the `dep:` prefix anywhere in the `[features]` table, that disables the implicit feature. + +For example, let’s say in order to support the AVIF image format, our library needs two other dependencies to be enabled. +```toml +[dependencies] +ravif = { version = "0.6.3", optional = true } +rgb = { version = "0.8.25", optional = true } + +[features] +avif = ["dep:ravif", "dep:rgb"] +``` + +In this example, the avif feature will enable the two listed dependencies. This also avoids creating the implicit ravif and rgb features, since we don’t want users to enable those individually as they are internal details to our crate. + +> **Note**: Another way to optionally include a dependency is to use platform-specific dependencies. Instead of using features, these are conditional based on the target platform. + +#### Dependency features +Features of dependencies can be enabled within the dependency declaration. The features key indicates which features to enable. +```toml +[dependencies] +# Enables the `derive` feature of serde. +serde = { version = "1.0.118", features = ["derive"] } +``` + +The default features can be disabled using `default-features = false`: +```toml +[dependencies] +flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] } +``` + +> **Note**: This may not ensure the default features are disabled. If another dependency includes flate2 without specifying `default-features = false`, then the default features will be enabled. + +Features of dependencies can also be enabled in the `[features]` table. The syntax is "package-name/feature-name". For example: +```toml +[dependencies] +jpeg-decoder = { version = "0.1.20", default-features = false } + +[features] +# Enables parallel processing support by enabling the "rayon" feature of jpeg-decoder. +parallel = ["jpeg-decoder/rayon"] +``` + +The "package-name/feature-name" syntax will also enable package-name if it is an optional dependency. Often this is not what you want. You can add a `?` as in "package-name?/feature-name" which will only enable the given feature if something else enables the optional dependency. + +For example, let’s say we have added some serialization support to our library, and it requires enabling a corresponding feature in some optional dependencies. That can be done like this: +```toml +[dependencies] +serde = { version = "1.0.133", optional = true } +rgb = { version = "0.8.25", optional = true } + +[features] +serde = ["dep:serde", "rgb?/serde"] +``` + +In this example, enabling the serde feature will enable the serde dependency. It will also enable the serde feature for the rgb dependency, but only if something else has enabled the rgb dependency. + +#### Command-line feature options +The following command-line flags can be used to control which features are enabled: +- `--features FEATURES`: Enables the listed features. Multiple features may be separated with commas or spaces. If using spaces, be sure to use quotes around all the features if running Cargo from a shell (such as `--features "foo bar"`). If building multiple packages in a workspace, the package-name/feature-name syntax can be used to specify features for specific workspace members. +- `--all-features`: Activates all features of all packages selected on the command-line. +- `--no-default-features`: Does not activate the default feature of the selected packages. + +#### Mutually exclusive features +There are rare cases where features may be mutually incompatible with one another. This should be avoided if at all possible, because it requires coordinating all uses of the package in the dependency graph to cooperate to avoid enabling them together. If it is not possible, consider adding a compile error to detect this scenario. For example: + +```rust +#[cfg(all(feature = "foo", feature = "bar"))] +compile_error!("feature \"foo\" and feature \"bar\" cannot be enabled at the same time"); +``` + +#### Build scripts +Build scripts can detect which features are enabled on the package by inspecting the `CARGO_FEATURE_` environment variable, where `` is the feature name converted to uppercase and `-` converted to `_`. + +### Profiles +Profiles provide a way to alter the compiler settings, influencing things like optimizations and debugging symbols. + +Cargo has 4 built-in profiles: `dev`, `release`, `test`, and `bench`. The profile is automatically chosen based on which command is being run if a profile is not specified on the command-line. In addition to the built-in profiles, custom user-defined profiles can also be specified. + +Profile settings can be changed in `Cargo.toml` with the `[profile]` table. Within each named profile, individual settings can be changed with key/value pairs like this: +```toml +[profile.dev] +opt-level = 1 # Use slightly better optimizations. +overflow-checks = false # Disable integer overflow checks. +``` + +Cargo only looks at the profile settings in the `Cargo.toml` manifest at the root of the workspace. Profile settings defined in dependencies will be ignored. + +Additionally, profiles can be overridden from a config definition. Specifying a profile in a config file or environment variable will override the settings from `Cargo.toml`. + +#### Profile Settings +The following is a list of settings that can be controlled in a profile. + +##### opt-level +The `opt-level` setting controls the `-C opt-level` flag which controls the level of optimization. Higher optimization levels may produce faster runtime code at the expense of longer compiler times. Higher levels may also change and rearrange the compiled code which may make it harder to use with a debugger. + +The valid options are: +- `0`: no optimizations +- `1`: basic optimizations +- `2`: some optimizations +- `3`: all optimizations +- `s`: optimize for binary size +- `z`: optimize for binary size, but also turn off loop vectorization. + +It is recommended to experiment with different levels to find the right balance for your project. There may be surprising results, such as level 3 being slower than 2, or the "s" and "z" levels not being necessarily smaller. You may also want to reevaluate your settings over time as newer versions of rustc change optimization behavior. + +##### debug +The debug setting controls the `-C debuginfo` flag which controls the amount of debug information included in the compiled binary. + +The valid options are: +- `0`, `false`, or `none`: no debug info at all, default for release +- `line-directives-only`: line info directives only. For the nvptx* targets this enables profiling. For other use cases, line-tables-only is the better, more compatible choice. +- `line-tables-only`: line tables only. Generates the minimal amount of debug info for backtraces with filename/line number info, but not anything else, i.e. no variable or function parameter info. +- `1` or `limited`: debug info without type or variable-level information. Generates more detailed module-level info than line-tables-only. +- `2`, `true`, or `full`: full debug info, default for dev + +##### split-debuginfo +The `split-debuginfo` setting controls the `-C split-debuginfo` flag which controls whether debug information, if generated, is either placed in the executable itself or adjacent to it. + +##### strip +The `strip` option controls the `-C strip` flag, which directs rustc to strip either symbols or debuginfo from a binary. This can be enabled like so: + +```toml +[package] +# ... + +[profile.release] +strip = "debuginfo" +``` + +Possible string values of strip are `none`, `debuginfo`, and `symbols`. The default is `none`. + +##### debug-assertions +The `debug-assertions` setting controls the `-C debug-assertions` flag which turns `cfg(debug_assertions)` conditional compilation on or off. Debug assertions are intended to include runtime validation which is only available in debug/development builds. These may be things that are too expensive or otherwise undesirable in a release build. Debug assertions enables the `debug_assert!` macro in the standard library. + +##### overflow-checks +The `overflow-checks` setting controls the `-C overflow-checks` flag which controls the behavior of runtime integer overflow. When overflow-checks are enabled, a panic will occur on overflow. + +##### lto +The `lto` setting controls rustc’s `-C lto`, `-C linker-plugin-lto`, and `-C embed-bitcode` options, which control LLVM’s link time optimizations. LTO can produce better optimized code, using whole-program analysis, at the cost of longer linking time. + +The valid options are: +- `false`: Performs “thin local LTO” which performs “thin” LTO on the local crate only across its codegen units. No LTO is performed if codegen units is 1 or opt-level is 0. +- `true` or `fat`: Performs “fat” LTO which attempts to perform optimizations across all crates within the dependency graph. +- `thin`: Performs “thin” LTO. This is similar to “fat”, but takes substantially less time to run while still achieving performance gains similar to “fat”. +- `off`: Disables LTO. + +##### panic +The `panic` setting controls the `-C panic` flag which controls which panic strategy to use. + +The valid options are: +- `unwind`: Unwind the stack upon panic. +- `abort`: Terminate the process upon panic. + +##### incremental +The `incremental` setting controls the -C incremental flag which controls whether or not incremental compilation is enabled. Incremental compilation causes rustc to save additional information to disk which will be reused when recompiling the crate, improving re-compile times. The additional information is stored in the `target` directory. + +##### codegen-units +The `codegen-units` setting controls the `-C codegen-units` flag which controls how many “code generation units” a crate will be split into. More code generation units allows more of a crate to be processed in parallel possibly reducing compile time, but may produce slower code. + +This option takes an integer greater than 0. + +The default is 256 for incremental builds, and 16 for non-incremental builds. + +##### rpath +The `rpath` setting controls the `-C rpath` flag which controls whether or not rpath is enabled. + +#### Default profiles +##### dev +The `dev` profile is used for normal development and debugging. It is the default for build commands like `cargo build`, and is used for `cargo install --debug`. + +The default settings for the `dev` profile are: +```toml +[profile.dev] +opt-level = 0 +debug = true +split-debuginfo = '...' # Platform-specific. +strip = "none" +debug-assertions = true +overflow-checks = true +lto = false +panic = 'unwind' +incremental = true +codegen-units = 256 +rpath = false +``` + +##### release +The `release` profile is intended for optimized artifacts used for releases and in production. This profile is used when the `--release` flag is used, and is the default for `cargo install`. + +The default settings for the `release` profile are: +```toml +[profile.release] +opt-level = 3 +debug = false +split-debuginfo = '...' # Platform-specific. +strip = "none" +debug-assertions = false +overflow-checks = false +lto = false +panic = 'unwind' +incremental = false +codegen-units = 16 +rpath = false +``` + +##### test +The `test` profile is the default profile used by `cargo test`. The `test` profile inherits the settings from the `dev` profile. + +##### bench +The `bench` profile is the default profile used by `cargo bench`. The `bench` profile inherits the settings from the `release` profile. + +#### Custom profiles +In addition to the built-in profiles, additional custom profiles can be defined. These may be useful for setting up multiple workflows and build modes. When defining a custom profile, you must specify the inherits key to specify which profile the custom profile inherits settings from when the setting is not specified. + +For example, let’s say you want to compare a normal release build with a release build with LTO optimizations, you can specify something like the following in `Cargo.toml`: +```toml +[profile.release-lto] +inherits = "release" +lto = true +``` + +The `--profile` flag can then be used to choose this custom profile: +```shell +cargo build --profile release-lto +``` + +The output for each profile will be placed in a directory of the same name as the profile in the `target` directory. As in the example above, the output would go into the `target/release-lto` directory. ## Build Scripts Some packages need to compile third-party non-[Rust](../../dev/programming/languages/Rust.md) code, for example C libraries. Other packages need to link to C libraries which can either be located on the system or possibly need to be built from source. Others still need facilities for functionality such as code generation before building (think parser generators). @@ -323,4 +1242,3 @@ Exposed environment variables: - `CARGO_BIN_EXE_` — The absolute path to a binary target’s executable. This is only set when building an integration test or benchmark. This may be used with the `env` macro to find the executable to run for testing purposes. The `` is the name of the binary target, exactly as-is. For example, `CARGO_BIN_EXE_my-program` for a binary named `my-program`. Binaries are automatically built when the test is built, unless the binary has required features that are not enabled. - `CARGO_PRIMARY_PACKAGE` — This environment variable will be set if the package being built is primary. Primary packages are the ones the user selected on the command-line, either with `-p` flags or the defaults based on the current directory and the default workspace members. This environment variable will not be set when building dependencies. This is only set when compiling the package (not when running binaries or tests). - `CARGO_TARGET_TMPDIR` — Only set when building integration test or benchmark code. This is a path to a directory inside the target directory where integration tests or benchmarks are free to put any data needed by the tests/benches. Cargo initially creates this directory but doesn’t manage its content in any way, this is the responsibility of the test code. -