-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Include executable in JSON output. #5517
Conversation
r? @matklad (rust_highfive has picked a reviewer for you, use r? to override) |
src/cargo/core/compiler/mod.rs
Outdated
@@ -393,6 +393,22 @@ fn link_targets<'a, 'cfg>( | |||
.collect(); | |||
let json_messages = bcx.build_config.json_messages(); | |||
|
|||
// Find the executable for the current target (if any). | |||
let mut executable : Option<PathBuf> = Option::None; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wanted to move this inside the job below but ran into problems with Unit
. Any suggestions of how to resolve these problems are appreciated. Not sure if there are any side effects with the current approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is exactly how it should look like, and it's kinda cool that Rust detects this at compile time. The Work
thing which we create below is a long-lived closure, and works are executed concurrently. If in that closure we close over Context
, than bad things would happen, because several works would try to access Context simultaneously from different threads, and context is not ready for that.
So Rust enforces that we compute all relevant data before hand, and store just simple stuff like String
s inside the Work
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, you can use let mut executable: Option<PathBuf> = None;
, no need to qualify None
. However, I hope when bindist
is extracted as a separate function, this could be simplified to let executable = if produces_executable(unit) { bindist(unit) } else { None }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matklad Awesome explanation. Thanks!
@@ -4213,6 +4217,7 @@ fn message_format_json_forward_stderr() { | |||
"overflow_checks": false, | |||
"test":false | |||
}, | |||
"executable": "{...}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not verifying the executable here since that's not what's being tested here. Is that OK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that's ok!
@matklad Any idea why tests are failing on Linux and MacOS?
|
@patriksvensson The |
src/cargo/core/compiler/mod.rs
Outdated
Some(ref link_dst) => link_dst, | ||
None => &output.path, | ||
}; | ||
if unit.target.is_bin() || unit.target.is_bin_example() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the logic here needs to be adjusted slightly. In Cargo, there are several flavors of excutables:
- binaries and examples, where the user writes
fn main()
themselves - tests and becnhmars, where
fn main()
is synthesized by the compiler - build scripts
I think we definitely should specify "executable" for 1 and 2, and maybe for 3 as well.
The test setup for it would look like this:
λ exa -GT
.
├── benches
│ └── benchmark.rs
├── Cargo.toml
├── src
│ ├── lib.rs
│ └── main.rs
└── tests
└── integration_test.rs
Then, executing cargo test --no-run
should show executables for integration_test
and for lib.rs
(when testing, libary is compiled as an executable which launches unit-tests).
Executing cargo bench --no-run
should show exetable for benchmark
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matklad I'm having some problems with the tests here. It seems like that the JSON lines emitted by cargo test
isn't emitted in a deterministic order. Am I missing something here or might this be a bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is ok: for example, Cargo could compile tests and becnhmarks in parallel, so either can be ready first. You could add with_json_unordered
method to the testing infra to avoid the problem. It also should be possible to modify the test such that there's only one executable per compilation. For example, you can run cargo build --lib
, cargo build --bin
separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matklad Ah, didn't know about the with_json_unordered
approach 👍 I'm going with separate assert passes like you suggest since that one sounds cleaner somehow. Thanks!
src/cargo/core/compiler/mod.rs
Outdated
let bindst = match output.hardlink { | ||
Some(ref link_dst) => link_dst, | ||
None => &output.path, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is duplicated when we populate Compilation::binaries
. Let's extract a helper function fn exetutable_dest(unit: &Unit)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might need access to cx
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matklad Do you mean the let bindst
logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! The "is this unit executable" logic needs to be different.
src/cargo/core/compiler/mod.rs
Outdated
@@ -439,6 +455,7 @@ fn link_targets<'a, 'cfg>( | |||
profile: art_profile, | |||
features, | |||
filenames: destinations, | |||
executable: executable, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be just executable
: if field name and var name are the same, you don't have to write foo: foo
.
@patriksvensson the actual implementation looks great to me, though I think we need to tweak a logic of what is considered an executable. Basically, we need to make sure that tests and benches also have not-None executable in the corresponding artifact. |
@matklad I noticed that for tests (regular one, not integration tests), there is nothing in the metadata about the target that seem to hint about it producing an executable (except the filename when running on Windows).
Any ideas about how to detect this? |
I believe this logic handles this: cargo/src/cargo/core/compiler/context/mod.rs Line 178 in b24b455
|
@matklad Any idea why I get a |
ping @patriksvensson, were you able to track down the CI failures? |
@alexchrichton No, I wasn't. Currently on vacation with family but planning to take another look at it in about 3 days. |
Sure thing, no worries! |
☔ The latest upstream changes (presumably #5651) made this pull request unmergeable. Please resolve the merge conflicts. |
@patriksvensson looks like some tests may still be failing? |
@alexchrichton Yes, I had some spare time so I rebased my PR against master. Will take a look at the failing tests as soon as I have some spare time again. |
Ok, no worries! |
☔ The latest upstream changes (presumably #5711) made this pull request unmergeable. Please resolve the merge conflicts. |
Ok I'm gonna close this for now, but feel free to update and I can always reopen! |
Include executable in JSON output. Fixes #5426 Rebase of @patriksvensson's #5517 CC @matklad I didn't really get into the issue or the code, I just interatively rebased Patrik's branch and then massaged and cleaned up the code until the tests passed. So please double check it for code correctness, test case correctness and test case coverage. Particularly the branch changed an if condition according to [this suggestion](#5517 (comment)) by Aleksey. I rolled that back because at one point it helped fix a series of tests. But let me know if that should be included here.
Closes #5426