如何使运行Cargo build脚本可选?

时间:2018-09-20 09:50:31

标签: build rust rust-cargo

我有一个Rust项目,该项目生成一个动态(cdylib)库。该项目使用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 Language Server)不能很好地工作,这使得在VS Code中进行编辑非常不愉快。是否有一种方法可以使运行构建脚本成为可选操作,默认情况下将其禁用,并且仅在命令行要求时(例如,cargo build --release --enable-build-scripts)手动启用它?

2 个答案:

答案 0 :(得分:5)

您不能有条件地禁用构建脚本或通过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

答案 1 :(得分:3)

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

将以下几行插入Cargo.toml

[features]
headers = []

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

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更新其状态或手动运行cargo test时,此解决方案仍将编译构建脚本和所有cbindgen依赖项。但是cbindgen运行时错误不再妨碍RLS。