rustup icon indicating copy to clipboard operation
rustup copied to clipboard

'rustup' detects inappropriate default host and incorrectly handles full paths set in *_HOME* environment variables

Open Petr-Lazecky opened this issue 5 months ago • 6 comments

Verification

  • [x] I searched for recent similar issues at https://github.com/rust-lang/rustup/issues?q=is%3Aissue+is%3Aopen%2Cclosed and found no duplicates.
  • [x] I am on the latest version of Rustup according to https://github.com/rust-lang/rustup/tags and am still able to reproduce my issue.

Problem

When 'rustup' is run within Cygwin environment on the Windows, it detects x86_64-pc-windows-msvc as default host. One would expect x86_64-pc-windows-gnu on Cygwin where gcc is typical primary toolchain. This can be handled by passing --default-host to install script so it is really minor problem but IMHO a little bit of inconvenience, depending on how one looks into it.

Also...

When one tries to pass CARGO_HOME and RUSTUP_HOME variables to control where rust should be installed within Cygwin environment on Windows and user sets absolute paths for these variables, installation script "mangles" these paths by prefixing them with "C:/" making them invalid (setting up rust somewhere "outside" of the Cygwin environment, typically in the C:\ root which is not what user really wants.

Steps

Issue 1:

  1. Environment: Windows 10, Cygwin environment

  2. Launch Cygwin environment

  3. Execute standard Linux command to install rustup:

    curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh -s

Observed:

`default host triple: x86_64-pc-windows-msvc`

Expected:

`default host triple: x86_64-pc-windows-gnu`

Issue 2:

  1. Environment: Windows 10, Cygwin environment
  2. Launch Cygwin environment
  3. Execute command by passing CARGO_HOME and RUSTUP_HOME environment variables referencing full paths within Cygwin environment where rust should be installed:

CARGO_HOME="/home/user1/Rxes/rust/cargo" RUSTUP_HOME="/home/user1/Rxes/rust/env" bash -c "curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh -s -- --default-host x86_64-pc-windows-gnu"

Observed:

Instalation message contains this:

The Cargo home directory is located at:
  C:/home/user1/Rxes/rust/cargo
...
The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:
  C:/home/user1/Rxes/rust/cargo/bin

Expected:

Absolute Cygwin paths should not be "mangled" with "C:/" prefix but used as they are:

The Cargo home directory is located at:
  /home/user1/Rxes/rust/cargo
...
The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:
  /home/user1/Rxes/rust/cargo/bin

Possible Solution(s)

I think that in order to fix it, rustup installer would have to recognize/detect Cygwin/MSYS2/MinGW enviroments on Windows and handle paths and default host according to these runtimes. I think that GNU host for these environments should be default as this is primary reason why users typically set up these environments on their Windows systems.

uname -s command returns 'CYGWIN_NT-xxxxxxxx' so the question is how Rust can extract it. If parent process of rustup-init is bash.exe, then it may be assumed, that this is running through emulated terminal on Windows. Another option would be to allow user to explicitly pass full paths on the installation script and simply trust user that what he is passing is what he really wants and simply do not change it in any way.

Notes

BTW, I was able to workaround these issues by setting these options in .bash_profile file in my Cygwin home directory:

PATH="/sbin:/usr/sbin:.:Rxes\\rust\\cargo\\bin:${PATH}"

# I have another rustup installation on my Windows system
# which I would like to have untouched and separate from one on Cygwin. 
# Removing it from it from the $PATH will hide it from rustup-init and
# makes my installation completely independent from the other one on Windows
export PATH=`echo $PATH | sed "s/:\/cygdrive\/e\/Environments\/Rust\/cargo\/bin//"`

# This weird setup of using double \\ is used intentionally in order 
# to provide consistent look and feel of absolute path for rustup. 
# rustup is also not able to handle absolute unix-like paths, it prepends
# them with Windows drive letter like "C:\" making them invalid. So
# relative paths here are intentional as well.
export RUSTUP_HOME="Rxes\\rust\\env"
export CARGO_HOME="Rxes\\rust\\cargo"

Basically, using relative paths would make it work.

Rustup version

rustup 1.28.2 (e4f3ad6f8 2025-04-28)

Installed toolchains

$ rustup show
Default host: x86_64-pc-windows-msvc
rustup home:  C:/home/user1/Rxes/rust/env

installed toolchains
--------------------

active toolchain
----------------
no active toolchain

(Reason for this output is again the wrong mangling of the full path, `rustup` is trying to look for toolchain in `C:/home/user1/Rxes/rust/env` but tool chain was installed within Cygwin on `/home/user1/Rxes/rust/env` which is completely different directory)

By changing $PATH on the Cygwin to use relative path instead of absolute path to cargo\bin, the output is as expected:

$ rustup show
Default host: x86_64-pc-windows-gnu
rustup home:  C:\Portable\cygwin\3.6.1\home\user1\Rxes\rust\env

installed toolchains
--------------------
stable-x86_64-pc-windows-gnu (active, default)

active toolchain
----------------
name: stable-x86_64-pc-windows-gnu
active because: it's the default toolchain
installed targets:
  x86_64-pc-windows-gnu

OS version

Windows 10

Petr-Lazecky avatar Jul 21 '25 21:07 Petr-Lazecky

@rustbot claim

cachebag avatar Sep 16 '25 17:09 cachebag

@rami3l or @djc Both of these look fixable with localized changes, but I wanted to check first: is Cygwin considered a supported environment, or more of a best-effort case? I wouldn't want to open a PR at all before knowing if I should focus on a minimal patch or something broader that also accounts for MSYS2/Git Bash (or just not even attempt this issue if you guys don't think it's worth addressing).

cachebag avatar Sep 16 '25 17:09 cachebag

@cachebag I would like to kindly ask @ChrisDenton for the global stance on the Rust toolchain in general (if there is any) but I personally don't have the impression of cygwin being supported to this level...

Update: If there needs to be a solution then I assume it would cover the most common cases where x86_64-pc-windows-gnu is desired, not just within cygwin.

rami3l avatar Sep 17 '25 02:09 rami3l

For rustup itself, we don't "officially" support it but we do make a best effort to support common environments so I think fixing issue 1 is possible. We could possibly just make the .sh script default to -gnu on Windows, seeing as most people will be using the exe installer and you have to go out of your way to use the shell script (e.g. the website suggests it only for use in WSL).

On the rustc side, we do now have a cygwin target but it's not yet supported as a host and it's "tier 3" which means it's still a work in progress (and therefore not distributed by rustup). Without that, using cygwin paths in CARGO_HOME and RUSTUP_HOME environment variables is problematic because they are global and used by tools such as cargo (obviously) as well as others. It's important to note that they can be used both natively and within e.g. git bash or cygwin so detecting whether it's currently within cygwin is not sufficient. I'm not sure that we can square that circle without having a cygwin host toolchain that understands such paths.

ChrisDenton avatar Sep 22 '25 02:09 ChrisDenton

For rustup itself, we don't "officially" support it but we do make a best effort to support common environments so I think fixing issue 1 is possible. We could possibly just make the .sh script default to -gnu on Windows, seeing as most people will be using the exe installer and you have to go out of your way to use the shell script (e.g. the website suggests it only for use in WSL).

@ChrisDenton Thanks for your insight! That is indeed a good idea, but currently blocked on https://github.com/rust-lang/rustup/issues/1851. Do you think it'd be reasonable to address the latter first?

rami3l avatar Sep 22 '25 02:09 rami3l

Hm, I would have to look into this more before answering that definitively but I think we can address this by the shell script passing --default-host to rustup (assuming it's not set by the user) and not need any bigger changes.

ChrisDenton avatar Sep 22 '25 02:09 ChrisDenton