Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default target conflicts with explicit targets causing full recompile #9239

Closed
Skepfyr opened this issue Mar 5, 2021 · 7 comments
Closed
Labels
C-bug Category: bug

Comments

@Skepfyr
Copy link

Skepfyr commented Mar 5, 2021

Problem
Running cargo (incrementally) without an explicit target conflicts with running cargo with an explicit target in that it causes all dependencies to be recompiled. Compiling with multiple different explicit targets doesn't conflict however. I'd expect compiling without an explicit target to behave the same as compiling with the default target.

One surprising thing that I noticed here is that cargo check --target x86_64-unknown-linux-musl creates the target/x86_64-unknown-linux-musl/debug directory and the target/debug directory.

Steps

  1. cargo new --bin blah
  2. Add a dependency (I tested with rand 0.8)
  3. Run cargo check --target x86_64-unknown-linux-gnu
  4. Run cargo check --target x86_64-unknown-linux-musl
  5. Run cargo check --target x86_64-unknown-linux-gnu (This should reuse cached builds)
  6. Run cargo check --target x86_64-unknown-linux-musl (This should reuse cached builds)
  7. Run cargo check (This will rebuild all dependencies)
  8. Run cargo check --target x86_64-unknown-linux-gnu (This will suddenly rebuild all dependencies)

Notes

Output of cargo version: cargo 1.50.0 (f04e7fa 2021-02-04)

@Skepfyr Skepfyr added the C-bug Category: bug label Mar 5, 2021
@ehuss
Copy link
Contributor

ehuss commented Mar 5, 2021

Hm, I'm unable to reproduce with the given steps. If you're still able to reproduce, can you run the final command with the CARGO_LOG=cargo::core::compiler::fingerprint=trace environment variable set, and post the output?

One surprising thing that I noticed here is that cargo check --target x86_64-unknown-linux-musl creates the target/x86_64-unknown-linux-musl/debug directory and the target/debug directory.

This is normal. Host artifacts (such as build scripts and proc macros) go into target/debug.

I'd expect compiling without an explicit target to behave the same as compiling with the default target.

There are some subtle differences if you specify --target and if you don't, which are somewhat intentional. This is described a bit in the Build Cache documentation.

@Skepfyr
Copy link
Author

Skepfyr commented Mar 5, 2021

So I tested this out on another machine and couldn't replicate it, and after a bit of debugging I think it is occurring because I have the following in my cargo config:

[build]
rustflags = ["-C", "link-arg=-fuse-ld=lld"]

The extra log output (from one of the runs that requires a rebuild) is here: https://github.com/rust-lang/cargo/files/6093143/check.log

@Skepfyr
Copy link
Author

Skepfyr commented Mar 5, 2021

The output always conatins the line:

err: current filesystem status shows we're outdated

If the last command run specified a target then cargo check contains this line:

err: RUSTFLAGS has changed: ["-C", "link-arg=-fuse-ld=lld"] != []

After that cargo check --target x86_64-unknown-linux-gnu contains this line:

err: RUSTFLAGS has changed: [] != ["-C", "link-arg=-fuse-ld=lld"]

Another cargo check --target=x86_64-unknown-linux-musl now doesn't contain any lines mentioning RUSTFLAGS, and if the gnu and musl are run the other way around the first one always contains the RUSTFLAGS mention, and the second doesn't.

@ehuss
Copy link
Contributor

ehuss commented Mar 5, 2021

Ah, yea, that's somewhat expected for now. Changes in RUSTFLAGS are not segregated in separate files/directories, so changing RUSTFLAGS will trigger a rebuild, and the way RUSTFLAGS interacts with build scripts can be a bit awkward (they are used for build scripts if --target is not specified, but not otherwise).

There are several other issues tracking that behavior (#8716, #6375, #4423, #3739), so closing in favor of one of those. One workaround is to use different target directories, though I realize that is fairly cumbersome.

@ehuss ehuss closed this as completed Mar 5, 2021
@Skepfyr
Copy link
Author

Skepfyr commented Mar 8, 2021

For anyone who stumbles across this in the future and this hasn't been solved, I've solved this by adding my default target to the cargo config, e.g.

[build]
target = "x86_64-unkown-linux-gnu"

At a guess, that's making cargo behave as if it always runs with --target x86_64-unknown-linux-gnu and so cargo check and --target x86_64-unknown-linux-gnu now behave identically.

@kjvalencik
Copy link

kjvalencik commented Mar 30, 2021

I can confirm that this issue still exists in cargo 1.51.0 (43b129a20 2021-03-16) and that the workaround provided by @Skepfyr is effective. FYI, I am not changing RUSTFLAGS based on target. This is sufficient to trigger the issue:

[build]
rustflags = ["-C", "force-unwind-tables"]

It appears cargo things these flags changed, even though they did not:

[2021-03-30T13:49:26Z INFO  cargo::core::compiler::fingerprint]     err: RUSTFLAGS has changed: previously [], now ["-C", "force-unwind-tables"]

It only occurs when switching targets. It happens in reverse when specifying the target:

[2021-03-30T13:50:27Z INFO  cargo::core::compiler::fingerprint]     err: RUSTFLAGS has changed: previously ["-C", "force-unwind-tables"], now []

It even happens if both are the same target, but one is using the default and the other is specifying --target.

@ehuss Can this issue be re-opened or should I file a new issue?

Edit: After further testing, it's directly related to the default target. Switching targets continues to cache correctly as long as --target is always specified. Switching between the default and a manually specified --target causes the issue.

@ehuss
Copy link
Contributor

ehuss commented Mar 30, 2021

@kjvalencik Unfortunately for now that is expected behavior. Due to #8716, RUSTFLAGS is not part of the filename hash. Due to #4423 RUSTFLAGS are not used for build scripts when --target is specified. Combining the two means that host dependencies can switch whether or not they use RUSTFLAGS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

3 participants