build/cargo: touching unrelated file triggers unnecessary re-link
There seems to be a problem in our incremental build system. I discovered this when comparing uutils against GNU coreutils in a semi-automated way, and my script wrote to some new, unrelated files, because surely that won't impact uutils, right?
Turns out, cargo re-links the coreutils binary whenever a new file pops up:
$ cargo +stable build --all-features
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
$ cargo +stable build --all-features
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
$ cargo +stable build --all-features
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.17s
$ cargo +stable build --all-features
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
$ touch completely_unrelated
$ cargo +stable build --all-features # ?!
Compiling coreutils v0.0.27 (/home/user/workspace/coreutils-rs)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.74s
$ cargo +stable build --all-features
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
$ cargo +stable build --all-features
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
$ cargo +stable build --all-features
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.17s
Notice the extra 2.6 seconds in the middle? that makes everything quite slow. I'm not sure where the bug lives, or even whether it's uutil's fault at all (and perhaps a missed optimization in cargo?), but let's start here.
I may not be the authority here, but it looks like a cargo thing to me. As far as I'm aware, there is no way for cargo projects to force the rebuild without user interaction. I may be wrong though, feel free to correct me.
I don't understand? This issue is about cargo rebuilding too often, and not too seldomly.
What I tried to say was that I don't think it's uutils' fault, rather a bug in cargo. Have you perhaps tried a similar thing on other cargo projects to see if the issue persists?
The build script build.rs does not emit any cargo::rerun-if-changed= directive, which causes the build script to be rebuilt (and the link to retrigger) every time any file is changed within the package.