Rust学习-- Cargo配置详解
概述 Cargo.toml是cargo命令的运行清单,它以 TOML 格式编写。每个清单文件都包含以下部分:
- cargo-features — 指定启用的不稳定特性。
- [package] — 定义包。
- [lib] — Library target设置。
- [[bin]] — Binary target设置。
- [[example]] — Example target设置。
- [[test]] — Test target设置。
- [[bench]] — Benchmark target 设置。
- [dependencies] — 包的库依赖。
- [dev-dependencies] — examples, tests, and benchmarks的依赖。
- [build-dependencies] — build scripts的依赖。
- [target] — 特定于平台的依赖项。
- [badges] — 显示在注册表上的标识。
- [features] — 条件编译。
- [patch] — 覆盖依赖。
- [replace] — 覆盖依赖 (deprecated),使用patch。
- [profile] —编译器设置和优化。
- [workspace] — 工作区定义。
#
文件布局Cargo 使用文件放置约定,文件放置具有以下规则:
- Cargo.toml 和 Cargo.lock 存储在包的根目录。
- 源代码位于 src 目录中。
- 默认库文件是 src/lib.rs。
- 默认的可执行文件是 src/main.rs。
- 其他可执行文件可以放在 src/bin/ 中。
- 基准测试文件在 benches 目录中。
- 示例文件在examples目录中。
- 集成测试文件在tests目录。
cargo-features 该配置用于启用一些实验性的特性,并且仅在夜间频道"cargo +nightly build"有用。
例如:
具体可用的实验性特性查看这里。
[package] Cargo 所需的唯一字段是package中的name和version。如果发布到注册中心,注册中心可能需要其他字段。
例如:
name 包名称是用于引用包的标识符。并作为推断的 lib 和 bin 目标的默认名称。
名称只能使用字母数字字符或 - 或 _,并且不能为空。
cargo new 和cargo init 对包名称施加了一些额外的限制,例如强制它是有效的 Rust 标识符而不是关键字。
crates.io 施加了更多限制,例如强制使用 ASCII 字符,并且不是保留名称,不是特殊的 Windows 名称(例如“nul”),不能太长等。
例如:
version version用于指定当前包的版本。Cargo 融入了语义版本控制的概念,因此确保遵循以下基本规则:
- 使用包含三个数字部分的版本号,例如 1.0.0 而不是 1.0。
- 版本到达 1.0.0 之前,一切都可以发生。但是如果进行了重大更改,例如向结构添加字段或向枚举添加成员,请增加次要版本。
- 版本到达在 1.0.0 之后,只有在增加主要版本时才进行重大更改。
- 版本到达在 1.0.0 之后,不要在补丁级别的版本中添加任何新的公共 API。
- 版本到达在 1.0.0 之后,如果添加任何新的 pub 结构、特征、字段、类型、函数、方法或其他任何内容,请始终增加次要版本。
例如: [package] version = "0.1.0" # the current version, obeying semver
authors authors字段列出了被视为包“作者”的人员或组织。这些名称将列在 crates.io 上的 crate 页面上。每个作者末尾的可以添加一个尖括号,其中可以包含一个可选的电子邮件地址。
例如: [package] authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
edition edition键是一个可选键,它会影响你的包是用哪个 Rust 版本编译的。在 [package] 中设置edition将影响包中的所有targets/crates,包括test suites, benchmarks, binaries, examples等。
大多数manifests的版本字段都由" cargo new"自动填充为最新的稳定版本,默认情况下为"2018"。
如果 Cargo.toml 中不存在edition字段,则假定为 2015 版本以实现向后兼容性。
例如: [package] edition = '2018'
description description字段是关于package的简短介绍。crates.io 将与package一起显示。这应该是纯文本(不是 Markdown)。
例如: [package] description = "A short description of my package"
documentation documentation字段指定托管 crate 文档的网站的 URL。如果cargo.toml清单文件中没有指定 URL,crates.io 将自动将您的 crate 链接到相应的 docs.rs 页面。
例如: [package] documentation = "https://docs.rs/bitflags"
readme readme 字段应该是包根目录中文件的路径(相对于 Cargo.toml),其中包含有关包的一般信息。
当发布包时,此文件将传输到注册表。crates.io 会将其解释为 Markdown 并将其呈现在 crate 的页面上。
如果没有为此字段指定值,并且包根目录中存在名为 README.md、README.txt 或 README 的文件,则将使用该文件的名称。可以通过将此字段设置为 false 来抑制此行为。 如果该字段设置为 true,则将假定值为README.md。
例如: [package] readme = "README.md"
homepage homepage 字段应该是指向包的主页的站点的 URL。
例子: [package] homepage = "https://serde.rs/"
repository repository 字段是包的源存储库的 URL。
例子: [package] repository = "https://github.com/rust-lang/cargo/"
license license字段包含发布包所依据的软件许可证的名称。
crates.io 将许可证字段解释为 SPDX 2.1 许可证表达式。该名称必须是 SPDX 许可证列表 3.11 中的已知许可证。目前不支持括号。
SPDX 许可证表达式支持 AND 和 OR 运算符来组合多个许可证。使用 OR 表示用户可以选择任一许可证。使用 AND 表示用户必须同时遵守两个许可证。 WITH 运算符表示具有特殊例外的许可证。例如:
- 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
例子: [package] license = "MIT OR Apache-2.0"
license-file license-file 字段包含包含许可证文本的文件的路径(相对于此 Cargo.toml)。
例子: [package] license-file = "LICENSE.txt"
keywords keywords字段是描述此包的字符串数组。在注册表中搜索包时,这会有助于别人找到此包。
crates.io 最多有 5 个关键字。 每个关键字必须是ASCII文本,以字母开头,只能包含字母、数字、_或-,最多20个字符。
例子: [package] keywords = ["gamedev", "graphics"]
categories categories字段是此包所属类别的字符串数组。
crates.io 最多有 5 个类别。每个类别都应与 https://crates.io/category_slugs 上可用的字符串之一匹配,并且必须完全匹配。
例子: [package] categories = ["command-line-utilities", "development-tools::cargo-plugins"]
workspace workspace字段可用于配置此包所属的工作空间。
如果未指定,将被推断为文件系统中向上的第一个具有[workspace]表的Cargo.toml。
当成员不在工作区根目录的子目录中,设置此项很有用。
如果当前Cargo.toml清单已定义了[workspace]表,则无法指定此字段。也就是说,一个crate不能既是工作区中的根 crate,又是另一个工作区的成员 crate。
例子: [package] workspace = "path/to/workspace/root"
build build 字段指定包根目录中的一个文件,该文件是用于构建本机代码的构建脚本。
默认值为“build.rs”,从包根目录中名为 build.rs 的文件加载脚本。使用 build = "custom_build_name.rs" 指定不同文件的路径。使用 build = false 禁用构建脚本的自动检测。
例子: [package] build = "build.rs"
links links 字段指定要链接到的本机库的名称。和build字段使用构建脚本相关。
[package] links = "foo"
exclude 使用exclude 字段可以明确的指定一组打包时需要忽略的文件,文件模式应该是 gitignore 风格的模式:
- foo 匹配包中任何位置的名称为 foo 的任何文件或目录。 这相当于模式 **/foo。
- /foo 仅匹配包根目录中名称为 foo 的任何文件或目录。
- foo/ 匹配包中任何位置的名称为 foo 的任何目录。
- / 前缀表示在任何目录中匹配。例如,/foo/bar 匹配任何位置下的目录foo下的文件或者目录bar。
- / 后缀匹配里面的所有内容。 例如,foo/ 匹配目录 foo 内的所有文件,包括 foo 下子目录中的所有文件。
- // 匹配零个或多个目录。 例如,a//b 匹配 a/b、a/x/b、a/x/y/b 等。
- ! 前缀否定模式。例如,src/**.rs and !foo.rs 的模式将匹配 src 目录中所有扩展名为 .rs 的文件,但名为 foo.rs 的文件除外。
- 支持常见的 glob 模式,如 *、? 和 []:
- 匹配除 / 之外的零个或多个字符。 例如,*.html 匹配包中任何位置带有 .html 扩展名的任何文件或目录。
- ? 匹配除 / 之外的任何字符。 例如,foo? 匹配food,但不匹配 foo。
- [] 允许匹配一系列字符。 例如,[ab] 匹配 a 或 b。 [a-z] 匹配字母 a 到 z。
exclude字段和include字段是互斥的。
例子: [package] exclude = ["build//*.o", "doc//*.html"]
include 使用include字段可以明确的指定一组打包时需要包含的文件,文件模式应该是 gitignore 风格的模式:
- foo 匹配包中任何位置的名称为 foo 的任何文件或目录。 这相当于模式 **/foo。
- /foo 仅匹配包根目录中名称为 foo 的任何文件或目录。
- foo/ 匹配包中任何位置的名称为 foo 的任何目录。
- / 前缀表示在任何目录中匹配。例如,/foo/bar 匹配任何位置下的目录foo下的文件或者目录bar。
- / 后缀匹配里面的所有内容。 例如,foo/ 匹配目录 foo 内的所有文件,包括 foo 下子目录中的所有文件。
- // 匹配零个或多个目录。 例如,a//b 匹配 a/b、a/x/b、a/x/y/b 等。
- ! 前缀否定模式。例如,src/**.rs and !foo.rs 的模式将匹配 src 目录中所有扩展名为 .rs 的文件,但名为 foo.rs 的文件除外。
- 支持常见的 glob 模式,如 *、? 和 []:
- 匹配除 / 之外的零个或多个字符。 例如,*.html 匹配包中任何位置带有 .html 扩展名的任何文件或目录。
- ? 匹配除 / 之外的任何字符。 例如,foo? 匹配food,但不匹配 foo。
- [] 允许匹配一系列字符。 例如,[ab] 匹配 a 或 b。 [a-z] 匹配字母 a 到 z。
exclude字段和include字段是互斥的。
例子: [package] include = ["src/*/", "Cargo.toml"]
publish publish字段设置为false可用于防止错误地将包发布到包注册表(如 crates.io),例如将包在公司中保密。
该值也可以是一个字符串数组,这些字符串是允许发布到的注册表名称。如果publish数组仅包含单个注册表,则当未指定--registry 标志时,cargo publish命令将使用它。
例子: [package] publish = false
metadata metadata字段用于存储一些元数据,metadata 表被 Cargo 完全忽略,不会被警告。
例子: [package.metadata.android] package-name = "my-awesome-android-app" assets = "path/to/static"
default-run default-run 字段可用于指定由cargo run选择的默认二进制文件。例如,当同时存在 src/bin/a.rs 和 src/bin/b.rs 时指定a.rs:
例子: [package] default-run = "a"
autobins autobins字段用于禁用自动bin target发现,以便使用[[bin]]表数组构建手动配置的目标。
例子: [package] autobins = false
autoexamples autoexampless字段用于禁用自动example target发现,以便使用[[example]]表数组构建手动配置的目标。
例子: [package] autoexamples = false
autotests autoetests字段用于禁用自动test target发现,以便使用[[test]]表数组构建手动配置的目标。
例子: [package] autotests = false
autobenches autobenches字段用于禁用自动bench target发现,以便使用[[bench]]表数组构建手动配置的目标。
例子: [package] autobenches = false
resolver resolver字段用于指定解析器版本。
可以使用不同的特征解析器算法:
- 版本 "1" 解析器是 Cargo 1.50 版之前的原始解析器,如果未指定解析器,则为默认解析器。
- 版本“2”解析器引入了功能统一的变化。
解析器是影响整个工作区的全局选项。依赖项中的解析器版本将被忽略,只会使用顶层package中的值。
例子: [package] resolver = "2"
[lib] lib源文件名默认为 src/lib.rs,生成目标名默认为包名(任何破折号都替换为下划线)。lib的设置可以在 Cargo.toml 的 [lib] 表中自定义。
例子:
[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.
name name字段指定生成的库名称,这是依赖项将用于引用它的crate名。
path path 字段指定了 lib crate 的源文件所在的位置,相对于 Cargo.toml 文件。
如果未指定,则是src/lib.rs。
test test 字段指示运行cargo test时,是否需要执行lib crate中的单元测试。默认值为 true。
doctest doctest 字段指示运行cargo test时,是否需要执行lib crate中的测试文档示例。默认值为 true。
bench bench 字段指示运行cargo bench时,是否需要执行lib crate中的基准测试。默认值为 true。
doc doc 字段指示运行cargo doc时,是否需要为lib crate生成文档。默认值为 true。
proc-macro proc-macro 字段表示该lib crate是一个程序宏。
harness Harness 字段表示 --test 标志将被传递给 rustc,它会自动包含 libtest 库,该库是用于收集和运行标有 #[test] 属性的测试或标有 #[bench] 属性的基准测试的驱动程序。
默认值为 true。如果设置为 false,则需要负责定义 main() 函数来运行tests和benchmarks.
edition edition字段定义了将使用的 Rust 版本。如果未指定,则默认为package的 edition 字段。
crate-type crate-type字段定义了生成的lib crate类型。它是一个字符串数组,允许您为单个目标指定多种 crate 类型。
可用选项有lib、rlib、dylib、cdylib、staticlib 和 proc-macro:
- lib:生成rust库。具体类型由编译器决定。
- dylib:生成动态 Rust 库。此输出类型将在 Linux 上创建 .so 文件,在 macOS 上创建 .dylib 文件,在 Windows 上创建 .dll 文件。
- rlib:生成静态Rust库。这些 rlib 文件与 staticlib 文件不同,由编译器在将来的链接中进行解释。
- cdylib:产生动态系统库。此输出类型将在 Linux 上创建 .so 文件,在 macOS 上创建 .dylib 文件,在 Windows 上创建 .dll 文件。
- staticlib:产生静态系统库。其中包含所有本地 crate 的代码以及所有上游依赖项。 此输出类型将在 Linux、macOS 和 Windows (MinGW) 上创建 .a 文件,在 Windows (MSVC) 上创建 .lib 文件。 建议在将 Rust 代码链接到现有的非 Rust 应用程序等情况下使用这种格式,因为它不会动态依赖其他 Rust 代码。
- proc-macro:使用此 crate 类型编译的 crate 只能导出程序宏。 编译器会自动设置 proc_macro 配置选项。 crate 总是使用与编译器本身构建时相同的目标进行编译。 例如,如果您使用 x86_64 CPU 从 Linux 执行编译器,目标将是 x86_64-unknown-linux-gnu,即使 crate 是为不同目标构建的另一个 crate 的依赖项。
[[bin]] bin源文件名默认为 src/main.rs,生成目标名默认为包名(任何破折号都替换为下划线)。其他bin的源文件在src/bin/目录中,生成目标名默认为文件名。可以在 Cargo.toml 的 [[bin]] 表数组中自定义每个bin的设置。
例子: [[bin]] name = "cool-tool" test = false bench = false
[[bin]] name = "frobnicator" required-features = ["frobnicate"]
name name字段指定生成binary的名称。
path path 字段指定了bin crate 的源所在的位置,相对于 Cargo.toml 文件。
test test 字段指示运行cargo test时,是否需要执行bin crate中的单元测试。默认值为 true。
bench bench 字段指示运行cargo bench时,是否需要执行bin crate中的基准测试。默认值为 true。
doc doc 字段指示运行cargo doc时,是否需要为bin crate生成文档。默认值为 true。
harness Harness 字段表示 --test 标志将被传递给 rustc,它会自动包含 libtest 库,该库是用于收集和运行标有 #[test] 属性的测试或标有 #[bench] 属性的基准测试的驱动程序。
默认值为 true。如果设置为 false,则需要负责定义 main() 函数来运行tests和benchmarks.
edition edition字段定义了使用的 Rust 版本。如果未指定,则默认为package的 edition 字段。
required-features required-features 字段指定bin需要哪些[features]才能构建。如果未启用任何必需的feature,则将跳过。
例如: [features]
...
postgres = [] sqlite = [] tools = []
[[bin]] name = "my-pg-tool" required-features = ["postgres", "tools"]
[[example]] example源文件默认在examples/目录下,生成目标名默认为文件名。可以在 Cargo.toml 的 [[example]] 表数组中自定义每个example的设置。
默认情况下,example生成的是binary(带有 main() 函数)。 可以通过指定 crate-type 字段,将示例编译为库:
例子: [[example]] name = "foo" crate-type = ["staticlib"]
name name字段指定生成binary或library的名称。
path path 字段指定了 example的源所在的位置,相对于 Cargo.toml 文件。
test test 字段指示运行cargo test时,是否需要执行example中的单元测试。默认值为 false。
bench bench 字段指示运行cargo bench时,是否需要执行example中的基准测试。默认值为 true。
doc doc 字段指示运行cargo doc时,是否需要为example生成文档。默认值为 false。
harness Harness 字段表示 --test 标志将被传递给 rustc,它会自动包含 libtest 库,该库是用于收集和运行标有 #[test] 属性的测试或标有 #[bench] 属性的基准测试的驱动程序。
默认值为 true。如果设置为 false,则需要负责定义 main() 函数来运行tests和benchmarks.
edition edition字段定义了使用的 Rust 版本。如果未指定,则默认为package的 edition 字段。
crate-type crate-type字段定义了生成的example类型。它是一个字符串数组,允许您为单个目标指定多种 crate 类型。
可用选项有bin、lib、rlib、dylib、cdylib、staticlib 和 proc-macro。
required-features required-features 字段指定该example需要哪些[features]才能构建。如果未启用任何必需的feature,则将跳过。
例如: [features]
#
...postgres = [] sqlite = [] tools = []
[[example]] name = "my-pg-tool" required-features = ["postgres", "tools"]
[[test]] Cargo 项目中有两种测试:单元测试、集成测试。单元测试在lib、bin、example的源文件中,集成测试在tests目录下。
当运行 cargo test 时,Cargo 会将tests目录下的文件中的每一个编译为单独的 crate,名称默认为文件名,然后执行它们。可以在 Cargo.toml 的 [[test]] 表数组中自定义每个test的设置。
name name字段指定生成binary的名称。
path path 字段指定了test的源所在的位置,相对于 Cargo.toml 文件。
test test 字段指示运行cargo test时,是否需要执行该集成测试。默认值为 true。
bench bench 字段指示运行cargo bench时,是否需要执行test中的基准测试。默认值为 false。
doc doc 字段指示运行cargo doc时,是否需要为test生成文档。默认值为 false。
harness Harness 字段表示 --test 标志将被传递给 rustc,它会自动包含 libtest 库,该库是用于收集和运行标有 #[test] 属性的测试或标有 #[bench] 属性的基准测试的驱动程序。
默认值为 true。如果设置为 false,则需要负责定义 main() 函数来运行tests和benchmarks.
edition edition字段定义了使用的 Rust 版本。如果未指定,则默认为package的 edition 字段。
required-features required-features 字段指定该test需要哪些[features]才能构建。如果未启用任何必需的feature,则将跳过。
例如: [features]
#
...postgres = [] sqlite = [] tools = []
[[test]] name = "my-pg-tool" required-features = ["postgres", "tools"]
[[bench]] 基准测试提供了两种方法:1、在lib、bin、example的源文件中使用#[bench]属性进行注解,但是仅在夜间频道可用。2、在benches目录下的基准测试。
当运行 cargo bench时,Cargo 会将benches目录下的文件中的每一个编译为单独的crate,名称默认为文件名,然后执行它们。可以在 Cargo.toml 的 [[bench]] 表数组中自定义每个bench的设置。
name name字段指定生成binary的名称。
path path 字段指定了bench的源所在的位置,相对于 Cargo.toml 文件。
test test 字段指示运行cargo test时,是否需要执行bench中的单元测试。默认为false。
bench bench 字段指示运行cargo bench时,是否需要执行该基准测试。默认值为 true。
doc doc 字段指示运行cargo doc时,是否需要为bench生成文档。默认值为 false。
harness Harness 字段表示 --test 标志将被传递给 rustc,它会自动包含 libtest 库,该库是用于收集和运行标有 #[test] 属性的测试或标有 #[bench] 属性的基准测试的驱动程序。
默认值为 true。如果设置为 false,则需要负责定义 main() 函数来运行tests和benchmarks.
edition edition字段定义了使用的 Rust 版本。如果未指定,则默认为package的 edition 字段。
required-features required-features 字段指定该bench需要哪些[features]才能构建。如果未启用任何必需的feature,则将跳过。
例如: [features]
#
...postgres = [] sqlite = [] tools = []
[[bench]] name = "my-pg-tool" required-features = ["postgres", "tools"]
[dependencies] crate 可以依赖 crates.io 或其他注册表、git 存储库或本地文件系统上的子目录中的其他包。
[dependencies]表用于说明当前package依赖哪些其他package。
Cargo 默认配置为在 crates.io 上查找依赖项。在这种情况下,只需要名称和版本字符串。例如: [dependencies] time = "0.1.12"
version requirements cargo中库的版本依赖支持以下几种方式来指定依赖版本号的要求:
- caret requirements:指定兼容版本。如果新版本号不修改主要、次要、补丁分组中最左边的非零数字,则允许更新。例如: ^1.2.3 等价于 >=1.2.3, <2.0.0 ^1.2 等价于 >=1.2.0, <2.0.0 ^1 等价于 >=1.0.0, <2.0.0 ^0.2.3 等价于 >=0.2.3, <0.3.0 ^0.2 等价于 >=0.2.0, <0.3.0 ^0.0.3 等价于 >=0.0.3, <0.0.4 ^0.0 等价于 >=0.0.0, <0.1.0 ^0 等价于 >=0.0.0, <1.0.0
- tilde requirements:指定最小版本。如果指定了主要、次要和补丁版本或仅指定了主要和次要版本,则只允许进行补丁级别的更改。如果只指定一个主要版本,则允许次要和补丁级别的更改。例如: ~1.2.3 等价于 >=1.2.3, <1.3.0 ~1.2 等价于 >=1.2.0, <1.3.0 ~1 等价于 >=1.0.0, <2.0.0
- wildcard requirements:允许通配符匹配的任何版本。例如:
- 1. 等价于 >=1.0.0, <2.0.0 1.2. 等价于 >=1.2.0, <1.3.0
- comparison requirements:指定要依赖的版本范围或确切版本。例如:
= 1.2.0 1 < 2 = 1.2.3
- multiple requirements:由多个逗号分割的其他requirements组成,他们之间是与的关系。例如:
=1.0.0, <2.0.0 =1.2.0, <1.3.0
dependency location 默认情况下,从crates.io注册表中搜索依赖项。但是同样允许依赖其他位置的crate:
- other registries:可以使用registry指定依赖其他注册表。例如: [dependencies] some-crate = { registry = "my-registry" }
- git repositories:允许依赖特定的git仓库。例如: [dependencies] rand = { git = "https://github.com/rust-lang-nursery/rand", branch = "next" } 其中branch可以省略,默认为main分支。
- local path:允许依赖特定的本地lib crate。例如: [dependencies] hello_utils = { path = "hello_utils" } path指定的是相对路径,其路径相对于当前cargo.toml。
- multiple locations:可以同时指定注册表版本和 git或path。例如:
注意:crates.io上不允许发布仅存在other registries或git repositories或local path依赖的包。
rename dependencies 如果需要在项目中对依赖包进行重命名,可以通过以下方式执行:
optional dependency 依赖项可以标记为"可选",这意味着默认情况下不会编译它们,此时隐式地定义了一个与依赖项同名的特性。例如: [dependencies] bar = { version = "0.1", optional = true }
#
实际为注意:实际[features]表中不能存在与依赖项同名的特性。当使用--features bar标志进行编译时,才会编译bar依赖项。
如果[features]中存在与依赖项同名的特性,那么可以通过重命名依赖项来解决冲突。例如:
enable dependency feature 如果依赖包提供了特性选择,可以通过以下方式指定dependency中要打开的特性: [dependencies] awesome = { version = "1.3.5", default-features = false, features = ["secure-password", "civet"]} 其中default-features = false指示关闭默认的特性。
[dev-dependencies][dev-dependencies]表中存放了tests、examples和benchs的依赖项。
[dev-dependencies]表的键值参考[dependencies]表。
例如: [dev-dependencies] tempdir = "0.3"
[build-dependencies][build-dependencies] 表中存放了build script的依赖项。
[build-dependencies]表的键值参考[dependencies]表。
例如: [build-dependencies] cc = "1.0.3"
[target] 在target表下可以指定特定于平台的依赖项。依赖项可以是dependencies或dev-dependencies或build-dependencies。
使用类似 Rust 的 #[cfg] 语法将用于定义这些部分。例如:
[badges][badges]表用于指定可以在发布包时在注册网站上显示的状态标记。
例子:
[features] Cargo提供了一种机制来提供了两种功能:条件编译以及可选依赖。
define feature 在[feature] 表中定义了一系列的特性,每个特性可以选择性包含一组定义的特性或者要打开的dependency(隐式特性),如果一个特性包含了其他特性,那么当该特性启用时,其他特性也相应启用。
注意:注意:crates.io 对特性名称语法施加了额外的限制,即它们只能是 ASCII 字母数字字符或 _、- 或 +。
例如: [features] bmp = [] png = [] ico = ["bmp", "png"] webp = [] 定义了bmp、png、ico、webp四个特性,其中如果启用了ico特性,那么bmp特性和png特性也对应被启用。
use feature conditional compilation 在代码源文件中可以使用类似#[cfg(feature = "std")]注解,只有在指定特性打开的情况下,注解的代码才会被编译。
例如:
只有std特性打开的情况下,function_that_requires_std函数才会被编译。
optional dependencies 当依赖项可以标记为"可选",这意味着默认情况下不会编译它们,此时隐式地定义了一个与依赖项同名的特性。
例如:
只有在bar特性启用的情况下,bar这个dependency才会被编译。
详见optional dependency。
enable feature 默认情况下,除非明确启用,否则包中所有特性都被禁用。这可以通过指定默认特性来设置默认启用的特性,例如:
上例中默认启用了所有特性。
在进行编译时,以下命令行标志可用于控制启用哪些特性:
- 使用--features标志启用特性。多个特性用逗号或空格分隔。若在工作区中,使用"package-name"/"feature-name"打开指定特性。
- 使用--all-features标志启用所有特性。
- 使用--no-default-features不启用包的默认特性。
在设置包的依赖项时,通过dependencies.<pkg_name>.features设置依赖项中需要启用的特性,通过dependencies.<pkg_name>.default-features关闭包的默认特性。例如:
feature unification 特性对于定义它们的包来说是独一无二的。在启用一个包上的特性不会同时启用其他包上同名的特性。
当一个依赖项被多个包使用时,Cargo将在构建它时使用该依赖项上启用的所有特性的混合。这有助于确保仅使用依赖项的单个副本。但是在极少数情况下,一个包中的两个特性可能相互不兼容,但是构建时混合特性的功能可能会产生此种冲突,因此在代码中,需要能够在编译时检测这种冲突,例如:
[patch][patch]表定义了一系列副本用于覆盖依赖或子依赖。[patch]之后的每个键是需要被修补的git源的URL,或注册表的名称。每个条目都是正常的依赖项规范,与[dependencies]部分中的相同。例如:
上例中用 foo crate 和 bar crate 修补了 crates-io 源中的foo和bar。使用patched-baz修补 https://github.com/example/baz 源。
注意:[patch] 是可传递的,但只能在顶层定义,如果依赖项中仍然存在patch,必须在当前[patch]中重复依赖项的[patch]部分。例如:
[profile] profile提供了一种更改编译器设置的方法,可以影响优化和调试符号等内容。
Cargo 有4个内置profile:dev、release、test 和 bench。会根据正在运行的命令、正在构建的包和目标以及 --release 等命令行标志自动选择profile,选择过程如下:
- cargo build/rustc/check/run命令编译lib或bin目标时,默认使用dev profile。指定--release标志,则使用release profile。
- cargo install命令编译lib或bin目标时,默认使用release profile。指定--debug标志,则使用dev profile。
- test 目标编译默认使用test profile。指定--release标志,则使用bench profile。
- bench 目标编译默认使用bench profile。当使用cargo build --debug编译bench 目标时,使用test profile。
- cargo test/bench命令编译时,test/bench目标使用test/bench profile,但是他们的依赖项仍然使用dev/release profile编译。
在Cargo.toml的[profile]表中可以更改profile设置。在每个命名配置文件中,可以使用键/值对更改单独的设置,如下所示:
注意:Cargo 仅查看工作区根目录下 Cargo.toml中的profile设置,依赖项中定义的profile设置将被忽略。
profile settings opt-level opt-level 设置控制 -C opt-level 标志,该标志控制优化级别。有效的选项如下:
- 0:没有优化
- 1:基本优化
- 2:一些优化
- 3:所有优化
- "s":优化二进制大小
- "z":优化二进制大小,同时关闭循环矢量化
debug debug设置控制 -C debuginfo 标志,该标志控制已编译二进制文件中包含的调试信息量。有效的选项如下:
- 0 或 false:没有调试信息
- 1:仅行表
- 2 或 true:完整的调试信息
split-debuginfo split-debuginfo 设置控制 -C split-debuginfo 标志,该标志控制调试信息(如果生成)是放置在可执行文件本身中还是与其相邻。
此选项是一个字符串,可接受的值与编译器接受的值相同。
debug-assertions debug-assertions 设置控制 -C debug-assertions 标志,它打开或关闭 cfg(debug_assertions) 条件编译。调试断言启用标准库中的debug_assert!宏。有效的选项如下:
- true: enabled
- false: disabled
overflow-checks overflow-checks设置控制 -C overflow-checks标志,该标志控制运行时整数溢出的行为。 当启用溢出检查时,溢出时会发生恐慌。有效的选项如下:
- true: enabled
- false: disabled
lto lto 设置控制 -C lto 标志,该标志控制 LLVM 的链接时间优化。 LTO 可以使用整个程序分析生成更好的优化代码,但代价是链接时间更长。有效的选项如下:
- false:在本地 crate 上通过代码生成单元执行"thin" LTO。如果代码生成单元为 1 或 opt-level 为 0,则不执行 LTO。
- true或"fat":执行"fat" LTO,它尝试对依赖图中的所有 crate 执行优化。
- "thin":执行"thin" LTO。 这类似于“fat”,但运行时间大大减少,同时仍能实现类似于“fat”的性能提升。
- "off":禁用 LTO。
panic panic设置控制 -C panic标志,该标志控制使用哪种恐慌策略。有效的选项如下:
- "unwind":在panic时展开堆栈。
- "abort":在panic时终止进程。
当设置为"unwind"时,实际值取决于目标平台的默认值。比如NVPTX平台不支持unwinding,所以一直使用"abort"。
测试、基准测试、构建脚本和 proc 宏会忽略panic设置。 rustc 测试工具目前需要展开行为。
incremental incremental设置控制 -C incremental标志,该标志控制是否启用增量编译。 增量编译会导致 rustc 将附加信息保存到磁盘,这些信息将在重新编译 crate 时重复使用,从而缩短重新编译时间。 附加信息存储在目标目录中。有效的选项如下:
- true: enabled
- false: disabled
codegen-units codegen-units 设置控制 -C codegen-units 标志,该标志控制将 crate 分成多少个“代码生成单元”。 更多的代码生成单元允许并行处理更多的 crate,可能会减少编译时间,但可能会产生更慢的代码。
此选项采用大于 0 的整数。增量构建的默认值为 256,非增量构建的默认值为 16。
rpath rpath 设置控制 -C rpath 标志,该标志控制是否启用 rpath。
default profiles dev dev profile用于正常的开发和调试。其默认值如下:
release release profile用于发布。其默认值如下:
test test profile用于构建测试。其默认值如下:
bench bench profile用于构建基准测试。其默认值如下:
override profile 可以覆盖指定包和构建时crate的profile设置。例如:
包名称实际上是一个包 ID 规范,因此可以使用 [profile.dev.package."foo:2.1.0"] 等语法来定位包的各个版本。
要覆盖所有依赖项(但不是任何工作区成员)的设置,请使用"*"包名称:
默认情况下,所有profile都不会优化build的依赖项(build script、proc 宏及其依赖项)。build override的默认设置是:
可以通过如下方式进行override:
注意:overrides 不能指定 panic、lto 或 rpath 设置。
[workspace] workspace是一个或多个共享公共依赖项解析(具有共享的 Cargo.lock)、输出目录和各种设置(例如配置文件)的包的集合。作为工作区一部分的包称为工作区成员。workspace有两种风格:
- root package:可以通过向 Cargo.toml 添加 [workspace] 表来创建工作区。这可以添加到已经定义了 [package] 的 Cargo.toml 中,在这种情况下,当前包是工作区的根包。工作空间根目录是工作空间的 Cargo.toml 所在的目录。
- virtual manifest:可以使用 [workspace] 部分但没有 [package] 部分创建 Cargo.toml 文件。这称为virtual manifest。当没有"main"包时,这通常很有用,或者您希望将所有包组织在单独的目录中。
workspace的主要特征如下:
- 所有包共享一个位于工作区根目录中的通用 Cargo.lock 文件。
- 所有包共享一个公共输出目录,该目录默认为工作区根目录中名为 target 的目录。
- Cargo.toml 中的 [patch] 和 [profile.*] 部分仅在根清单中被识别,在成员 crate 的清单中被忽略。
workspace member 在工作区目录中的所有使用本地路径的依赖项会自动成为该workspace的成员。一个空的 [workspace] 表可以与 [package] 一起使用,以方便地创建一个包及含包其所有路径依赖项的工作空间。
另外在[workspace] 表中使用member键定义哪些包是工作区的成员: [workspace] members = ["member1", "path/to/member2", "crates/*"] 成员列表支持使用 * 和 ? 等典型文件名 glob 模式匹配多个路径的 glob。
另外可以在[workspace] 表中使用exclude 键防止路径包含在工作区中: [workspace] members = ["member1", "path/to/member2", "crates/*"] exclude = ["crates/foo", "path/to/other"]
workspace selection 当在工作区的子目录中时,Cargo 将自动搜索带有 [workspace] 定义的 Cargo.toml 文件的父目录,以确定要使用的工作区。
package.workspace键可用于将成员crate 指向工作区。如果成员不在工作区根目录的子目录中,手动设置会很有用。详见package.workspace。
package selection 在工作区中,与包相关的cargo命令(例如 cargo build)可以使用 -p/--package 或 --workspace 命令行标志来确定要操作的包。
如果这些标志都没有指定,Cargo 将使用当前工作目录中的包。 如果当前目录是虚拟工作区,它将应用于所有成员(就像在命令行中指定了 --workspace 一样)。
可以指定 workspace.default-members 键来设置要在工作空间根目录中操作的成员,并且不使用包选择标志:
作者 : machenjie
Github地址:machenjie