如何激活所有板条箱中的功能?

Rya*_*729 3 compilation rust rust-cargo

我想有条件地启用运行时检查和日志记录,彼此独立并独立于调试和发布模式。所以我开始向我的项目添加两个功能,一个称为“不变检查”,另一个称为“日志记录”。最终,我希望通过我在项目范围内可见的板条箱中定义的宏来使用它们。

我曾假设如果我在所有 crate 中以相同的方式填写features 部分,那么当我在编译 bin crate 时激活该功能时,所有 lib crate 也会启用该功能,但这不是案子!如何跨多个板条箱启用和禁用功能?希望这可以通过只改变一件事来完成,比如货物的命令行参数。

为了确切说明我想要什么,这里有一个示例,我还将在下面重现:

共有三个 crate,main、bin、crate 和两个 lib crate,分别称为“中间”和“普通”。以下是相关文件的相关部分:

主文件

extern crate common;
extern crate middle;

fn main() {
    common::check!();

    middle::run();

    println!("done");
}
Run Code Online (Sandbox Code Playgroud)

Cargo.toml

[dependencies]

[dependencies.common]
path = "libs/common"

[dependencies.middle]
path = "libs/middle"

[features]
default = []
invariant-checking = []
logging = []
Run Code Online (Sandbox Code Playgroud)

中间的lib.rs

extern crate common;

pub fn run() {
    common::check!();

    common::run();
}
Run Code Online (Sandbox Code Playgroud)

中间的Cargo.toml

[dependencies]

[dependencies.common]
path = "../common"

[features]
default = []
invariant-checking = []
logging = []
Run Code Online (Sandbox Code Playgroud)

公共的lib.rs

#[macro_export]
macro_rules! check {
    () => {{
        if cfg!(feature = "invariant-checking") {
            println!("invariant-checking {}:{}", file!(), line!());
        }
        if cfg!(feature = "logging") {
            println!("logging {}:{}", file!(), line!());
        }
    }};
}

pub fn run() {
    check!()
}
Run Code Online (Sandbox Code Playgroud)

最后是 common 的Cargo.toml

[dependencies]

[features]
default = []
invariant-checking = []
logging = []
Run Code Online (Sandbox Code Playgroud)

当我运行时,cargo run --features "invariant-checking,logging"我得到以下输出

invariant-checking src\main.rs:5
logging src\main.rs:5
done
Run Code Online (Sandbox Code Playgroud)

但希望它也登录中间和普通。我怎样才能改变这个项目,让它做到这一点,并且仍然允许我只通过改变一个地方来“完成”作为输出?

gnz*_*lbg 5

如何跨多个板条箱启用和禁用功能?

ACargo.toml可以添加可传递地启用允许属于依赖项的其他功能的功能。

例如,在Cargo.toml依赖于 cratesfoo和的 crate 中bar

[dependencies]
foo = "0.1"
bar = "0.1"

[features]
default = []
invariant-checking = [ "foo/invariant-checking", "bar/invariant-checking" ]
logging = [ "foo/logging", "bar/logging" ]
Run Code Online (Sandbox Code Playgroud)

这个板条箱增加了invariant-checkinglogging功能。启用它们可传递地启用 cratefoo和的各自功能bar,以便

[dependencies]
foo = "0.1"
bar = "0.1"

[features]
default = []
invariant-checking = [ "foo/invariant-checking", "bar/invariant-checking" ]
logging = [ "foo/logging", "bar/logging" ]
Run Code Online (Sandbox Code Playgroud)

将使logginginvariant-checking功能在这个箱子,并在它的依赖foo,并bar为好。

在您的特定情况下,你可能想main以传递地实现的功能middlecommon,并middle以传递地实现的功能common