Skip to content

Commit 3526d8f

Browse files
committed
Auto merge of #3752 - matklad:always-artifacts, r=alexcrichton
Always produce artifact messages This changes `artifact` messages in several ways: * They are produced even for fresh builds * They used the path after hard linking (@jsgf talked about it in the end of #3319 (comment)) * Don't produce filenames if the compiler has not actually produced the binaries (`-Z-no-trans`).
2 parents 163de44 + 7bfd7dc commit 3526d8f

File tree

3 files changed

+90
-31
lines changed

3 files changed

+90
-31
lines changed

src/cargo/ops/cargo_rustc/mod.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,9 @@ fn compile<'a, 'cfg: 'a>(cx: &mut Context<'a, 'cfg>,
230230
} else {
231231
rustc(cx, unit, exec.clone())?
232232
};
233-
let link_work1 = link_targets(cx, unit)?;
234-
let link_work2 = link_targets(cx, unit)?;
235233
// Need to link targets on both the dirty and fresh
236-
let dirty = work.then(link_work1).then(dirty);
237-
let fresh = link_work2.then(fresh);
234+
let dirty = work.then(link_targets(cx, unit, false)?).then(dirty);
235+
let fresh = link_targets(cx, unit, true)?.then(fresh);
238236
(dirty, fresh, freshness)
239237
};
240238
jobs.enqueue(cx, unit, Job::new(dirty, fresh), freshness)?;
@@ -291,10 +289,6 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc<Executor>) -> CargoResult<Work
291289
let json_messages = cx.build_config.json_messages;
292290
let package_id = unit.pkg.package_id().clone();
293291
let target = unit.target.clone();
294-
let profile = unit.profile.clone();
295-
let features = cx.resolve.features(unit.pkg.package_id()).iter()
296-
.map(|s| s.to_owned())
297-
.collect();
298292

299293
exec.init(cx);
300294
let exec = exec.clone();
@@ -388,18 +382,6 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc<Executor>) -> CargoResult<Work
388382
fingerprint::append_current_dir(&dep_info_loc, &cwd)?;
389383
}
390384

391-
if json_messages {
392-
machine_message::emit(machine_message::Artifact {
393-
package_id: &package_id,
394-
target: &target,
395-
profile: &profile,
396-
features: features,
397-
filenames: filenames.iter().map(|&(ref src, _, _)| {
398-
src.display().to_string()
399-
}).collect(),
400-
});
401-
}
402-
403385
Ok(())
404386
}));
405387

@@ -435,38 +417,64 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc<Executor>) -> CargoResult<Work
435417

