Skip to content

Commit

Permalink
Auto merge of #8927 - alexcrichton:why-rebuild, r=Eh2406
Browse files Browse the repository at this point in the history
Add an FAQ for "Why is my crate rebuilt?"

In hindsight we should have added this long ago, but I feel like we get
this enough that it's worth adding a deidcated entry we can point to.
  • Loading branch information
bors committed Dec 1, 2020
2 parents 6de98d1 + e95193d commit cee17c2
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/doc/src/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,61 @@ replacement][replace].
[replace]: reference/source-replacement.md
[`cargo fetch`]: commands/cargo-fetch.md
[offline config]: reference/config.md#netoffline

### Why is Cargo rebuilding my code?

Cargo is responsible for incrementally compiling crates in your project. This
means that if you type `cargo build` twice the second one shouldn't rebuild you
crates.io dependencies, for example. Nevertheless bugs arise and Cargo can
sometimes rebuild code when you're not expecting it!

We've long [wanted to provide better diagnostics about
this](https://github.com/rust-lang/cargo/issues/2904) but unfortunately haven't
been able to make progress on that issue in quite some time. In the meantime,
however, you can debug a rebuild at least a little by by setting the `CARGO_LOG`
environment variable:

```sh
$ CARGO_LOG=cargo::core::compiler::fingerprint=info cargo build
```

This will cause Cargo to print out a lot of information about diagnostics and
rebuilding. This can often contain clues as to why your project is getting
rebuilt, although you'll often need to connect some dots yourself since this
output isn't super easy to read just yet. Note that the `CARGO_LOG` needs to be
set for the command that rebuilds when you think it should not. Unfortunately
Cargo has no way right now of after-the-fact debugging "why was that rebuilt?"

Some issues we've seen historically which can cause crates to get rebuilt are:

* A build script prints `cargo:rerun-if-changed=foo` where `foo` is a file that
doesn't exist and nothing generates it. In this case Cargo will keep running
the build script thinking it will generate the file but nothing ever does. The
fix is to avoid printing `rerun-if-changed` in this scenario.

* Two successive Cargo builds may differ in the set of features enabled for some
dependencies. For example if the first build command builds the whole
workspace and the second command builds only one crate, this may causes a
dependency on crates.io to have a different set of features enabled, causing
it and everything that depends on it to get rebuilt. There's unfortunately not
really a great fix for this, although if possible it's best to have the set of
features enabled on a crate constant regardless of what you're building in
your workspace.

* Some filesystems exhibit unusual behavior around timestamps. Cargo primarily
uses timestamps on files to govern whether rebuilding needs to happen, but if
you're using a nonstandard filesystem it may be affecting the timestamps
somehow (e.g. truncating them, causing them to drift, etc). In this scenario
feel free to open an issue and we can see if we can accomodate the filesystem
somehow.

* A concurrent build process is either deleting artifacts or modifying files.
Sometimes you might have a background process that either tries to build or
check your project. These background processes might surprisingly delete some
build artifacts or touch files (or maybe just by accident), which can cause
rebuilds to look spurious! The best fix here would be to wrangle the
background process to avoid clashing with your work.

If after trying to debug your issue, however, you're still running into problems
then feel free to [open an
issue](https://github.com/rust-lang/cargo/issuses/new)!

0 comments on commit cee17c2

Please sign in to comment.