Skip to content

Commit

Permalink
Auto merge of #3752 - matklad:always-artifacts, r=alexcrichton
Browse files Browse the repository at this point in the history
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`).
  • Loading branch information
bors committed Feb 27, 2017
2 parents 163de44 + 7bfd7dc commit 3526d8f
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 31 deletions.
62 changes: 35 additions & 27 deletions src/cargo/ops/cargo_rustc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,9 @@ fn compile<'a, 'cfg: 'a>(cx: &mut Context<'a, 'cfg>,
} else {
rustc(cx, unit, exec.clone())?
};
let link_work1 = link_targets(cx, unit)?;
let link_work2 = link_targets(cx, unit)?;
// Need to link targets on both the dirty and fresh
let dirty = work.then(link_work1).then(dirty);
let fresh = link_work2.then(fresh);
let dirty = work.then(link_targets(cx, unit, false)?).then(dirty);
let fresh = link_targets(cx, unit, true)?.then(fresh);
(dirty, fresh, freshness)
};
jobs.enqueue(cx, unit, Job::new(dirty, fresh), freshness)?;
Expand Down Expand Up @@ -291,10 +289,6 @@ fn rustc(cx: &mut Context, unit: &Unit, exec: Arc<Executor>) -> CargoResult<Work
let json_messages = cx.build_config.json_messages;
let package_id = unit.pkg.package_id().clone();
let target = unit.target.clone();
let profile = unit.profile.clone();
let features = cx.resolve.features(unit.pkg.package_id()).iter()
.map(|s| s.to_owned())
.collect();

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

if json_messages {
machine_message::emit(machine_message::Artifact {
package_id: &package_id,
target: &target,
profile: &profile,
features: features,
filenames: filenames.iter().map(|&(ref src, _, _)| {
src.display().to_string()
}).collect(),
});
}

Ok(())
}));

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

/// Link the compiled target (often of form foo-{metadata_hash}) to the
/// final target. This must happen during both "Fresh" and "Compile"
fn link_targets(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
fn link_targets(cx: &mut Context, unit: &Unit, fresh: bool) -> CargoResult<Work> {
let filenames = cx.target_filenames(unit)?;
let package_id = unit.pkg.package_id().clone();
let target = unit.target.clone();
let profile = unit.profile.clone();
let features = cx.resolve.features_sorted(&package_id).into_iter()
.map(|s| s.to_owned())
.collect();
let json_messages = cx.build_config.json_messages;

Ok(Work::new(move |_| {
// If we're a "root crate", e.g. the target of this compilation, then we
// hard link our outputs out of the `deps` directory into the directory
// above. This means that `cargo build` will produce binaries in
// `target/debug` which one probably expects.
for (src, link_dst, _linkable) in filenames {
let mut destinations = vec![];
for &(ref src, ref link_dst, _linkable) in filenames.iter() {
// This may have been a `cargo rustc` command which changes the
// output, so the source may not actually exist.
debug!("Thinking about linking {} to {:?}", src.display(), link_dst);
if !src.exists() || link_dst.is_none() {
if !src.exists() {
continue
}
let dst = link_dst.unwrap();
let dst = match link_dst.as_ref() {
Some(dst) => dst,
None => {
destinations.push(src.display().to_string());
continue;
}
};
destinations.push(dst.display().to_string());

debug!("linking {} to {}", src.display(), dst.display());
if dst.exists() {
fs::remove_file(&dst).chain_error(|| {
human(format!("failed to remove: {}", dst.display()))
})?;
}
fs::hard_link(&src, &dst)
fs::hard_link(src, dst)
.or_else(|err| {
debug!("hard link failed {}. falling back to fs::copy", err);
fs::copy(&src, &dst).map(|_| ())
fs::copy(src, dst).map(|_| ())
})
.chain_error(|| {
human(format!("failed to link or copy `{}` to `{}`",
src.display(), dst.display()))
})?;
}

if json_messages {
machine_message::emit(machine_message::Artifact {
package_id: &package_id,
target: &target,
profile: &profile,
features: features,
filenames: destinations,
fresh: fresh,
});
}
Ok(())
}))
}
Expand Down
1 change: 1 addition & 0 deletions src/cargo/util/machine_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct Artifact<'a> {
pub profile: &'a Profile,
pub features: Vec<String>,
pub filenames: Vec<String>,
pub fresh: bool,
}

impl<'a> Message for Artifact<'a> {
Expand Down
58 changes: 54 additions & 4 deletions tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2512,8 +2512,9 @@ fn compiler_json_error_format() {
authors = ["wycats@example.com"]
"#)
.file("bar/src/lib.rs", r#"fn dead() {}"#);
p.build();

assert_that(p.cargo_process("build").arg("-v")
assert_that(p.cargo("build").arg("-v")
.arg("--message-format").arg("json"),
execs().with_status(0).with_json(r#"
{
Expand Down Expand Up @@ -2544,7 +2545,8 @@ fn compiler_json_error_format() {
"name":"bar",
"src_path":"[..]lib.rs"
},
"filenames":["[..].rlib"]
"filenames":["[..].rlib"],
"fresh": false
}
{
Expand Down Expand Up @@ -2575,7 +2577,54 @@ fn compiler_json_error_format() {
"test": false
},
"features": [],
"filenames": ["[..]"]
"filenames": ["[..]"],
"fresh": false
}
"#));

// With fresh build, we should repeat the artifacts,
// but omit compiler warnings.
assert_that(p.cargo("build").arg("-v")
.arg("--message-format").arg("json"),
execs().with_status(0).with_json(r#"
{
"reason":"compiler-artifact",
"profile": {
"debug_assertions": true,
"debuginfo": 2,
"opt_level": "0",
"test": false
},
"features": [],
"package_id":"bar 0.5.0 ([..])",
"target":{
"kind":["lib"],
"crate_types":["lib"],
"name":"bar",
"src_path":"[..]lib.rs"
},
"filenames":["[..].rlib"],
"fresh": true
}
{
"reason":"compiler-artifact",
"package_id":"foo 0.5.0 ([..])",
"target":{
"kind":["bin"],
"crate_types":["bin"],
"name":"foo",
"src_path":"[..]main.rs"
},
"profile": {
"debug_assertions": true,
"debuginfo": 2,
"opt_level": "0",
"test": false
},
"features": [],
"filenames": ["[..]"],
"fresh": true
}
"#));
}
Expand Down Expand Up @@ -2633,7 +2682,8 @@ fn message_format_json_forward_stderr() {
"test":false
},
"features":[],
"filenames":["[..]"]
"filenames":[],
"fresh": false
}
"#));
}
Expand Down

0 comments on commit 3526d8f

Please sign in to comment.