Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make running a Cargo build script optional?

I have a Rust project that generates a dynamic (cdylib) library. The project uses a cbindgen build script to create an according C header file, matching the exported functions of the library. Cargo.toml looks like this:

[package]
name = "example"
version = "0.1.0"
authors = ["Me <[email protected]>"]
build = "build.rs"

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

[dependencies]

[build-dependencies]
cbindgen = "0.6.2"

Unfortunately RLS (Rust Language Server) doesn't work very well when the build script is active which makes editing in VS Code rather unpleasant. Is there a way to make running the build script optional, having it disabled by default and only manually enable it when requested on the command-line (i.e. something like cargo build --release --enable-build-scripts)?

like image 793
blerontin Avatar asked Dec 08 '22 13:12

blerontin


2 Answers

You can't conditionally disable build scripts or pass variables to them via cargo build, but you can make use of environment variables instead.

Inside your 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 with your build script:

BUILD_ENABLED=1 cargo build

Build without your build script:

BUILD_ENABLED=0 cargo build
like image 131
Peter Hall Avatar answered Jan 15 '23 03:01

Peter Hall


To extend the answer from @PeterHall one can use a Cargo "features" section to pass information on to the build script.

Insert the following lines into Cargo.toml:

[features]
headers = []

Then check for environment variable CARGO_FEATURE_HEADERS in 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();
    }
}

To make a release build run cargo build --features=headers --release.

Now this solution still compiles the build script and all cbindgen dependencies when RLS updates its status or when manually running cargo test. But cbindgen run-time errors do not hamper RLS anymore.

like image 39
blerontin Avatar answered Jan 15 '23 05:01

blerontin