Cargo feature 是条件编译和可选依赖的基础,却有一个出名的坑:feature 统一。这篇用自己写的小库逐个验证 default、可选依赖、转发,以及两个依赖启用不同 feature 时到底发生什么、互斥 feature 为什么不行。
default-features = false(不启用任何) → fmtx 编译时启用的 feature:[];int(42) = 42 --features use-std → fmtx 编译时启用的 feature:["std-fmt"];int(42) = 42 --features use-fast → fmtx 编译时启用的 feature:["fast"];int(42) = 42 --features use-fast,use-extra → fmtx 编译时启用的 feature:["fast", "extra"];int(42) = 42 | extra 功能存在
依赖版本的解析见Cargo.toml 依赖解析;条件编译的 cfg 更多用法见跨平台路径差异。
app v0.1.0 (<实验目录>/proj/u153/app)
└── fmtx v0.1.0 (<实验目录>/proj/u153/fmtx)
└── itoa feature "default"
└── itoa v1.0.18 app 自己没有启用任何 feature,但 fmtx 实际启用了:["fast", "extra"]
left 用到 fast:1;right 用到 extra:extra 功能存在
cargo tree -e features -i fmtx:
fmtx v0.1.0 (<实验目录>/proj/u153/fmtx)
└── both v0.1.0 (<实验目录>/proj/u153/both)
└── both feature "default" (command-line)
├── fmtx feature "extra"
│ └── right v0.1.0 (<实验目录>/proj/u153/right)
│ └── right feature "default"
│ └── both v0.1.0 (<实验目录>/proj/u153/both) (*)
└── fmtx feature "fast"
└── left v0.1.0 (<实验目录>/proj/u153/left)
└── left feature "default"
└── both v0.1.0 (<实验目录>/proj/u153/both) (*)resolver = "2" 对 build-dependencies 与 dev-dependencies 的 feature 分开统一,本文没有验证。
两个依赖各启用一个互斥 feature,统一后同时启用:
error: backend-a 与 backend-b 不能同时启用
1 | #[cfg(all(feature = "backend-a", feature = "backend-b"))] compile_error!("backend-a 与 backend-b 不能同时启用");
error: could not compile `excl` (lib) due to 1 previous errorcargo tree --no-default-features(fmtx): [' Updating crates.io index', ' Locking 1 package to latest Rust 1.98.1 compatible version', 'fmtx v0.1.0 (<实验目录>/proj/u153/fmtx)'] cargo tree --features fast(fmtx): ['fmtx v0.1.0 (<实验目录>/proj/u153/fmtx)', '└── itoa v1.0.18']
工作区里统一管理见Workspace 依赖管理。