Skip to content
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

RFC: Provide only std for windows-gnu and not rustc #41165

Closed
TimNN opened this issue Apr 8, 2017 · 14 comments
Closed

RFC: Provide only std for windows-gnu and not rustc #41165

TimNN opened this issue Apr 8, 2017 · 14 comments

Comments

@TimNN
Copy link
Contributor

TimNN commented Apr 8, 2017

Motivation: Compiling LLVM with MinGW is a huge PITA and for LLVM 4.0 would likely require us to switch to "MinGW with Posix Threads" from "MinGW with Win32 Threads".

As far as I know, there should be no reason why an enduser would require rustc to be available compiled by MinGW (Edit: as pointed out below, unless they have a compiler plugin which requires windows-gnu).

Such a change would likely require modifications to any or multiple of rustc, rustup and rustbuild, depending on the approach taken.

Another benefit: This would probably get rid of 95% of spurious appveyor failures.

cc @alexcrichton, @retep998, @rust-lang/tools

@TimNN TimNN added the T-tools label Apr 8, 2017
@TimNN TimNN mentioned this issue Apr 8, 2017
5 tasks
@TimNN
Copy link
Contributor Author

TimNN commented Apr 8, 2017

Nominated since this seems like an important change to the rust release / deployment process.

@hanna-kruppe
Copy link
Contributor

Wouldn't this break compiler plugins? (Including procedural macros, unless and until those move into separate processes.) Rust code compiled for windows-gnu can't link with compiler libraries compiled for windows-msvc.

@TimNN
Copy link
Contributor Author

TimNN commented Apr 8, 2017

Compiler plugins work today while cross compiling, so they should continue to work, shouldn't they?

(Unless the compiler plugin can only be compiled with windows-gnu and not with windows-msvc).

@hanna-kruppe
Copy link
Contributor

Good point, I missed that because I didn't think of this as cross compiling. However, when cross compiling, you normally have a full host tool chain. For this proposal that would mean you'd need Visual Studio installed to compile windows-gnu crates which transitively use plugins (which more and more crates will, now that custom derive is stable). That amounts to eliminating windows-gnu as a host platform and demoting it to a cross compilation target. I'm not sure if that's acceptable.

@TimNN
Copy link
Contributor Author

TimNN commented Apr 8, 2017

However, when cross compiling, you normally have a full host tool chain. For this proposal that would mean you'd need Visual Studio installed to compile windows-gnu crates which transitively use plugins (which more and more crates will, now that custom derive is stable).

Indeed, I hadn't thought of that. This does make my proposal significantly less appealing.

@alexcrichton
Copy link
Member

Unfortunately while I would very much enjoy implementing such a proposal I don't think that it's possible. As @rkruppe brought up plugins (and also build scripts) will throw a wrench into this.

Cargo currently assumes that if it doesn't pass --target then the resulting artifact is suitable for loading into a plugin. This basically means that Cargo will compile all plugins omitting --target (also proc-macros) and it has a similar assumption for build scripts (the host can run binaries compiled without --target).

Finally, Cargo also deduplicates compilations as much as possible. If you've got a build script that depends on crate foo, and then your library also depends on crate foo, then the crate foo will only be compiled once if you omit the --target argument to Cargo.

Unfortunately all of these are incompatible (I think at least) with a compiler that produces a different target by default. Let's say we have a MSVC host compiler with a MinGW target.

  • If the compiler defaults to MSVC when omitting --target, then cargo build will break as it will produce a MSVC binary.
  • If the compiler defaults to MinGW when omitting --target, then procedural macros will break as they'll be compiled incorrectly.
  • If Cargo were to always pass --target then it would have to understand default host/default target differences
  • If Cargo were to always pass --target then it would force all compiles of crate foo above to compile foo twice, instead of once today.

I fear that our only recourse here is to simply deprecate the MinGW host compiler. This would be a serious blow to usability, however, as you've discovered because that means that to be productive in Rust you'll need a Visual Studio installation no matter what.

Now I think an argument can be made that you should have Visual Studio regardless. It really does seem like we're going in the direction of making MinGW purely a cross-compiled target, not a hosted target. We simply do not have a choice if LLVM does not compile.

@petrochenkov
Copy link
Contributor

The primary missing alternative - make sure LLVM compiles on MinGW (with posix threads if needed), communicate to LLVM devs that MinGW is important, send patches if necessary.
MSYS2 packages LLVM so they are probably interested in this as well, maybe their work can be reused.
This may be less effort consuming and certainly more constructive than deprecating a tier 1 platform.
(I'm obviously biased, because this is my primary platform for years.)

@vadimcn
Copy link
Contributor

vadimcn commented Apr 8, 2017

My PR #40805 allows building rust with "pthreads" mingw-w64, including the one packaged by msys.
I think the pain of dealing with -gnu toolchain is a bit overstated here.

@retep998
Copy link
Member

retep998 commented Apr 8, 2017

If we made compiler plugins into cdylibs instead of dylibs and we made the compiler invoke them through a plain C ABI interface that does not transfer ownership of any resources or unwind, then it wouldn't matter whether the plugin was compiled with the same target_env. We'd be able to have an i686-pc-windows-msvc rustc load a plugin compiled for i686-pc-windows-gnu since they have the same C ABI. For build scripts this is actually much easier, since sometimes the architecture doesn't even have to match. x86_64-pc-windows-msvc will always be able to run an i686-pc-windows-gnu build script for example. The only problem with this is figuring out how we'd teach cargo this magical knowledge, and also doing some fairly major changes to the technical aspects of plugins.

@hanna-kruppe
Copy link
Contributor

@retep998 That would probably work for current custom derives, but it becomes increasingly unworkable as the proc_macro API surface increases. After a certain point not too far away from the current state, it would be easier to just make it a whole separate process and communicate via IPC, as has been proposed before.

What's worse, it's entirely impractical for other kinds of plugins (e.g., lints like clippy) which directly interact with large portions of rustc internals.

@TimNN
Copy link
Contributor Author

TimNN commented Apr 9, 2017

Thanks for all the comments. It seems like this is not something we want to do at this time, so I'm gonna close this for now.

Out of curiosity, would a functional lld alleviate the need for Visual Studio for the -msvc targets?

@TimNN TimNN closed this as completed Apr 9, 2017
@retep998
Copy link
Member

retep998 commented Apr 9, 2017

@TimNN As I've said before we need 1. the linker 2. the CRT and 3. the windows SDK. A functional lld would replace only 1. Since such a pure lld target with no msvc available would not be able to rely on the CRT, it means we would not be able to statically link C/C++ code, so I'd rather not modify the -msvc targets. Instead I'd prefer to add a new third target_env for pure Rust only which uses lld, doesn't use the CRT at all, and emits idata sections to avoid needing the Windows SDK.

@TimNN
Copy link
Contributor Author

TimNN commented Apr 9, 2017

@retep998: Thanks for the explanation!

@mati865
Copy link
Contributor

mati865 commented Apr 12, 2017

MSYS2 have few not critical LLVM 4.0 patches (0001-0007) but they are enough to let it work fine: https://github.com/Alexpux/MINGW-packages/tree/master/mingw-w64-clang
It's not packaged yet because many packages using libLLVM doesn't build with it.

As it was mentioned earlier MinGW GCC/Clang and MSVC produce ABI incompatible libs so mixing is impossible.

BTW lld is still mostly unusable for MinGW hosts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants