'How can I force `build.rs` to run again without cleaning my whole project?
How can I force build.rs to run again without cleaning my whole project? I checked cargo build --help but I couldn't find anything related to build.rs.
Solution 1:[1]
Register build.rs as a crate's bin target:
- Add this to your
Cargo.tomlfile:
[package]
edition = "2018"
build = "build.rs"
[[bin]]
name = "force-build"
path = "build.rs"
required-features = ["build_deps"] # only needed for build-dependencies
- If you have any
[build-dependencies](e.g.some_crate = "1.2.3"), you need to add those to (the main)[dependencies](sadly no[bin-dependencies]as of yet), but you can make them optional:
[dependencies]
some_crate = { version = "1.2.3", optional = true }
[features]
build_deps = ["some_crate"]
Then you can run the build script with:
$ cargo run --bin force-build --features build_deps
(or $ cargo run --bin force-build when no [build-dependencies])
You can even disable the automatic call of the build script by replacing the
build = "build.rs"line inCargo.tomlwithbuild = falseNote: since the
OUT_DIRenv var is not present forbintargets, if yourbuild.rsscript usesenv!("OUT_DIR"), you may "fix this" by usingconcat!(env!("CARGO_MANIFEST_DIR"), "/target/")instead.
Solution 2:[2]
If build.rs changes, Cargo already rebuilds the project:
Note that if the build script itself (or one of its dependencies) changes, then it's rebuilt and rerun unconditionally, so
cargo:rerun-if-changed=build.rsis almost always redundant (unless you want to ignore changes in all other files except forbuild.rs). doc
On Linux, I will just do touch build.rs && cargo build. For Windows, see Windows equivalent of the Linux command 'touch'?
Solution 3:[3]
If you got target under gitignore (which you should) this might be useful for any file changes when you're developing and testing the build script.
if Path::new(".git/HEAD").exists() {
println!("cargo:rerun-if-changed=.git/HEAD");
}
Solution 4:[4]
if you're trying to rebuild based on non-rust or include!() files that might've changed, you can use
const _: &[u8] = include_bytes!("foobar.baz");
to ensure that any changes to those files will trigger a new build. pretty sure this solution adds neither time nor filesize.
you can shove this into a macro too, so its easy to do a bunch of files.
macro_rules! build_on{($file:literal) => {
const _: &[u8] = include_bytes!($file);
}
build_on!("foobar.baz");
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Caesar |
| Solution 2 | Shepmaster |
| Solution 3 | Seivan |
| Solution 4 |
