diff --git a/src/doc/src/SUMMARY.md b/src/doc/src/SUMMARY.md index 8a1ca888b..9cb3d16d7 100644 --- a/src/doc/src/SUMMARY.md +++ b/src/doc/src/SUMMARY.md @@ -21,6 +21,7 @@ * [Cargo Reference](reference/index.md) * [Specifying Dependencies](reference/specifying-dependencies.md) * [The Manifest Format](reference/manifest.md) + * [Cargo Targets](reference/cargo-targets.md) * [Profiles](reference/profiles.md) * [Configuration](reference/config.md) * [Environment Variables](reference/environment-variables.md) diff --git a/src/doc/src/appendix/glossary.md b/src/doc/src/appendix/glossary.md index f87ab45a3..6152312a6 100644 --- a/src/doc/src/appendix/glossary.md +++ b/src/doc/src/appendix/glossary.md @@ -185,14 +185,14 @@ manifest is located. [feature]: ../reference/manifest.md#the-features-section [git dependency]: ../reference/specifying-dependencies.md#specifying-dependencies-from-git-repositories [git source]: ../reference/source-replacement.md -[integration-tests]: ../reference/manifest.md#integration-tests +[integration-tests]: ../reference/cargo-targets.md#integration-tests [manifest]: ../reference/manifest.md [path dependency]: ../reference/specifying-dependencies.md#specifying-path-dependencies [path overrides]: ../reference/specifying-dependencies.md#overriding-with-local-dependencies [pkgid-spec]: ../reference/pkgid-spec.md [rustdoc-unstable]: https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html [target-feature]: ../../reference/attributes/codegen.html#the-target_feature-attribute -[targets]: ../reference/manifest.md#configuring-a-target +[targets]: ../reference/cargo-targets.md#configuring-a-target [unstable-book]: https://doc.rust-lang.org/nightly/unstable-book/index.html [virtual]: ../reference/manifest.md#virtual-manifest [workspace]: ../reference/manifest.md#the-workspace-section diff --git a/src/doc/src/guide/project-layout.md b/src/doc/src/guide/project-layout.md index 7e1566f6b..4869924c6 100644 --- a/src/doc/src/guide/project-layout.md +++ b/src/doc/src/guide/project-layout.md @@ -55,5 +55,5 @@ See [Target auto-discovery] for more information on controlling how Cargo automatically infers target names. [book-modules]: ../../book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html -[Configuring a target]: ../reference/manifest.md#configuring-a-target -[Target auto-discovery]: ../reference/manifest.md#target-auto-discovery +[Configuring a target]: ../reference/cargo-targets.md#configuring-a-target +[Target auto-discovery]: ../reference/cargo-targets.md#target-auto-discovery diff --git a/src/doc/src/reference/cargo-targets.md b/src/doc/src/reference/cargo-targets.md new file mode 100644 index 000000000..e3eb7cc55 --- /dev/null +++ b/src/doc/src/reference/cargo-targets.md @@ -0,0 +1,368 @@ +## Cargo Targets + +Cargo packages consist of *targets* which correspond to source files which can +be compiled into a crate. Packages can have [library](#library), +[binary](#binaries), [example](#examples), [test](#tests), and +[benchmark](#benchmarks) targets. The list of targets can be configured in the +`Cargo.toml` manifest, often [inferred automatically](#target-auto-discovery) +by the [directory layout][package layout] of the source files. + +See [Configuring a target](#configuring-a-target) below for details on +configuring the settings for a target. + +### 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. 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 executables 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][package layout]. 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]`][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][package layout] are example +uses of the functionality provided by the library. When compiled, they are +placed in the [`target/debug/examples` directory][build cache]. + +Examples can use the public API of the package's library. They are also linked +with the [`[dependencies]`][dependencies] and +[`[dev-dependencies]`][dev-dependencies] defined in `Cargo.toml`. + +By default, examples are executable binaries (with a `main()` function). You +can specify the [`crate-type` field](#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](#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][test-attribute] located within your library or binaries (or any + target enabled with [the `test` field](#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][test-attribute] and executing them in +parallel, reporting the success and failure of each test. See [the `harness` +field](#the-harness-field) if you want to use a different harness or test +strategy. + +#### Integration tests + +Files located under the [`tests` directory][package layout] 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]`][dependencies] and +[`[dev-dependencies]`][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](#tests), +with each benchmark function annotated with the `#[bench]` attribute. +Similarly to tests: + +* Benchmarks are placed in the [`benches` directory][package layout]. +* 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](#the-bench-field) can be used to define which targets + are benchmarked by default. +* [The `harness` field](#the-harness-field) can be used to disable the + built-in harness. + +> **Note**: The [`#[bench]` +> attribute](../../unstable-book/library-features/test.html) is currently +> unstable and only available on the [nightly channel]. There are some +> packages available on [crates.io](https://crates.io/keywords/benchmark) that +> may help with running benchmarks on the stable channel, such as +> [Criterion](https://crates.io/crates/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](https://github.com/toml-lang/toml#array-of-tables), +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, with each +field described in detail below. + +```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). +``` + +#### The `name` field + +The `name` field specifies the name of the target, which corresponds to the +filename of the artifact that will be generated. For a library, this is the +crate name that dependencies will use to reference it. + +For the `[lib]` and the default binary (`src/main.rs`), this defaults to the +name of the package, with any dashes replaced with underscores. For other +[auto discovered](#target-auto-discovery) targets, it defaults to the +directory or file name. + +This is required for all targets except `[lib]`. + +#### The `path` field + +The `path` field specifies where the source for the crate is located, relative +to the `Cargo.toml` file. + +If not specified, the [inferred path](#target-auto-discovery) is used based on +the target name. + +#### The `test` field + +The `test` field indicates whether or not the target is tested by default by +[`cargo test`]. The default is `true` for lib, bins, and tests. + +> **Note**: Examples are built by [`cargo test`] by default to ensure they +> continue to compile, but they are not *tested* by default. Setting `test = +> true` for an example will also build it as a test and run any +> [`#[test]`][test-attribute] functions defined in the example. + +#### The `doctest` field + +The `doctest` field indicates whether or not [documentation examples] are +tested by default by [`cargo test`]. This is only relevant for libraries, it +has no effect on other sections. The default is `true` for the library. + +#### The `bench` field + +The `bench` field indicates whether or not the target is benchmarked by +default by [`cargo bench`]. The default is `true` for lib, bins, and +benchmarks. + +#### The `doc` field + +The `doc` field indicates whether or not the target is included in the +documentation generated by [`cargo doc`] by default. The default is `true` for +libraries and binaries. + +> **Note**: The binary will be skipped if its name is the same as the lib +> target. + +#### The `plugin` field + +This field is used for `rustc` plugins, which are being deprecated. + +#### The `proc-macro` field + +The `proc-macro` field indicates that the library is a [procedural macro] +([reference][proc-macro-reference]). This is only valid for the `[lib]` +target. + +#### The `harness` field + +The `harness` field indicates that the [`--test` flag] will be passed to +`rustc` which will automatically include the libtest library which is the +driver for collecting and running tests marked with the [`#[test]` +attribute][test-attribute] or benchmarks with the `#[bench]` attribute. The +default is `true` for all targets. + +If set to `false`, then you are responsible for defining a `main()` function +to run tests and benchmarks. + +#### The `edition` field + +The `edition` field defines the [Rust edition] the target will use. If not +specified, it defaults to the [`edition` field][package-edition] for the +`[package]`. This field should usually not be set, and is only intended for +advanced scenarios such as incrementally transitioning a large package to a +new edition. + +#### The `crate-type` field + +The `crate-type` field defines the [crate types] that will be generated by the +target. It is an array of strings, allowing you to specify multiple crate +types for a single target. This can only be specified for libraries and +examples. Binaries, tests, and benchmarks are always the "bin" crate type. The +defaults are: + +Target | Crate Type +-------|----------- +Normal library | `"lib"` +Proc-macro library | `"proc-macro"` +Example | `"bin"` + +The available options are `bin`, `lib`, `rlib`, `dylib`, `cdylib`, +`staticlib`, and `proc-macro`. You can read more about the different crate +types in the [Rust Reference Manual][crate types]. + +#### The `required-features` field + +The `required-features` field specifies which [features] the target needs in +order to be built. If any of the required features are not enabled, the +target will be skipped. This is only relevant for the `[[bin]]`, `[[bench]]`, +`[[test]]`, and `[[example]]` sections, it has no effect on `[lib]`. + +```toml +[features] +# ... +postgres = [] +sqlite = [] +tools = [] + +[[bin]] +name = "my-pg-tool" +required-features = ["postgres", "tools"] +``` + + +### Target auto-discovery + +By default, Cargo automatically determines the targets to build based on the +[layout of the files][package layout] on the filesystem. The target +configuration tables, such as `[lib]`, `[[bin]]`, `[[test]]`, `[[bench]]`, or +`[[example]]`, can be used to add additional targets that don't follow the +standard directory layout. + +The automatic target discovery can be disabled so that only manually +configured targets will be built. Setting the keys `autobins`, `autoexamples`, +`autotests`, or `autobenches` to `false` in the `[package]` section will +disable auto-discovery of the corresponding target type. + +```toml +[package] +# ... +autobins = false +autoexamples = false +autotests = false +autobenches = false +``` + +Disabling automatic discovery should only be needed for specialized +situations. For example, if you have a library where you want a *module* named +`bin`, this would present a problem because Cargo would usually attempt to +compile anything in the `bin` directory as an executable. Here is a sample +layout of this scenario: + +``` +├── Cargo.toml +└── src +    ├── lib.rs +    └── bin +       └── mod.rs +``` + +To prevent Cargo from inferring `src/bin/mod.rs` as an executable, set +`autobins = false` in `Cargo.toml` to disable auto-discovery: + +```toml +[package] +# … +autobins = false +``` + +> **Note**: For packages with the 2015 edition, the default for auto-discovery +> is `false` if at least one target is manually defined in `Cargo.toml`. +> Beginning with the 2018 edition, the default is always `true`. + + +[Build cache]: ../guide/build-cache.md +[Rust Edition]: ../../edition-guide/index.html +[`--test` flag]: ../../rustc/command-line-arguments.html#option-test +[`cargo bench`]: ../commands/cargo-bench.md +[`cargo build`]: ../commands/cargo-build.md +[`cargo doc`]: ../commands/cargo-doc.md +[`cargo install`]: ../commands/cargo-install.md +[`cargo run`]: ../commands/cargo-run.md +[`cargo test`]: ../commands/cargo-test.md +[crate types]: ../../reference/linkage.html +[crates.io]: https://crates.io/ +[customized]: #configuring-a-target +[dependencies]: specifying-dependencies.md +[dev-dependencies]: specifying-dependencies.md#development-dependencies +[documentation examples]: ../../rustdoc/documentation-tests.html +[features]: manifest.md#the-features-section +[nightly channel]: ../../book/appendix-07-nightly-rust.html +[package layout]: ../guide/project-layout.md +[package-edition]: manifest.md#the-edition-field +[proc-macro-reference]: ../../reference/procedural-macros.html +[procedural macro]: ../../book/ch19-06-macros.html +[test-attribute]: ../../reference/attributes/testing.html#the-test-attribute diff --git a/src/doc/src/reference/index.md b/src/doc/src/reference/index.md index a6eb8a2e0..a8258ec5c 100644 --- a/src/doc/src/reference/index.md +++ b/src/doc/src/reference/index.md @@ -4,6 +4,7 @@ The reference covers the details of various areas of Cargo. * [Specifying Dependencies](specifying-dependencies.md) * [The Manifest Format](manifest.md) + * [Cargo Targets](cargo-targets.md) * [Profiles](profiles.md) * [Configuration](config.md) * [Environment Variables](environment-variables.md) diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md index a30558d57..305d1498f 100644 --- a/src/doc/src/reference/manifest.md +++ b/src/doc/src/reference/manifest.md @@ -679,200 +679,6 @@ When `default-members` is not specified, the default is the root manifest if it is a package, or every member manifest (as if `--workspace` were specified on the command-line) for virtual workspaces. -### Examples - -Files located under `examples` are example uses of the functionality provided by -the library. When compiled, they are placed in the `target/examples` directory. - -They can compile either as executables (with a `main()` function) or libraries -and pull in the library by using `extern crate `. They are -compiled when you run your tests to protect them from bitrotting. - -You can run individual executable examples with the command `cargo run --example -`. - -Specify `crate-type` to make an example be compiled as a library (additional -information about crate types is available in -[The Rust Reference](../../reference/linkage.html)): - -```toml -[[example]] -name = "foo" -crate-type = ["staticlib"] -``` - -You can build individual library examples with the command `cargo build ---example `. - -### Tests - -When you run [`cargo test`], Cargo will: - -* compile and run your library’s unit tests, which are in the files reachable - from `lib.rs` (naturally, any sections marked with `#[cfg(test)]` will be - considered at this stage); -* compile and run your library’s documentation tests, which are embedded inside - of documentation blocks; -* compile and run your library’s [integration tests](#integration-tests); and -* compile your library’s examples. - -#### Integration tests - -Each file in `tests/*.rs` is an integration test. When you run [`cargo test`], -Cargo will compile each of these files as a separate crate. The crate can link -to your library by using `extern crate `, like any other code that -depends on it. - -Cargo will not automatically compile files inside subdirectories of `tests`, but -an integration test can import modules from these directories as usual. For -example, if you want several integration tests to share some code, you can put -the shared code in `tests/common/mod.rs` and then put `mod common;` in each of -the test files. - -### Configuring a target - -All of the `[[bin]]`, `[lib]`, `[[bench]]`, `[[test]]`, and `[[example]]` -sections support similar configuration for specifying how a target should be -built. The double-bracket sections like `[[bin]]` are array-of-table of -[TOML](https://github.com/toml-lang/toml#array-of-tables), which means you can -write more than one `[[bin]]` section to make several executables in your crate. - -The example below uses `[lib]`, but it also applies to all other sections -as well. All values listed are the defaults for that option unless otherwise -specified. - -```toml -[package] -# ... - -[lib] -# The name of a target is the name of the library that will be generated. This -# is defaulted to the name of the package, with any dashes replaced -# with underscores. (Rust `extern crate` declarations reference this name; -# therefore the value must be a valid Rust identifier to be usable.) -name = "foo" - -# This field points at where the crate is located, relative to the `Cargo.toml`. -path = "src/lib.rs" - -# A flag for enabling unit tests for this target. This is used by `cargo test`. -test = true - -# A flag for enabling documentation tests for this target. This is only relevant -# for libraries, it has no effect on other sections. This is used by -# `cargo test`. -doctest = true - -# A flag for enabling benchmarks for this target. This is used by `cargo bench`. -bench = true - -# A flag for enabling documentation of this target. This is used by `cargo doc`. -doc = true - -# If the target is meant to be a compiler plugin, this field must be set to true -# for Cargo to correctly compile it and make it available for all dependencies. -plugin = false - -# If the target is meant to be a "macros 1.1" procedural macro, this field must -# be set to true. -proc-macro = false - -# If set to false, `cargo test` will omit the `--test` flag to rustc, which -# stops it from generating a test harness. This is useful when the binary being -# built manages the test runner itself. -harness = true - -# If set then a target can be configured to use a different edition than the -# `[package]` is configured to use, perhaps only compiling a library with the -# 2018 edition or only compiling one unit test with the 2015 edition. By default -# all targets are compiled with the edition specified in `[package]`. -edition = '2015' - -# Here's an example of a TOML "array of tables" section, in this case specifying -# a binary target name and path. -[[bin]] -name = "my-cool-binary" -path = "src/my-cool-binary.rs" -``` - -#### Target auto-discovery - -By default, Cargo automatically determines the targets to build based on the -[layout of the files][package-layout] on the filesystem. The target -configuration tables, such as `[lib]`, `[[bin]]`, `[[test]]`, `[[bench]]`, or -`[[example]]`, can be used to add additional targets that don't follow the -standard directory layout. - -The automatic target discovery can be disabled so that only manually -configured targets will be built. Setting the keys `autobins`, `autoexamples`, -`autotests`, or `autobenches` to `false` in the `[package]` section will -disable auto-discovery of the corresponding target type. - -Disabling automatic discovery should only be needed for specialized -situations. For example, if you have a library where you want a *module* named -`bin`, this would present a problem because Cargo would usually attempt to -compile anything in the `bin` directory as an executable. Here is a sample -layout of this scenario: - -``` -├── Cargo.toml -└── src -    ├── lib.rs -    └── bin -       └── mod.rs -``` - -To prevent Cargo from inferring `src/bin/mod.rs` as an executable, set -`autobins = false` in `Cargo.toml` to disable auto-discovery: - -```toml -[package] -# … -autobins = false -``` - -> **Note**: For packages with the 2015 edition, the default for auto-discovery -> is `false` if at least one target is manually defined in `Cargo.toml`. -> Beginning with the 2018 edition, the default is always `true`. - -#### The `required-features` field - -The `required-features` field specifies which features the target needs in order -to be built. If any of the required features are not selected, the target will -be skipped. This is only relevant for the `[[bin]]`, `[[bench]]`, `[[test]]`, -and `[[example]]` sections, it has no effect on `[lib]`. - -```toml -[features] -# ... -postgres = [] -sqlite = [] -tools = [] - -[[bin]] -# ... -required-features = ["postgres", "tools"] -``` - -#### Building dynamic or static libraries - -If your package produces a library, you can specify which kind of library to -build by explicitly listing the library in your `Cargo.toml`: - -```toml -# ... - -[lib] -name = "..." -crate-type = ["dylib"] # could be `staticlib` as well -``` - -The available options are `dylib`, `rlib`, `staticlib`, `cdylib`, and -`proc-macro`. - -You can read more about the different crate types in the -[Rust Reference Manual](../../reference/linkage.html) - ### The `[patch]` Section This section of Cargo.toml can be used to [override dependencies][replace] with @@ -969,7 +775,6 @@ dependencies][replace] section of the documentation. [`cargo init`]: ../commands/cargo-init.md [`cargo new`]: ../commands/cargo-new.md [`cargo run`]: ../commands/cargo-run.md -[`cargo test`]: ../commands/cargo-test.md [crates.io]: https://crates.io/ [docs.rs]: https://docs.rs/ [publishing]: publishing.md @@ -977,13 +782,19 @@ dependencies][replace] section of the documentation. [spdx-2.1-license-expressions]: https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60 [spdx-license-list-3.6]: https://github.com/spdx/license-list-data/tree/v3.6 [SPDX site]: https://spdx.org/license-list -[package-layout]: ../guide/project-layout.md [patch]: #the-patch-section