rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
96.77k stars 12.5k forks source link

`cargo build` and `cargo test` always expire each other build cache #129820

Open loynoir opened 2 weeks ago

loynoir commented 2 weeks ago

bug

very common scenario let build cache expired

version

1.80.0

edit

actual

N th build is expected.

$ cargo build --profile xxx && yarn workspaces foreach --all run postbuild
...
255.36s user 15.29s system 110% cpu 4:04.42 total

N+1 th build are also expected.

$ cargo build --profile xxx && yarn workspaces foreach --all run postbuild
...
15.90s user 1.18s system 100% cpu 16.910 total
$ cargo build --profile xxx && yarn workspaces foreach --all run postbuild
...
15.27s user 1.11s system 104% cpu 15.685 total
$ cargo build --profile xxx && yarn workspaces foreach --all run postbuild
...
15.65s user 1.07s system 104% cpu 16.081 total

BUT unexpectedly, cargo test seems expire all cache.

$ cargo test --profile xxx
...
391.13s user 24.45s system 114% cpu 6:04.12 total

Below cargo test are expected.

$ cargo test --profile xxx
...
0.66s user 0.39s system 16% cpu 6.182 total
$ cargo test --profile xxx
...
0.45s user 0.23s system 122% cpu 0.555 total

Unexpectedly, cargo build expire cargo test cache.

$ cargo build --profile xxx && yarn workspaces foreach --all run postbuild
...
247.31s user 15.54s system 110% cpu 3:58.70 total
$ cargo build --profile xxx && yarn workspaces foreach --all run postbuild
...
15.57s user 1.04s system 103% cpu 16.054 total

expected

additional

I always see compiling all the dep tree again and again and again and again and again.

saethlin commented 2 weeks ago

very common

This is not common. Something is changing about your build settings which is not obvious here. The usual cause of this is your editor running cargo check in the background with a different set of flags than your builds done at the CLI. If you add --verbose to your builds you should see messages like this:

Dirty zerocopy v0.7.35: the rustflags changed

which should contain some explanation about what is changing between builds that is causing the cache to be evicted.

loynoir commented 2 weeks ago

The usual cause of this is your editor running cargo check in the background with a different set of flags than your builds done at the CLI.

I'm using vscode with RA using seperated profile, so seems not editor extension problem.

        "rust-analyzer.cargo.extraArgs": [
            "--profile",
            "x-rust-analyzer"
        ],

Currently, I workaround with cargo build and cargo test with different profiles.

Maybe debug what happen with --verbose when later. :)

loynoir commented 2 weeks ago

Long story short:


I deleted old profile with cargo clean, nothing else changed.

[profile.release]
debug = false
strip = true
opt-level = 3
lto = true
codegen-units = 1
panic = "abort"

[profile.x-reproduce]
inherits = "release"
  1. cargo build --profile x-reproduce stable at 0.09s, 136 deps, 136 fresh, 0 dirty, 0 compiling.

  2. cargo test --profile x-reproduce use 14:28.60 total, 154 deps, 19 fresh, 0 dirty, 135 compiling.

  3. cargo test --profile x-reproduce use 0.286 total, 154 deps, 154 fresh, 0 dirty, 0 compiling.

  4. cargo build --profile x-reproduce use 0.130 total, 136 deps, 136 fresh, 0 dirty, 0 compiling.

Cannot reproduce build cache problem again.

Before I delete old profile, I was able to 100% reproduce that multiple times.


Speak of why I let RA use seperate profile, background problem is https://github.com/rust-lang/rust-analyzer/issues/15057

        "rust-analyzer.cargo.extraArgs": [
            "--profile",
            "x-rust-analyzer"
        ],

Not sure why build cache problem happen again here.

Maybe a rust build cache sometime drop into always happen bug?

Maybe a sccache bug?

I have no idea.

hanna-kruppe commented 2 weeks ago

Aside: I don't think it explains repeated from-scratch rebuilds, but cargo test and panic = "abort" is a bad combination because the libtest harness needs unwinding, so Cargo will build all your crates and all dependencies twice: once with panic=abort for cargo {build,run} and once with panic=unwind for cargo test. After that's done and if nothing else causes a full rebuild, cargo will happily keep both versions in the target directory and reuse them, but it will make any spurious or legitimate rebuilds even more annoying, so you might want to fix it regardless.