Skip to content

Commit dcb4360

Browse files
committed
Auto merge of #6503 - Eh2406:RUSTFLAGS-in-Metadata, r=ehuss
Rustflags in metadata This is a small change that adds Rustflags to the `Metadata`. This means, for example, that if you do a plane build then build with "-C target-cpu=native", you will get 2 copies of the dependencies. Con, more space if you are changing Rustflags. Pro, not rebuilding all the dependencies when you switch back. Suggested by <https://internals.rust-lang.org/t/idea-cargo-global-binary-cache/9002/31>
2 parents 34320d2 + 6d24d57 commit dcb4360

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/cargo/core/compiler/context/compilation_files.rs

+37
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,34 @@ use super::{BuildContext, Context, FileFlavor, Kind, Layout, Unit};
1212
use crate::core::{TargetKind, Workspace};
1313
use crate::util::{self, CargoResult};
1414

15+
/// The `Metadata` is a hash used to make unique file names for each unit in a build.
16+
/// For example:
17+
/// - A project may depend on crate `A` and crate `B`, so the package name must be in the file name.
18+
/// - Similarly a project may depend on two versions of `A`, so the version must be in the file name.
19+
/// In general this must include all things that need to be distinguished in different parts of
20+
/// the same build. This is absolutely required or we override things before
21+
/// we get chance to use them.
22+
///
23+
/// We use a hash because it is an easy way to guarantee
24+
/// that all the inputs can be converted to a valid path.
25+
///
26+
/// This also acts as the main layer of caching provided by Cargo.
27+
/// For example, we want to cache `cargo build` and `cargo doc` separately, so that running one
28+
/// does not invalidate the artifacts for the other. We do this by including `CompileMode` in the
29+
/// hash, thus the artifacts go in different folders and do not override each other.
30+
/// If we don't add something that we should have, for this reason, we get the
31+
/// correct output but rebuild more than is needed.
32+
///
33+
/// Some things that need to be tracked to ensure the correct output should definitely *not*
34+
/// go in the `Metadata`. For example, the modification time of a file, should be tracked to make a
35+
/// rebuild when the file changes. However, it would be wasteful to include in the `Metadata`. The
36+
/// old artifacts are never going to be needed again. We can save space by just overwriting them.
37+
/// If we add something that we should not have, for this reason, we get the correct output but take
38+
/// more space than needed. This makes not including something in `Metadata`
39+
/// a form of cache invalidation.
40+
///
41+
/// Note that the `Fingerprint` is in charge of tracking everything needed to determine if a
42+
/// rebuild is needed.
1543
#[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
1644
pub struct Metadata(u64);
1745

@@ -465,6 +493,15 @@ fn compute_metadata<'a, 'cfg>(
465493
args.hash(&mut hasher);
466494
}
467495

496+
// Throw in the rustflags we're compiling with.
497+
// This helps when the target directory is a shared cache for projects with different cargo configs,
498+
// or if the user is experimenting with different rustflags manually.
499+
if unit.mode.is_doc() {
500+
cx.bcx.rustdocflags_args(unit).ok().hash(&mut hasher);
501+
} else {
502+
cx.bcx.rustflags_args(unit).ok().hash(&mut hasher);
503+
}
504+
468505
// Artifacts compiled for the host should have a different metadata
469506
// piece than those compiled for the target, so make sure we throw in
470507
// the unit's `kind` as well

tests/testsuite/freshness.rs

+23
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,29 @@ fn reuse_shared_build_dep() {
11531153
.run();
11541154
}
11551155

1156+
#[test]
1157+
fn changing_rustflags_is_cached() {
1158+
let p = project().file("src/lib.rs", "").build();
1159+
1160+
p.cargo("build").run();
1161+
p.cargo("build")
1162+
.env("RUSTFLAGS", "-C target-cpu=native")
1163+
.with_stderr(
1164+
"\
1165+
[COMPILING] foo v0.0.1 ([..])
1166+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
1167+
)
1168+
.run();
1169+
// This should not recompile!
1170+
p.cargo("build")
1171+
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
1172+
.run();
1173+
p.cargo("build")
1174+
.env("RUSTFLAGS", "-C target-cpu=native")
1175+
.with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]")
1176+
.run();
1177+
}
1178+
11561179
#[test]
11571180
fn reuse_panic_build_dep_test() {
11581181
let p = project()

0 commit comments

Comments
 (0)