< 返回版块

zaq7434 发表于 2024-08-01 09:00

Tags:build

查询说是可以通过CARGO_CFG_TEST环境变量来区分, 但是我在build.rs里加入该打印后:

println!("env: {:?}", env::var("CARGO_CFG_TEST"));

在target/debug/build/xxx/output里查看到的结果是:

env: Err(NotPresent)

请各位指导下,应该如何处理?我需要在build.rs的编译配置test和正式版本不一样。

评论区

写评论
苦瓜小仔 2024-08-01 16:40

有些内置于 rustc 或者 cargo 的编译选项是特殊的,虽然最终都在控制条件编译,但 cargo 在不同场景下对这些编译选项的支持方式并不一样。这些都以 cargo 的文档为准 —— 因为你现在在问 build.rs,它属于 cargo 而不属于 rustc。

CARGO_CFG_<cfg> ... This includes values built-in to the compiler (which can be seen with rustc --print=cfg) and values set by build scripts and extra flags passed to rustc (such as those defined in RUSTFLAGS).

P.S. #[cfg(test)] 属于 cargo 的 test harness 部分,而 #[test] 属于 rustc 的 --test 部分(rustc --print=cfg 的结果并不包含 test)。

P.S.2 feature 属于 cargo 条件编译

Cargo “features” provide a mechanism to express conditional compilation and optional dependencies.

作者 zaq7434 2024-08-01 16:21

test本身不就是编译选项吗?我查询说是test时 会把CARGO_CFG_TEST设置为true, 但是实际测试没有,感觉很奇怪。

--
👇
苦瓜小仔: println!("env: {:?}", env::var("CARGO_CFG_TEST")); 的意思是通过 cfg flags 控制条件编译,在 build.rs 通过 CARGO_CFG_* 感知。

文档:https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts

CARGO_CFG_<cfg> — For each configuration option of the package being built, this environment variable will contain the value of the configuration, where <cfg> is the name of the configuration uppercased and having - translated to _. Boolean configurations are present if they are set, and not present otherwise. Configurations with multiple values are joined to a single variable with the values delimited by ,. This includes values built-in to the compiler (which can be seen with rustc --print=cfg) and values set by build scripts and extra flags passed to rustc (such as those defined in RUSTFLAGS). Some examples of what these variables are:

比如,你的测试是条件编译控制的:

#[test]
#[cfg(my_test_flag)] # 你自己知道的 cfg flag
fn test() {}
// build.rs
fn main() {
    println!(
        "CARGO_CFG_MY_TEST_FLAG={:?}",
        std::env::var("CARGO_CFG_MY_TEST_FLAG")
    );
}

然后传递 cfg flags 就行了:

RUSTFLAGS='--cfg=my_test_flag' cargo test 

这会涉及一些条件编译的细节,不限于:

  1. RUSTFLAGS 如何传递:比如通过环境变量、或者 $PROJ/.cargo/config.toml 之类的
  2. 使用 -vvv 可以打印完整的 build 阶段的输出(包括 build.rs,不过由于缓存,不是每次都会打印):RUSTFLAGS='--cfg=my_test_flag' cargo test -vvv 可以看到 [你的包名 版本号] CARGO_CFG_MY_TEST_FLAG=Ok(""),并编译那个测试;而 cargo test -vvv 显示 [...] CARGO_CFG_MY_TEST_FLAG=Err(NotPresent),且不编译那个测试
  3. 我只是把 #[cfg(my_test_flag)] 放到测试函数上控制是否编译那个测试函数,你也可以放到 statements / items 之类任何条件编译支持的地方
苦瓜小仔 2024-08-01 10:06

println!("env: {:?}", env::var("CARGO_CFG_TEST")); 的意思是通过 cfg flags 控制条件编译,在 build.rs 通过 CARGO_CFG_* 感知。

文档:https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts

CARGO_CFG_<cfg> — For each configuration option of the package being built, this environment variable will contain the value of the configuration, where <cfg> is the name of the configuration uppercased and having - translated to _. Boolean configurations are present if they are set, and not present otherwise. Configurations with multiple values are joined to a single variable with the values delimited by ,. This includes values built-in to the compiler (which can be seen with rustc --print=cfg) and values set by build scripts and extra flags passed to rustc (such as those defined in RUSTFLAGS). Some examples of what these variables are:

比如,你的测试是条件编译控制的:

#[test]
#[cfg(my_test_flag)] # 你自己知道的 cfg flag
fn test() {}
// build.rs
fn main() {
    println!(
        "CARGO_CFG_MY_TEST_FLAG={:?}",
        std::env::var("CARGO_CFG_MY_TEST_FLAG")
    );
}

然后传递 cfg flags 就行了:

RUSTFLAGS='--cfg=my_test_flag' cargo test 

这会涉及一些条件编译的细节,不限于:

  1. RUSTFLAGS 如何传递:比如通过环境变量、或者 $PROJ/.cargo/config.toml 之类的
  2. 使用 -vvv 可以打印完整的 build 阶段的输出(包括 build.rs,不过由于缓存,不是每次都会打印):RUSTFLAGS='--cfg=my_test_flag' cargo test -vvv 可以看到 [你的包名 版本号] CARGO_CFG_MY_TEST_FLAG=Ok(""),并编译那个测试;而 cargo test -vvv 显示 [...] CARGO_CFG_MY_TEST_FLAG=Err(NotPresent),且不编译那个测试
  3. 我只是把 #[cfg(my_test_flag)] 放到测试函数上控制是否编译那个测试函数,你也可以放到 statements / items 之类任何条件编译支持的地方
1 共 3 条评论, 1 页