From 982b9e8f9e766f901968cb548c1b8bf2b44c5288 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 30 Nov 2018 21:58:18 +0000 Subject: [PATCH 1/6] Switch Artifacts.filenames to paths --- src/cargo/core/compiler/mod.rs | 4 ++-- src/cargo/util/machine_message.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index d1f92ceb89a..498806768bf 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -432,11 +432,11 @@ fn link_targets<'a, 'cfg>( let dst = match output.hardlink.as_ref() { Some(dst) => dst, None => { - destinations.push(src.display().to_string()); + destinations.push(src.clone()); continue; } }; - destinations.push(dst.display().to_string()); + destinations.push(dst.clone()); hardlink_or_copy(src, dst)?; if let Some(ref path) = output.export_path { let export_dir = export_dir.as_ref().unwrap(); diff --git a/src/cargo/util/machine_message.rs b/src/cargo/util/machine_message.rs index 993c00521fa..16bd5a7e262 100644 --- a/src/cargo/util/machine_message.rs +++ b/src/cargo/util/machine_message.rs @@ -33,7 +33,7 @@ pub struct Artifact<'a> { pub target: &'a Target, pub profile: ArtifactProfile, pub features: Vec, - pub filenames: Vec, + pub filenames: Vec, pub fresh: bool, } From 282f238d93b55a72d71167ac8b79906dfa0bc614 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 30 Nov 2018 14:31:01 +0000 Subject: [PATCH 2/6] Include executable in JSON output. --- .../compiler/context/compilation_files.rs | 10 +++ src/cargo/core/compiler/context/mod.rs | 22 +++++- src/cargo/core/compiler/mod.rs | 2 + src/cargo/util/machine_message.rs | 3 + tests/testsuite/bench.rs | 78 +++++++++++++++++++ tests/testsuite/build.rs | 7 ++ tests/testsuite/test.rs | 77 ++++++++++++++++++ 7 files changed, 195 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs index 276e053cf5e..cb13d669061 100644 --- a/src/cargo/core/compiler/context/compilation_files.rs +++ b/src/cargo/core/compiler/context/compilation_files.rs @@ -49,6 +49,16 @@ pub struct OutputFile { pub flavor: FileFlavor, } +impl OutputFile { + /// Gets the hardlink if present. Otherwise returns the path. + pub fn bindst(&self) -> &PathBuf { + return match self.hardlink { + Some(ref link_dst) => link_dst, + None => &self.path, + }; + } +} + impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { pub(super) fn new( roots: &[Unit<'a>], diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index 8252af66f6b..40eb985c16f 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -163,10 +163,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { continue; } - let bindst = match output.hardlink { - Some(ref link_dst) => link_dst, - None => &output.path, - }; + let bindst = output.bindst(); if unit.mode == CompileMode::Test { self.compilation.tests.push(( @@ -274,6 +271,23 @@ impl<'a, 'cfg> Context<'a, 'cfg> { Ok(self.compilation) } + /// Returns the executable for the specified unit (if any). + pub fn get_executable(&mut self, unit: &Unit<'a>) -> CargoResult> { + for output in self.outputs(unit)?.iter() { + if output.flavor == FileFlavor::DebugInfo { + continue; + } + + let is_binary = unit.target.is_bin() || unit.target.is_bin_example(); + let is_test = unit.mode.is_any_test() && !unit.mode.is_check(); + + if is_binary || is_test { + return Ok(Option::Some(output.bindst().clone())); + } + } + return Ok(None); + } + pub fn prepare_units( &mut self, export_dir: Option, diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 498806768bf..95497adbc76 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -409,6 +409,7 @@ fn link_targets<'a, 'cfg>( .map(|s| s.to_owned()) .collect(); let json_messages = bcx.build_config.json_messages(); + let executable = cx.get_executable(unit)?; let mut target = unit.target.clone(); if let TargetSourcePath::Metabuild = target.src_path() { // Give it something to serialize. @@ -463,6 +464,7 @@ fn link_targets<'a, 'cfg>( profile: art_profile, features, filenames: destinations, + executable, fresh, }); } diff --git a/src/cargo/util/machine_message.rs b/src/cargo/util/machine_message.rs index 16bd5a7e262..a41ce918fc8 100644 --- a/src/cargo/util/machine_message.rs +++ b/src/cargo/util/machine_message.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + use serde::ser; use serde_json::{self, value::RawValue}; @@ -34,6 +36,7 @@ pub struct Artifact<'a> { pub profile: ArtifactProfile, pub features: Vec, pub filenames: Vec, + pub executable: Option, pub fresh: bool, } diff --git a/tests/testsuite/bench.rs b/tests/testsuite/bench.rs index 5e57278b48c..5c54c5d4dcc 100644 --- a/tests/testsuite/bench.rs +++ b/tests/testsuite/bench.rs @@ -1485,3 +1485,81 @@ fn bench_virtual_manifest_all_implied() { .with_stdout_contains("test bench_bar ... bench: [..]") .run(); } + +#[test] +fn json_artifact_includes_executable_for_benchmark() { + if !is_nightly() { + return; + } + + let p = project() + .file("src/main.rs", "fn main() {}") + .file( + "benches/benchmark.rs", + r#" + #![feature(test)] + extern crate test; + + use test::Bencher; + + #[bench] + fn bench_foo(_: &mut Bencher) -> () { () } + "#, + ) + .build(); + + p.cargo("bench --no-run --message-format=json") + .with_json(r#" + { + "executable": "[..]/foo/target/release/foo[EXE]", + "features": [], + "filenames": "{...}", + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "bin" ], + "kind": [ "bin" ], + "edition": "2015", + "name": "foo", + "src_path": "[..]/foo/src/main.rs" + } + } + + { + "executable": "[..]/foo/target/release/foo-[..][EXE]", + "features": [], + "filenames": [ "[..]/foo/target/release/foo-[..][EXE]" ], + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "bin" ], + "kind": [ "bin" ], + "edition": "2015", + "name": "foo", + "src_path": "[..]/foo/src/main.rs" + } + } + + { + "executable": "[..]/foo/target/release/benchmark-[..][EXE]", + "features": [], + "filenames": [ "[..]/foo/target/release/benchmark-[..][EXE]" ], + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "bin" ], + "kind": [ "bench" ], + "edition": "2015", + "name": "benchmark", + "src_path": "[..]/foo/benches/benchmark.rs" + } + } + "#) + .run(); +} diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 09f044f7981..3bf70548d99 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -3083,6 +3083,7 @@ fn compiler_json_error_format() { "overflow_checks": true, "test": false }, + "executable": null, "features": [], "filenames": "{...}", "fresh": false @@ -3110,6 +3111,7 @@ fn compiler_json_error_format() { "overflow_checks": true, "test": false }, + "executable": null, "features": [], "package_id":"bar 0.5.0 ([..])", "target":{ @@ -3162,6 +3164,7 @@ fn compiler_json_error_format() { "overflow_checks": true, "test": false }, + "executable": "[..]/foo/target/debug/foo[EXE]", "features": [], "filenames": "{...}", "fresh": false @@ -3191,6 +3194,7 @@ fn compiler_json_error_format() { "overflow_checks": true, "test": false }, + "executable": null, "features": [], "filenames": "{...}", "fresh": true @@ -3205,6 +3209,7 @@ fn compiler_json_error_format() { "overflow_checks": true, "test": false }, + "executable": null, "features": [], "package_id":"bar 0.5.0 ([..])", "target":{ @@ -3244,6 +3249,7 @@ fn compiler_json_error_format() { "overflow_checks": true, "test": false }, + "executable": "[..]/foo/target/debug/foo[EXE]", "features": [], "filenames": "{...}", "fresh": true @@ -3309,6 +3315,7 @@ fn message_format_json_forward_stderr() { "overflow_checks": false, "test":false }, + "executable": "{...}", "features":[], "filenames": "{...}", "fresh": false diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index d3f24e5bf41..9bc4993da05 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -3004,6 +3004,7 @@ fn json_artifact_includes_test_flag() { "overflow_checks": true, "test": false }, + "executable": null, "features": [], "package_id":"foo 0.0.1 ([..])", "target":{ @@ -3026,6 +3027,7 @@ fn json_artifact_includes_test_flag() { "overflow_checks": true, "test": true }, + "executable": "[..]/foo-[..]", "features": [], "package_id":"foo 0.0.1 ([..])", "target":{ @@ -3042,6 +3044,81 @@ fn json_artifact_includes_test_flag() { ).run(); } +#[test] +fn json_artifact_includes_executable_for_library_tests() { + let p = project() + .file("src/main.rs", "fn main() { }") + .file("src/lib.rs", r#"#[test] fn lib_test() {}"#) + .build(); + + p.cargo("test --lib -v --no-run --message-format=json") + .with_json(r#" + { + "executable": "[..]/foo/target/debug/foo-[..][EXE]", + "features": [], + "filenames": "{...}", + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "lib" ], + "kind": [ "lib" ], + "edition": "2015", + "name": "foo", + "src_path": "[..]/foo/src/lib.rs" + } + } + "#) + .run(); +} + +#[test] +fn json_artifact_includes_executable_for_integration_tests() { + let p = project() + .file("src/main.rs", "fn main() {}") + .file("tests/integration_test.rs", r#"#[test] fn integration_test() {}"#) + .build(); + + p.cargo("test -v --no-run --message-format=json --test integration_test") + .with_json(r#" + { + "executable": "[..]/foo/target/debug/foo[EXE]", + "features": [], + "filenames": "{...}", + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "bin" ], + "kind": [ "bin" ], + "edition": "2015", + "name": "foo", + "src_path": "[..]/foo/src/main.rs" + } + } + + { + "executable": "[..]/foo/target/debug/integration_test-[..][EXE]", + "features": [], + "filenames": "{...}", + "fresh": false, + "package_id": "foo 0.0.1 ([..])", + "profile": "{...}", + "reason": "compiler-artifact", + "target": { + "crate_types": [ "bin" ], + "kind": [ "test" ], + "edition": "2015", + "name": "integration_test", + "src_path": "[..]/foo/tests/integration_test.rs" + } + } + "#) + .run(); +} + #[test] fn test_build_script_links() { let p = project() From c78cd0ceb78460c99bbd7f29711e384878780363 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 30 Nov 2018 23:15:31 +0000 Subject: [PATCH 3/6] Ignore filenames, to avoid extra Windows file Apparently on Windows it creates an .exe & a .pdb. --- tests/testsuite/bench.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testsuite/bench.rs b/tests/testsuite/bench.rs index 5c54c5d4dcc..4cb237a419f 100644 --- a/tests/testsuite/bench.rs +++ b/tests/testsuite/bench.rs @@ -1530,7 +1530,7 @@ fn json_artifact_includes_executable_for_benchmark() { { "executable": "[..]/foo/target/release/foo-[..][EXE]", "features": [], - "filenames": [ "[..]/foo/target/release/foo-[..][EXE]" ], + "filenames": "{...}", "fresh": false, "package_id": "foo 0.0.1 ([..])", "profile": "{...}", From b0046c084d33627caa651ae14abc7d9da3d4d424 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 30 Nov 2018 23:16:34 +0000 Subject: [PATCH 4/6] Fix message order --- tests/testsuite/test.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index 9bc4993da05..c64dd127d65 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -3080,10 +3080,11 @@ fn json_artifact_includes_executable_for_integration_tests() { .file("tests/integration_test.rs", r#"#[test] fn integration_test() {}"#) .build(); - p.cargo("test -v --no-run --message-format=json --test integration_test") + // Using jobs=1 to ensure that the order of messages is consistent. + p.cargo("test -v --no-run --message-format=json --jobs=1 --test integration_test") .with_json(r#" { - "executable": "[..]/foo/target/debug/foo[EXE]", + "executable": "[..]/foo/target/debug/integration_test-[..][EXE]", "features": [], "filenames": "{...}", "fresh": false, @@ -3092,15 +3093,15 @@ fn json_artifact_includes_executable_for_integration_tests() { "reason": "compiler-artifact", "target": { "crate_types": [ "bin" ], - "kind": [ "bin" ], + "kind": [ "test" ], "edition": "2015", - "name": "foo", - "src_path": "[..]/foo/src/main.rs" + "name": "integration_test", + "src_path": "[..]/foo/tests/integration_test.rs" } } { - "executable": "[..]/foo/target/debug/integration_test-[..][EXE]", + "executable": "[..]/foo/target/debug/foo[EXE]", "features": [], "filenames": "{...}", "fresh": false, @@ -3109,10 +3110,10 @@ fn json_artifact_includes_executable_for_integration_tests() { "reason": "compiler-artifact", "target": { "crate_types": [ "bin" ], - "kind": [ "test" ], + "kind": [ "bin" ], "edition": "2015", - "name": "integration_test", - "src_path": "[..]/foo/tests/integration_test.rs" + "name": "foo", + "src_path": "[..]/foo/src/main.rs" } } "#) From 70af0636d41942fb755c6930b3a72c99e5486064 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 1 Dec 2018 16:52:20 +0000 Subject: [PATCH 5/6] Simplify & fix int test test --- tests/testsuite/test.rs | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index c64dd127d65..a16dfb3b0be 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -3076,12 +3076,10 @@ fn json_artifact_includes_executable_for_library_tests() { #[test] fn json_artifact_includes_executable_for_integration_tests() { let p = project() - .file("src/main.rs", "fn main() {}") .file("tests/integration_test.rs", r#"#[test] fn integration_test() {}"#) .build(); - // Using jobs=1 to ensure that the order of messages is consistent. - p.cargo("test -v --no-run --message-format=json --jobs=1 --test integration_test") + p.cargo("test -v --no-run --message-format=json --test integration_test") .with_json(r#" { "executable": "[..]/foo/target/debug/integration_test-[..][EXE]", @@ -3099,23 +3097,6 @@ fn json_artifact_includes_executable_for_integration_tests() { "src_path": "[..]/foo/tests/integration_test.rs" } } - - { - "executable": "[..]/foo/target/debug/foo[EXE]", - "features": [], - "filenames": "{...}", - "fresh": false, - "package_id": "foo 0.0.1 ([..])", - "profile": "{...}", - "reason": "compiler-artifact", - "target": { - "crate_types": [ "bin" ], - "kind": [ "bin" ], - "edition": "2015", - "name": "foo", - "src_path": "[..]/foo/src/main.rs" - } - } "#) .run(); } From 020efe02f5aaeec9e4cdf16af3047dd76971bab6 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 1 Dec 2018 18:35:31 +0000 Subject: [PATCH 6/6] Trim the bench test so it cannot be non-deterministic --- tests/testsuite/bench.rs | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/tests/testsuite/bench.rs b/tests/testsuite/bench.rs index 4cb237a419f..c912981678f 100644 --- a/tests/testsuite/bench.rs +++ b/tests/testsuite/bench.rs @@ -1493,7 +1493,6 @@ fn json_artifact_includes_executable_for_benchmark() { } let p = project() - .file("src/main.rs", "fn main() {}") .file( "benches/benchmark.rs", r#" @@ -1510,40 +1509,6 @@ fn json_artifact_includes_executable_for_benchmark() { p.cargo("bench --no-run --message-format=json") .with_json(r#" - { - "executable": "[..]/foo/target/release/foo[EXE]", - "features": [], - "filenames": "{...}", - "fresh": false, - "package_id": "foo 0.0.1 ([..])", - "profile": "{...}", - "reason": "compiler-artifact", - "target": { - "crate_types": [ "bin" ], - "kind": [ "bin" ], - "edition": "2015", - "name": "foo", - "src_path": "[..]/foo/src/main.rs" - } - } - - { - "executable": "[..]/foo/target/release/foo-[..][EXE]", - "features": [], - "filenames": "{...}", - "fresh": false, - "package_id": "foo 0.0.1 ([..])", - "profile": "{...}", - "reason": "compiler-artifact", - "target": { - "crate_types": [ "bin" ], - "kind": [ "bin" ], - "edition": "2015", - "name": "foo", - "src_path": "[..]/foo/src/main.rs" - } - } - { "executable": "[..]/foo/target/release/benchmark-[..][EXE]", "features": [],