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

installing Rust on Windows without Microsoft C++ Build Tools #3358

Closed
garretwilson opened this issue May 17, 2023 · 8 comments
Closed

installing Rust on Windows without Microsoft C++ Build Tools #3358

garretwilson opened this issue May 17, 2023 · 8 comments

Comments

@garretwilson
Copy link

garretwilson commented May 17, 2023

Problem you are trying to solve

I want to install Rust on Windows without using the Microsoft C++ Build Tools, because I prefer not to install gigabytes of license-restricted software just to be able to compile a Rust program on Windows.

Solution you'd like

I want to install and use Rust normally on Windows without the Microsoft C++ Build Tools.

Notes

Here are some links that discuss this:

I'll stop there because it's the same thing over and over.

  • The posts keep mentioning mingw. Does that mean I can go find mingw and install it, and everything will magically work? Or is there something else I need to do?
  • Another comment mentioned that lld-link works. What is lld-link, and what do I need to do to use it? Is it better than the mingw route?
@garretwilson
Copy link
Author

garretwilson commented May 17, 2023

As I noted in #2912, I'll be happy to help update the documentation once I figure out what needs to be done to avoid Microsoft C++ Build Tools.

@ChrisDenton
Copy link
Member

The docs attempt to explain the difference between MSVC and GNU ABI https://rust-lang.github.io/rustup/installation/windows.html

