-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Pass rustflags to artifacts built with implicit targets when using target-applies-to-host #13900
Pass rustflags to artifacts built with implicit targets when using target-applies-to-host #13900
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @ehuss (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
@rustbot label: Z-target-applies-to-host The original work for this feature was done under Alex Crichton, and no team member has seemingly picked up the feature after he stepped down. Since the original bug isn't marked as "S-accepted" I'm rather ignoring the contributor documentation by submitting this PR in the first place (sorry). If this isn't the direction whatever team member picks this up would like to go in, I'm happy to do something else. If no team member picks this up (which is what the contributing docs suggest should happen)... I guess the PR sits here harmlessly ¯\_(ツ)_/¯ (I'll probably show up at office hours in that case and see if I can prompt some movement). |
If I'm reading the test error correctly, it's a formatting change in the benchmark harness completely unrelated to this PR It's expecting
It's finding
With extra Fixed in #13901 |
If you rebase on latest master, the test issue should be fixed. |
7494b08
to
ba2c5c2
Compare
Rebased on master. Also merged the commit fixing the doc links into the commits moving the the docs around, since I noticed comments on other PRs asking that every commit pass tests. |
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.
Thanks and sorry for the long wait.
Could you follow the "atomic commit" pattern? That is, the first commit show the current buggy behavior and pass all tests, followed by the other commits fix both tests and the bug.
let ct = CompileTarget::new(&rustc.host)?; | ||
target_info.insert(ct, host_info.clone()); | ||
target_config.insert(ct, gctx.target_cfg_triple(&rustc.host)?); | ||
target_config.insert(host_target, gctx.target_cfg_triple(&rustc.host)?); |
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 looks correct.
Would you mind sharing why we need the entire infra change (Arc
and move out rustflags from targetinfo), instead of just the change here?
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 question is basically what "How it is implemented" tries to answer in the original comment on this PR. To take another stab at explaining it here:
The CompileKind
for artifact Unit
starts out as CompileKind::Target(host_target)
(assuming we're not cross compiling). The CompileKind
for host Unit
starts out as CompileKind::Host
This change sets up target_info
so that lookups for CompileKind::Target(host_target)
get the correct rustflags (as well as units with CompileKind::Host
, which need different rustflags). Which is great provided we lookup artifact Unit
's with their original CompileKind
.
rebuild_unit_graph_shared
changes artifact Unit
s with CompileKind::Target(host_target)
to have CompileKind::Host
. It does this so that we can deduplicate identical otherwise identical units and only compile them once*.
The current infrastructure attempts to look up rustflags
via kind
after rebuild_unit_graph_shared
. Thus even though we have correctly set up the target_info
for CompileKind::Target(host_target)
we're going to look up the flags in host_info
, which are wrong. The infrastructure change is to push this lookup forwards to before we rebuild the unit with a different kind
. It is also necessary because we deduplicate Unit
s based on their hash, so even if we could somehow lookup the correct rustflags later, there wouldn't necessarily be a unique set of them (in the case where host and target artifacts have different rustflags, and a shared dependency).
* To draw your attention to the table at the top. This is why no --target flag
, target_applies_to_host=false
has "Without rustflags, built with 5 invocations" rather than 6. A dependency shared between the host artifacts and the target artifacts only has to be built once because it is built the exact same way for both of them.
However this question caused me to double check that my understanding was correct by... trying it. I believe it is, however it turns out my test is broken and will (incorrectly) pass (fail to compile) because passing an invalid rustflag will cause TargetInfo::new(host_target)
to fail because that command calls rustc with rustflags to query file-names/sysroot/... even though we never build a target with those rustflags.
I'll figure out how to write a version of that test without the false-pass on the partial change and push it later tonight.
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.
Thanks. I like the idea that Unit
holds the exact rustflags it is going to invoke. It opens a new door that we might be able to use this information to create the acutal “build plans” for external systems.
There's only one nit left and I'll merge this :)
ba2c5c2
to
b8ce338
Compare
I've done this as requested, as well as incorporation the suggested 1 line change, rebasing on master, and fixing the use of a now-deprecated testing function. I owe you fixing the test so that it doesn't pass on the partial-fix you asked about in the other review commit. |
b8ce338
to
2d693d5
Compare
Alright, pushed an updated test that passes The partial fix branch is here, just for illustrative purposes. |
Oops, pushing again with fixed formatting in the test in the first commit, and a fixed comment in the test in the second commit (just sloppy rebasing on my part) |
2d693d5
to
1f6de2e
Compare
@@ -1587,3 +1587,29 @@ fn host_config_rustflags_with_target() { | |||
.arg("host.rustflags=[\"--cfg=foo\"]") | |||
.run(); | |||
} | |||
|
|||
#[cargo_test] | |||
fn target_applies_to_host_rustflags_works() { |
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.
Should we have a similar test for rustdocflags to prevent regressions?
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.
Sure, just pushed this
let ct = CompileTarget::new(&rustc.host)?; | ||
target_info.insert(ct, host_info.clone()); | ||
target_config.insert(ct, gctx.target_cfg_triple(&rustc.host)?); | ||
target_config.insert(host_target, gctx.target_cfg_triple(&rustc.host)?); |
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.
Thanks. I like the idea that Unit
holds the exact rustflags it is going to invoke. It opens a new door that we might be able to use this information to create the acutal “build plans” for external systems.
There's only one nit left and I'll merge this :)
1f6de2e
to
5be8044
Compare
Thanks a lot! @bors r+ |
☀️ Test successful - checks-actions |
Update cargo 13 commits in a515d463427b3912ec0365d106791f88c1c14e1b..f86ce56396168edf5d0e1c412ddda0b2edba7d46 2024-07-02 20:53:36 +0000 to 2024-07-05 17:52:05 +0000 - test: Migrate jobserver to snapbox (rust-lang/cargo#14191) - chore(deps): update msrv (3 versions) to v1.77 (rust-lang/cargo#14186) - test: migrate build_plan and build_script to snapbox (rust-lang/cargo#14193) - test: migrate cfg and check to snapbox (rust-lang/cargo#14185) - test: migrate install* and inheritable_workspace_fields to snapbox (rust-lang/cargo#14170) - Pass rustflags to artifacts built with implicit targets when using target-applies-to-host (rust-lang/cargo#13900) - test: Migrate network tests to snapbox (rust-lang/cargo#14187) - test: migrate some files to snapbox (rust-lang/cargo#14113) - test: Auto-redact `... after last build at ...`; Migrate `freshness` to Snapbox (rust-lang/cargo#14161) - chore: fix some typos (rust-lang/cargo#14182) - fix: improve message for inactive weak optional feature with edition2024 through unused dep collection (rust-lang/cargo#14026) - test:migrate `doc/directory/docscrape` to snapbox (rust-lang/cargo#14171) - test: Migrate git_auth to snapbox (rust-lang/cargo#14172)
Add rustdocflags to Unit's Debug impl ### What does this PR try to resolve? Not adding this was an oversight in #13900, `rustflags` was added but not `rustdocflags`. Sorry about not getting this right the first time. ### How should we test and review this PR? Read the code and compare to the original PR where the matching line was added for rustflags. r? `@weihanglo`
Update cargo 20 commits in a515d463427b3912ec0365d106791f88c1c14e1b..154fdac39ae9629954e19e9986fd2cf2cdd8d964 2024-07-02 20:53:36 +0000 to 2024-07-07 01:28:23 +0000 - test: relax redactions for rust-lang/rust (rust-lang/cargo#14203) - use "bootstrap" instead of "rustbuild" (rust-lang/cargo#14207) - test: migrate serveral files to snapbox (rust-lang/cargo#14180) - Add rustdocflags to Unit's Debug impl (rust-lang/cargo#14201) - Allow enabling `config-include` feature in config (rust-lang/cargo#14196) - fix(test): Restore `does_not_contain` for check (rust-lang/cargo#14198) - test: migrate patch, pkgid, proc_macro and progress to snapbox (rust-lang/cargo#14181) - test: Migrate jobserver to snapbox (rust-lang/cargo#14191) - chore(deps): update msrv (3 versions) to v1.77 (rust-lang/cargo#14186) - test: migrate build_plan and build_script to snapbox (rust-lang/cargo#14193) - test: migrate cfg and check to snapbox (rust-lang/cargo#14185) - test: migrate install* and inheritable_workspace_fields to snapbox (rust-lang/cargo#14170) - Pass rustflags to artifacts built with implicit targets when using target-applies-to-host (rust-lang/cargo#13900) - test: Migrate network tests to snapbox (rust-lang/cargo#14187) - test: migrate some files to snapbox (rust-lang/cargo#14113) - test: Auto-redact `... after last build at ...`; Migrate `freshness` to Snapbox (rust-lang/cargo#14161) - chore: fix some typos (rust-lang/cargo#14182) - fix: improve message for inactive weak optional feature with edition2024 through unused dep collection (rust-lang/cargo#14026) - test:migrate `doc/directory/docscrape` to snapbox (rust-lang/cargo#14171) - test: Migrate git_auth to snapbox (rust-lang/cargo#14172)
Fix passing of links-overrides with target-applies-to-host and an implicit target ### What does this PR try to resolve? This fixes the link-overrides half of #14195, both the panic, and the fact that the field is being discarded, the latter of which caused the former as discussed in [the issue](#14195 (comment)). It does so following the blueprint laid out in #13900 - which is also in my opinion the current best summary of the broader context. ### How should we test and review this PR? For reviewing, comparing to the changes in #13900 might be useful. ### Additional information I'm pushing a PR for the other half of #14195 simultaneously. I thought it better to keep the PRs small since they're independent, though if merged simultaneously there will be a conflict over the ordering of fields in `Unit`.
Use `Rc` instead of `Arc` for storing rustflags # What does this PR try to resolve? There's no reason that these reference counted pointers (which I introduced in #13900) need to be atomic, so let's use non-atomic pointers. # Additional information First noticed by `@weihanglo` [here](#14205 (comment)). r? `@weihanglo`
What this PR does
This fixes #10744, a long-standing bug with
target-applies-to-host=false
whereRUSTFLAGS
are not being passed to artifact-units when built withcargo build
(as opposed tocargo build --target <host>
).It doesn't fix a similar problem with
linker
andlinks
. If the architecture in this PR is accepted, I expect I will be able to fixlinker
andlinks
in the same way in a subsequent PR.Below is a hopefully useful table of what flags are passed when, with new behavior bolded (without these changes the flag is not passed). I've only changed values in the top right cell, I've included the whole table for completeness and to hopefully make clear what exactly this feature is doing (which took me awhile to understand).
The table was generated with a host of x86_64-unknown-linux-gnu. "Flag" refers to values in RUSTFLAGS. "Linker" refers to the value of
--config target.<host>.linker
. The table was built with this repo and then hand modify to bold changed values.Flag passed to shared dep from bin
Linker passed to bin
Flag passed to proc macro
Flag passed to shared dep from proc macro
Linker passed to proc macro
Built with 5 invocations
Without rustflags, built with 5 invocations
Flag passed to shared dep from bin
Linker not passed to bin
Flag not passed to proc macro
Flag not passed to shared dep from proc macro
Linker not passed to proc macro
Built with 6 invocations
Without rustflags, built with 5 invocations
Flag passed to shared dep from bin
Linker passed to bin
Flag not passed to proc macro
Flag not passed to shared dep from proc macro
Linker passed to proc macro
Built with 6 invocations
Without rustflags, built with 6 invocations
Flag passed to shared dep from bin
Linker passed to bin
Flag not passed to proc macro
Flag not passed to shared dep from proc macro
Linker not passed to proc macro
Built with 6 invocations
Without rustflags, built with 6 invocations
Flag passed to shared dep from bin
Linker not passed to bin
Flag not passed to proc macro
Flag not passed to shared dep from proc macro
Linker passed to proc macro
Built with 6 invocations
Without rustflags, built with 6 invocations
Flag passed to shared dep from bin
Linker not passed to bin
Flag not passed to proc macro
Flag not passed to shared dep from proc macro
Linker not passed to proc macro
Built with 6 invocations
Without rustflags, built with 6 invocations
How it is implemented
There are two stages in the
UnitGraph
's life. It gets built, with correctCompileKind
:CompileKind::Host
for host units,CompileKind::Target(HostTriple)
for artifact units. Then it gets rebuilt with artifact units that are intended for the host having their kind changed toCompileKind::Host
.This rebuilding step serves to de-duplicate host and artifact units. A step that we want to maintain where possible. Because de-duplicating host and artifact dependencies is only possible if their
rustflags
don't differ we must calculaterustflags
for units before this step, and this step necessarily throws away the information necessary to calculate them.The possible rustflags have already been determined before creating units. "Calculating rustflags for units" just means determining which set of rustflags go with a particular unit, and storing that somewhere. The obvious place to do that is in the unit itself, so that's what this PR does, which has the convenient side affect of also handing the de-duplication logic for us. If the rustflags are the same, two units can be merged, if they differ, they cannot.
In the above table that's why it takes 5 invocations to build the repo without rustflags, but 6 with them. The shared_dependency merges when it is built without rustflags, and not when it is built with rustflags.
Related PRs, comments and issues
fixes #10744
#9453 - Tracking issue
#9753 - Stabilization PR
#9634 - I believe this was another attempt (going down another implementation route) to fix the same issue
Comments from Alex Crichton noting that this must be fixed 1 2
My own comment describing exactly how I ran into this
Documentation for the feature