-
Notifications
You must be signed in to change notification settings - Fork 14k
Windows-gnullvm self-contained #147536
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
base: main
Are you sure you want to change the base?
Windows-gnullvm self-contained #147536
Conversation
|
Tested locally on Windows but a shareable build would be useful. |
This comment has been minimized.
This comment has been minimized.
Windows-gnullvm self-contained try-job: dist-x86_64-linux try-job: dist-x86_64-windows-gnullvm
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
@bors try jobs=dist-x86_64-linux,dist-x86_64-windows-gnullvm |
This comment has been minimized.
This comment has been minimized.
Windows-gnullvm self-contained try-job: dist-x86_64-linux try-job: dist-x86_64-windows-gnullvm
|
Seems to work nicely, even with |
|
@mati865 are there any blockers we could help you with? |
|
@estebank I had a few ideas how to refactor it, but none of them turned out satisfying. I'm going to take another stab at it this week. |
f3f33b7 to
9d27d77
Compare
This comment has been minimized.
This comment has been minimized.
9d27d77 to
9f92112
Compare
This comment was marked as resolved.
This comment was marked as resolved.
9f92112 to
48d04c8
Compare
48d04c8 to
2b5ac0b
Compare
|
@bors try jobs=dist-x86_64-linux,dist-x86_64-windows-gnullvm |
This comment has been minimized.
This comment has been minimized.
Windows-gnullvm self-contained try-job: dist-x86_64-linux try-job: dist-x86_64-windows-gnullvm
| let self_contained_target = sess.target.os == Os::Windows | ||
| && sess.target.env == Env::Gnu | ||
| && sess.target.abi == Abi::Llvm | ||
| && self_contained_components.is_linker_enabled(); | ||
| if self_contained_target | ||
| && let Some(ret) = | ||
| infer_from(sess, None, Some(LinkerFlavor::Gnu(Cc::No, Lld::Yes)), features) | ||
| { | ||
| return ret; | ||
| } |
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 doesn't feel nice, but alternatives would involve modifying the target spec to somehow allow configuring two different linkers.
|
Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 This PR modifies If appropriate, please update These commits modify compiler targets. |
| } | ||
| } | ||
|
|
||
| fn make_win_llvm_dist(plat_root: &Path, target: TargetSelection, builder: &Builder<'_>) { |
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.
Nit: maybe put it next to fn make_win_dist? I tried to look above and below to check the difference between the two functions, but didn't find what I searched for.
| "libmingw32.a", | ||
| "libmingwex.a", | ||
| "libmsvcrt.a", | ||
| // Windows import libs, remove them once std transitions to raw-dylib |
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.
Wait, it didn't transition yet? I clearly remember some PR doing that. Maybe not for this target specifically?
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.
Std is still built without raw-dylib:
rust/src/bootstrap/src/core/builder/cargo.rs
Lines 665 to 668 in c199562
| if let Mode::Rustc | Mode::ToolRustcPrivate | Mode::ToolBootstrap | Mode::ToolTarget = mode | |
| { | |
| rustflags.arg("--cfg=windows_raw_dylib"); | |
| } |
| return ret; | ||
| } | ||
|
|
||
| // When using a supported target in self-contained linker mode, we want to use rust-lld directly. |
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 dislike this at pretty fundamental level.
-Clink-self-contained isn't supposed to change the linker flavor, only to change where the linker (and other things) are looked up.
If windows-gnullvm targets can be built with naked linker, without clang, then perhaps they should change the default linker and linker flavor to ld.lld?
Are windows-gnullvm targets stable enough for it to be considered a breaking change?
Also, in self-contained mode we are supposed to use ld.lld from the self-contained directory, not rust-lld.
It seems like the logic below results in that, but then the comment above is misleading.
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.
If windows-gnullvm targets can be built with naked linker, without clang
Basically all the targets can be linked with just a linker without CC driver given you provide required objects and libraries.
Currently, Rust ships those libraries and objects for *-pc-windows-gnu (in rust-mingw component) and some musl targets (I don't know which ones exactly; definitely x86_64 and aarch64). Which means they could just pass those shipped libs to the linker directly if they are using them anyway (so we are using -Clink-self-contained).
For example, take x86_64-pc-windows-gnu. It ships x86_64-w64-mingw32-gcc.exe and ld.exe, but it doesn't really matter whether we call x86_64-w64-mingw32-gcc -l[rust objects] -l[mingw-w64 objects and libs] -o result.exe or ld -l[rust objects] -l[mingw-w64 objects and libs] -o result.exe as long as you add the flags in the correct form, i.e. prepend them with -Wl, when using GCC as the proxy. It was just easier to ship GCC binary and reuse the code.
What I'm trying to achieve here is to pass the libraries directly to LLD in self-contained-mode for windows-gnullvm hosts, so it can run similarly to windows-gnu hosts even when there is no mingw-w64 toolchain installed. But also keep the previous behaviour, which will call x86_64-w64-mingw32-clang from PATH if it finds one.
Shipping clang is difficult because of its sheer size, so writing a wrapper that just calls LLD would be more feasible.
then perhaps they should change the default linker and linker flavor to
ld.lld?
This would be a groundbreaking change. That would mean it no longer uses user's toolchain and libraries. I think this would be pretty bad.
Also, in self-contained mode we are supposed to use ld.lld from the self-contained directory, not rust-lld.
There are no self-contained binaries, only lib/rustlib/x86_64-pc-windows-gnullvm/bin/gcc-ld/ which contains various wrappers over rust-lld.
|
|
||
| // Returns true if linker is located within sysroot | ||
| fn detect_self_contained_mingw(sess: &Session, linker: &Path) -> bool { | ||
| // Assume `-C linker=rust-lld` as self-contained mode |
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.
The logic here pre-dates windows-gnullvm targets, so apparently someone used windows-gnu targets with the naked rust-lld linker, and I see some supports for that in the target specs.
But this PR removes the self-contained mode from windows-gnu + rust-lld mode, what is the reason for that?
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.
Ah, I lost that in one of the refactors of this code.
I happen to know the person who did it: https://github.com/rust-lang/rust/pull/76167/files#diff-862130c0af71054886913befc8084094485fa7d764d95f55644e033e34acd126R1214
No description provided.