The installer also has the option:

  1. Don't install the prerequisites
    (if you're targeting the GNU ABI).

@Diggsey
Copy link
Contributor

Diggsey commented May 18, 2023

If you are only compiling pure Rust code then you can use the -gnu toolchain and no extra dependencies are required. You don't need mingw or anything like that. In the same way, if you are only compiling pure Rust code, then the only things Rust's -msvc toolchain uses from the MSVC Build Tools is the linker - the commend you saw about the LLD linker is an alternative linker from the LLVM project that can be use instead of the one from the build tools. You'd have to research how to configure the compiler to use that linker but it shouldn't be too complicated, and if you figure it out I'm sure the documentation would be appreciated.

However, many rust crates pull in C or C++ code, so if you use one of those crates you'll need a valid C/C++ toolchain to build that dependency. Using the -mscv toolchain with the MSVC Build Tools are the easiest way to do that, and I would strongly recommend using them if you are compiling for windows as it is the option that "just works". However, you can use the -gnu toolchain with MinGW with some caveats.

One of the downsides to using MinGW is that it links to a very old version of libc due to an... interesting interpretation of the GPL. These licensing issues were resolved when microsoft introduced the UCRT, and I believe you can now opt-into using the UCRT with MinGW, but the rust -gnu toolchain does not enable that option (see this tier 3 target - https://doc.rust-lang.org/rustc/platform-support/pc-windows-gnullvm.html and associated github issue - rust-lang/rust#72241 (comment) )

There are also many ABI differences between the -gnu toolchain and the -msvc toolchain which can be a hazard if you are linking to any pre-compiled libraries. (eg. binaries that link to MSVCRT, the legacy C runtime used by -gnu are incompatible with modern binaries using the UCRT, used by -msvc and that tier 3 target I mentioned)

@garretwilson
Copy link
Author

garretwilson commented May 19, 2023

I'm still reading this and getting ready to experiment, but a quick note. I see this command in the indicated Window installation section in the rustup documentation:

rustup set default-host i686-pc-windows-msvc

Update: My bad; I reread that, and I now see it's referring to the 32-bit host.

I want to see what the current default host is before I start mucking with things. Being a complete Rust newbie, I try the most logical thing (i.e. the thing that would be most consistent as the complement to the rustup set default-host … command):

rustup get default-host

I expect it to say x86_64-pc-windows-msvc. Instead it says:

error: The subcommand 'default-host' wasn't recognized

Harrumph.

However I did find rustup show, which gives (among other things):

Default host: x86_64-pc-windows-msvc

The next question naturally is "What is the difference between i686-pc-windows-msvc and x86_64-pc-windows-msvc, and where are they all listed in the documentation?" Scratch that; I now see one is the 32-bit version.

To further complicate matters, rust show also shows stable-x86_64-pc-windows-msvc (default). So is stable-x86_64-pc-windows-msvc (default) the same as x86_64-pc-windows-msvc? (They must be, because they are both listed as the default, I guess.) I'm guessing this one comes from the "stable" branch/channel, so there's probably some convention for the default host triple to prefix the identifier with stable-. Totally guessing here. I see this information is in The rustup book. I have read a few other Rust books before even starting to install Rust itself, but it looks like I need to circle back and read the concepts in The rustup book, which apparently the other books glossed over.

@garretwilson
Copy link
Author

garretwilson commented May 19, 2023

Ah, rustup toolchain list will also show the default toolchains. After running rustup toolchain install stable-gnu, the list gives me:

stable-x86_64-pc-windows-gnu
stable-x86_64-pc-windows-msvc (default)

Making progress. So now I think I can do as it says in the docs:

rustup set default-host x86_64-pc-windows-gnu

It gives no response. So I run rustup toolchain list again, and it still shows stable-x86_64-pc-windows-msvc as the default. 🤔

So I think maybe I need to add the stable- prefix, i.e. rustup set default-host stable-x86_64-pc-windows-gnu. It doesn't like that at all. It says:

error: Provided host 'stable-x86_64-pc-windows-gnu' couldn't be converted to partial triple

Current roadblocks:

  • rustup set default-host x86_64-pc-windows-gnu didn't appear to switch the default toolchain.
  • I just discovered that another section in The rustup book says to use rustup default … instead of rustup set default-host … which the other section of the book said to use to set the default toolchain.

I don't want to mess up something, so I'll wait for clarification before trying more commands.

@Diggsey
Copy link
Contributor

Diggsey commented May 19, 2023

This could definitely be explained better in the book - and that page you linked to shouldn't be recommending rustup set default-host without explaining what it actually does - rustup default <blah> is what you want 99% of the time.

Let me start with the concept of a "triple" - this is something like x86_64-pc-windows-gnu and it is essentially a name that identifies a particular platform/ABI combination. Whenever you compile a program, you specify this name so the compiler knows how to build the program.

The two main types of "triple" you will encounter with rustup are a "target triple" and a "host triple".

  • Host triple
    This is the triple that the compiler toolchain itself was built for. ie. rustc and all other binaries in that toolchain were compiled for that triple.

  • Target triple
    This is the triple that the toolchain will build programs for. Since Rust is inherently a cross-compiler, the target triple doesn't necessarily match the host triple - you can compile code on linux for windows for example.

All the commands under rustup target are for managing the bits you need to build for a particular target triple.

When you install a toolchain or want to specify which toolchain to use, you need to specify what version (eg. stable) along with the host triple. That's why toolchains have names like stable-x86_64-pc-windows-gnu.

However, people generally don't want to type all that out every time - so rustup allows you to omit parts of the toolchain name, and rustup will try to fill them in. So when you ask for "stable", rustup recognises that it's a version identifier, and fills in the "host triple" with its best guess at what you want. It will even allow you to omit some parts of the triple and will still fill in the rest, which is why eg. rustup default stable-gnu works.

That "guess" for what the host triple should be is the "default host" and rustup set default-host changes that. So it only affects the resolution of short toolchain names to full names. If you always specify a full toolchain name it has no effect.

If the "default host" has never been specified explicitly, the rustup tries to detect what platform it is running on, and picks the appropriate host automatically. So, eg. if you are running on 64-bit windows, then it will probably pick x86_64-pc-windows-msvc.

The implications of all this are:

  • If you just want to compile programs for the "-gnu" target, you don't need to change toolchain at all. You can just install the "-gnu" target via rustup target add x86_64-pc-windows-gnu and then specify that target via cargo build --target x86_64-pc-windows-gnu.
  • If you want to install the rust toolchain which was itself built for the "-gnu" triple, and use that by default, then you can just run rustup default stable-gnu - since that will come with the "-gnu" target by default, you won't need to do the above step as well.
  • If you want to change rustup's configuration so that eg. "rustup default stable" always refers to the "-gnu" toolchain without having to explicitly add the "-gnu" suffix, then you can run rustup set default-host x86_64-pc-windows-gnu.

@rbtcollins
Copy link
Contributor

Can I suggest that this is currently the realm of user education, and that https://users.rust-lang.org/ would be a better forum for that?

Actionable bugs like 'the docs are wrong or confusing in location XXX' that spin out of such a conversation are certainly welcome, as are new features relevant to rustup such as 'please support this new triple that has the underlying platform behaviour I want'.

Rustup as a project doesn't provide any capabilities that are not already implemented in cargo/rustc/system linkers and so on. Rustup's job is to:

  • download, install and update Rustup itself
  • download, install, and update Rust and Rust component distributions
  • provide a sensible on-ramp to development using those Rust distributions

The last point is the key one here, because there is a lot of complexity if we get into installing links, system headers for C and C++ libraries and so on. For the most part Rustup doesn't do - and I see no compelling reason for it to start doing - any of that.

The one exception, for a few reasons, is the MSVC build tools on Windows. I think we'd be happy to do the same for XCode on Mac, except it is even more restricted than the MSVC build tools on Windows.

Mac and Windows combined form 86% of the desktop market; folk using Linux/*BSD/other-things are part of the long tail - where increased competence is required, and where widespread knowledge about the internals is less readily available, but also where - in large part due to the open source culture and driving pressure for efficiency from the volunteer development model - things like linkers and so on are readily available.

We get support requests here that show where the experience of getting going on a happy path - something that can build Rust binaries and works for the most part without substantial effort - is hard. Those requests have driven the installation UI we have today.

tl;dr: Two points: If there are changes that can be made to rustup to support what you need to do, we're happy to make them, but I'm not aware of any right now. But the default behaviour for Rustup will be centered around developer experience, not software freedom - when a free software stack can be substituted in on Windows without driving up the number of people that cannot build software successfully, and don't understand why, then we should have a discussion about defaults and what the system guides people towards.

@rbtcollins
Copy link
Contributor

I'm going to close this at this point, as there are no current actions. If something comes up that is relevant here feel free to reopen.

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

No branches or pull requests

4 participants