Cargo test --all vs cargo test in sub-crate build times

I have a project composed from various sub-crates. If I follow a cargo test --all run by doing a cargo test in each crate directory I notice that cargo needs to recompile a lot of dependencies. These were presumably compiled in the previous cargo test --all run. It seems like build artifacts aren't being shared.

Is this expected behaviour? or is it likely my project's build configuration etc.

For some extra context, this creates an issue for CI builds as cargo test --all is very slow to build in my project. I'd like to run tests on a per crate basis but the cost of recompiling each crate in the end vastly out weights the caching given by cargo test --all

It's the currently defined behaviour (you could call it expected, just not what you expected before).

I think this is how cargo works (by observation, haven't actually seen code):

  1. Based on the command, determine the minimum set of crates to compile for the current "compilation session".
  2. If the set of crates hasn't been compiled for before, then compile everything. Not sure how this detection is done (hash everything?).

This does mean if you have:

  • Two crates in a workspace, A and B
  • Both depend on a shared dependency C
  • A requires C without feature C1
  • B requires C with feature C1

Then:

  • cargo test --all will compile C once with C1 enabled
  • cargo test inside A's directory will compile C without C1
  • cargo test inside B's directory will compile C with C1. I don't think it will reuse C1 from cargo test --all (need someone with more knowledge to clarify).

What I do on CI is (gist):

  • Compile everything once, and collect the test binary names: cargo test --all --no-run --message-format=json
  • Run them individually with coverage
1 Like

Thanks @azriel91, it's nice to know it's not an isolated thing.
I'm experimenting with setting CARGO_TARGET_DIR and that seems to provide some caching

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.