436418
/// Link the compiled target (often of form foo-{metadata_hash}) to the
437419
/// final target. This must happen during both "Fresh" and "Compile"
438-
fn link_targets(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
420+
fn link_targets(cx: &mut Context, unit: &Unit, fresh: bool) -> CargoResult<Work> {
439421
let filenames = cx.target_filenames(unit)?;
422+
let package_id = unit.pkg.package_id().clone();
423+
let target = unit.target.clone();
424+
let profile = unit.profile.clone();
425+
let features = cx.resolve.features_sorted(&package_id).into_iter()
426+
.map(|s| s.to_owned())
427+
.collect();
428+
let json_messages = cx.build_config.json_messages;
429+
440430
Ok(Work::new(move |_| {
441431
// If we're a "root crate", e.g. the target of this compilation, then we
442432
// hard link our outputs out of the `deps` directory into the directory
443433
// above. This means that `cargo build` will produce binaries in
444434
// `target/debug` which one probably expects.
445-
for (src, link_dst, _linkable) in filenames {
435+
let mut destinations = vec![];
436+
for &(ref src, ref link_dst, _linkable) in filenames.iter() {
446437
// This may have been a `cargo rustc` command which changes the
447438
// output, so the source may not actually exist.
448-
debug!("Thinking about linking {} to {:?}", src.display(), link_dst);
449-
if !src.exists() || link_dst.is_none() {
439+
if !src.exists() {
450440
continue
451441
}
452-
let dst = link_dst.unwrap();
442+
let dst = match link_dst.as_ref() {
443+
Some(dst) => dst,
444+
None => {
445+
destinations.push(src.display().to_string());
446+
continue;
447+
}
448+
};
449+
destinations.push(dst.display().to_string());
453450

454451
debug!("linking {} to {}", src.display(), dst.display());
455452
if dst.exists() {
456453
fs::remove_file(&dst).chain_error(|| {
457454
human(format!("failed to remove: {}", dst.display()))
458455
})?;
459456
}
460-
fs::hard_link(&src, &dst)
457+
fs::hard_link(src, dst)
461458
.or_else(|err| {
462459
debug!("hard link failed {}. falling back to fs::copy", err);
463-
fs::copy(&src, &dst).map(|_| ())
460+
fs::copy(src, dst).map(|_| ())
464461
})
465462
.chain_error(|| {
466463
human(format!("failed to link or copy `{}` to `{}`",
467464
src.display(), dst.display()))
468465
})?;
469466
}
467+
468+
if json_messages {
469+
machine_message::emit(machine_message::Artifact {
470+
package_id: &package_id,
471+
target: &target,
472+
profile: &profile,
473+
features: features,
474+
filenames: destinations,
475+
fresh: fresh,
476+
});
477+
}
470478
Ok(())
471479
}))
472480
}

src/cargo/util/machine_message.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub struct Artifact<'a> {
3333
pub profile: &'a Profile,
3434
pub features: Vec<String>,
3535
pub filenames: Vec<String>,
36+
pub fresh: bool,
3637
}
3738

3839
impl<'a> Message for Artifact<'a> {

tests/build.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,8 +2512,9 @@ fn compiler_json_error_format() {
25122512
authors = ["[email protected]"]
25132513
"#)
25142514
.file("bar/src/lib.rs", r#"fn dead() {}"#);
2515+
p.build();
25152516

2516-
assert_that(p.cargo_process("build").arg("-v")
2517+
assert_that(p.cargo("build").arg("-v")
25172518
.arg("--message-format").arg("json"),
25182519
execs().with_status(0).with_json(r#"
25192520
{
@@ -2544,7 +2545,8 @@ fn compiler_json_error_format() {
25442545
"name":"bar",
25452546
"src_path":"[..]lib.rs"
25462547
},
2547-
"filenames":["[..].rlib"]
2548+
"filenames":["[..].rlib"],
2549+
"fresh": false
25482550
}
25492551
25502552
{
@@ -2575,7 +2577,54 @@ fn compiler_json_error_format() {
25752577
"test": false
25762578
},
25772579
"features": [],
2578-
"filenames": ["[..]"]
2580+
"filenames": ["[..]"],
2581+
"fresh": false
2582+
}
2583+
"#));
2584+
2585+
// With fresh build, we should repeat the artifacts,
2586+
// but omit compiler warnings.
2587+
assert_that(p.cargo("build").arg("-v")
2588+
.arg("--message-format").arg("json"),
2589+
execs().with_status(0).with_json(r#"
2590+
{
2591+
"reason":"compiler-artifact",
2592+
"profile": {
2593+
"debug_assertions": true,
2594+
"debuginfo": 2,
2595+
"opt_level": "0",
2596+
"test": false
2597+
},
2598+
"features": [],
2599+
"package_id":"bar 0.5.0 ([..])",
2600+
"target":{
2601+
"kind":["lib"],
2602+
"crate_types":["lib"],
2603+
"name":"bar",
2604+
"src_path":"[..]lib.rs"
2605+
},
2606+
"filenames":["[..].rlib"],
2607+
"fresh": true
2608+
}
2609+
2610+
{
2611+
"reason":"compiler-artifact",
2612+
"package_id":"foo 0.5.0 ([..])",
2613+
"target":{
2614+
"kind":["bin"],
2615+
"crate_types":["bin"],
2616+
"name":"foo",
2617+
"src_path":"[..]main.rs"
2618+
},
2619+
"profile": {
2620+
"debug_assertions": true,
2621+
"debuginfo": 2,
2622+
"opt_level": "0",
2623+
"test": false
2624+
},
2625+
"features": [],
2626+
"filenames": ["[..]"],
2627+
"fresh": true
25792628
}
25802629
"#));
25812630
}
@@ -2633,7 +2682,8 @@ fn message_format_json_forward_stderr() {
26332682
"test":false
26342683
},
26352684
"features":[],
2636-
"filenames":["[..]"]
2685+
"filenames":[],
2686+
"fresh": false
26372687
}
26382688
"#));
26392689
}

0 commit comments

Comments
 (0)