Skip to content

Commit

Permalink
Auto merge of #8755 - ehuss:fingerprint-lto, r=alexcrichton
Browse files Browse the repository at this point in the history
Add LTO to the metadata filename hash.

There are some rare cases where different cargo commands end up building dependencies with different LTO settings. This adds the LTO value to the filename hash so that the cache does not thrash when switching between these commands.

Fixes #8669
  • Loading branch information
bors committed Oct 5, 2020
2 parents f5e5e0e + a2e48fd commit 9d1a486
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ fn compute_metadata(
// settings like debuginfo and whatnot.
unit.profile.hash(&mut hasher);
unit.mode.hash(&mut hasher);
cx.lto[unit].hash(&mut hasher);

// Artifacts compiled for the host should have a different metadata
// piece than those compiled for the target, so make sure we throw in
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
let mut queue = JobQueue::new(self.bcx);
let mut plan = BuildPlan::new();
let build_plan = self.bcx.build_config.build_plan;
self.lto = super::lto::generate(&self.bcx)?;
self.prepare_units()?;
self.prepare()?;
custom_build::build_map(&mut self)?;
super::lto::generate(&mut self)?;
self.check_collistions()?;

for unit in &self.bcx.roots {
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
//! -C incremental=… flag | ✓ |
//! mtime of sources | ✓[^3] |
//! RUSTFLAGS/RUSTDOCFLAGS | ✓ |
//! LTO flags | ✓ |
//! LTO flags | ✓ |
//! config settings[^5] | ✓ |
//! is_std | | ✓
//!
Expand Down
17 changes: 8 additions & 9 deletions src/cargo/core/compiler/lto.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::core::compiler::{CompileMode, Context, CrateType, Unit};
use crate::core::compiler::{BuildContext, CompileMode, CrateType, Unit};
use crate::core::profiles;
use crate::util::interning::InternedString;

Expand Down Expand Up @@ -40,9 +40,9 @@ pub enum Lto {
OnlyObject,
}

pub fn generate(cx: &mut Context<'_, '_>) -> CargoResult<()> {
pub fn generate(bcx: &BuildContext<'_, '_>) -> CargoResult<HashMap<Unit, Lto>> {
let mut map = HashMap::new();
for unit in cx.bcx.roots.iter() {
for unit in bcx.roots.iter() {
let root_lto = match unit.profile.lto {
// LTO not requested, no need for bitcode.
profiles::Lto::Bool(false) | profiles::Lto::Off => Lto::OnlyObject,
Expand All @@ -60,10 +60,9 @@ pub fn generate(cx: &mut Context<'_, '_>) -> CargoResult<()> {
}
}
};
calculate(cx, &mut map, unit, root_lto)?;
calculate(bcx, &mut map, unit, root_lto)?;
}
cx.lto = map;
Ok(())
Ok(map)
}

/// Whether or not any of these crate types need object code.
Expand All @@ -87,7 +86,7 @@ fn lto_when_needs_object(crate_types: &[CrateType]) -> Lto {
}

fn calculate(
cx: &Context<'_, '_>,
bcx: &BuildContext<'_, '_>,
map: &mut HashMap<Unit, Lto>,
unit: &Unit,
parent_lto: Lto,
Expand Down Expand Up @@ -185,8 +184,8 @@ fn calculate(
}
};

for dep in cx.unit_deps(unit) {
calculate(cx, map, &dep.unit, merged_lto)?;
for dep in &bcx.unit_graph[unit] {
calculate(bcx, map, &dep.unit, merged_lto)?;
}
Ok(())
}
75 changes: 75 additions & 0 deletions tests/testsuite/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,3 +778,78 @@ fn dylib_rlib_bin() {
);
verify_lto(&output, "foo", "--crate-type bin", Lto::Run(None));
}

#[cargo_test]
fn fresh_swapping_commands() {
// In some rare cases, different commands end up building dependencies
// with different LTO settings. This checks that it doesn't cause the
// cache to thrash in that scenario.
Package::new("bar", "1.0.0").publish();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
bar = "1.0"
[profile.release]
lto = true
"#,
)
.file("src/lib.rs", "pub fn foo() { println!(\"hi!\"); }")
.build();

p.cargo("build --release -v")
.with_stderr(
"\
[UPDATING] [..]
[DOWNLOADING] crates ...
[DOWNLOADED] bar v1.0.0 [..]
[COMPILING] bar v1.0.0
[RUNNING] `rustc --crate-name bar [..]-C linker-plugin-lto[..]
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc --crate-name foo src/lib.rs [..]-C linker-plugin-lto[..]
[FINISHED] [..]
",
)
.run();
p.cargo("test --release -v")
.with_stderr_unordered(
"\
[COMPILING] bar v1.0.0
[RUNNING] `rustc --crate-name bar [..]-C embed-bitcode=no[..]
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib[..]-C embed-bitcode=no[..]
[RUNNING] `rustc --crate-name foo src/lib.rs [..]-C embed-bitcode=no[..]--test[..]
[FINISHED] [..]
[RUNNING] `[..]/foo[..]`
[DOCTEST] foo
[RUNNING] `rustdoc [..]-C embed-bitcode=no[..]
",
)
.run();

p.cargo("build --release -v")
.with_stderr(
"\
[FRESH] bar v1.0.0
[FRESH] foo [..]
[FINISHED] [..]
",
)
.run();
p.cargo("test --release -v --no-run -v")
.with_stderr(
"\
[FRESH] bar v1.0.0
[FRESH] foo [..]
[FINISHED] [..]
",
)
.run();
}

0 comments on commit 9d1a486

Please sign in to comment.