如何让 运行 的 Cargo 构建脚本成为可选的?

How can I make running a Cargo build script optional?

我有一个生成动态 (cdylib) 库的 Rust 项目。该项目使用 cbindgen 构建脚本创建相应的 C 头文件,匹配库的导出函数。 Cargo.toml 看起来像这样:

[package]
name = "example"
version = "0.1.0"
authors = ["Me <me@foo.bar>"]
build = "build.rs"

[lib]
name = "example"
crate-type = ["cdylib"]

[dependencies]

[build-dependencies]
cbindgen = "0.6.2"

不幸的是,当构建脚本处于活动状态时,RLS(Rust 语言服务器)不能很好地工作,这使得在 VS Code 中进行编辑变得相当不愉快。有没有办法让 运行 构建脚本可选,默认情况下禁用它,只有在命令行上请求时才手动启用它(即类似 cargo build --release --enable-build-scripts 的东西)?

您不能有条件地禁用构建脚本或通过 cargo build 向它们传递变量,但您可以改用环境变量。

在你的 build.rs 里面:

use std::env;

fn main() {  
    let build_enabled = env::var("BUILD_ENABLED")
        .map(|v| v == "1")
        .unwrap_or(true); // run by default

    if build_enabled {
        // do your build
    }
}

使用您的构建脚本构建:

BUILD_ENABLED=1 cargo build

在没有构建脚本的情况下构建:

BUILD_ENABLED=0 cargo build

要扩展@PeterHall 的答案,可以使用 Cargo "features" 部分将信息传递给构建脚本。

将以下行插入 Cargo.toml:

[features]
headers = []

然后检查 build.rs 中的环境变量 CARGO_FEATURE_HEADERS:

use std::env;

fn write_headers() {
    // call cbindgen ...
}

fn main() {
    let headers_enabled = env::var_os("CARGO_FEATURE_HEADERS").is_some();
    if headers_enabled {
        write_headers();
    }
}

制作发布版本 运行 cargo build --features=headers --release.

现在,当 RLS 更新其状态或手动 运行ning cargo test 时,此解决方案仍会编译构建脚本和所有 cbindgen 依赖项。但是 cbindgen 运行-time 错误不再妨碍 RLS。