cargo icon indicating copy to clipboard operation
cargo copied to clipboard

Cargo in WSL prefers windows user config

Open weltensturm opened this issue 2 years ago • 6 comments

Problem

Cargo in WSL uses the windows host cargo config in %UserProfile%/.cargo/config.toml, and it looks like values there are preferred over the WSL ~/.cargo/config.toml. When there is either rustc-wrapper or target-dir configured, cargo in WSL fails because it does not have access to those paths.

edit: The project I am trying to compile is in a folder symlinked to /c/Users/<user>/projects. It looks like cargo unwraps the symlink, then it's pretty clear why it finds the windows config first. But I am not sure this behavior is preferrable. /edit

I have a ~/.cargo/config.toml in WSL with the following content:

[build]
rustc-wrapper = "/home/<user>/.cargo/bin/sccache"
target-dir = "/home/<user>/.cargo/targets"

But cargo prefers the host values. Error when rustc-wrapper is set on windows:

error: failed to run `rustc` to learn about target-specific information

Caused by:
  could not execute process `/mnt/c/Users/<user>/C:/Users/<user>/.cargo/bin/sccache.exe rustc - --crate-name ___ --print=file-names --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg` (never executed)

Caused by:
  No such file or directory (os error 2)

Error when target-dir is set on windows:

error: failed to join paths from `$LD_LIBRARY_PATH` together

Check if any of path segments listed below contain an unterminated quote character or path separator:
    "/mnt/c/Users/<user>/C:/Users/<user>/.cargo/targets/debug/deps"
    "/home/<user>/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib"
    "/home/<user>/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib"

Caused by:
  path segment contains separator `:`

which { rustup cargo rustc } shows WSL binaries, so there is no issue with accidentally invoking host binaries.

When I delete the contents of the windows cargo.toml, the WSL config is applied correctly.

Steps

  1. Set up WSL
  2. Install cargo/rust in windows host and in WSL
  3. Set up a cargo project in %UserProfile%/projects/<name>
  4. Create a config.toml in %UserProfile%/.cargo with either rustc-wrapper or target-dir
  5. In WSL: Create a symlink in ~/ to /mnt/c/Users/<user>/projects
  6. In WSL: cargo run in ~/projects/<name>

Possible Solution(s)

Change cargo so it doesn't "unwrap" symlinks when looking for configs. If pwd prints ~/projects/, cargo should not behave like it's in /mnt/c/Users/<user>/projects.

Notes

wsl -v -l

WSL version: 1.0.3.0
Kernel version: 5.15.79.1
WSLg version: 1.0.47
MSRDC version: 1.2.3575
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22621.1105

Version

cargo 1.67.0 (8ecd4f20a 2023-01-10)
release: 1.67.0
commit-hash: 8ecd4f20a9efb626975ac18a016d480dc7183d9b
commit-date: 2023-01-10
host: x86_64-unknown-linux-gnu
libgit2: 1.5.0 (sys:0.16.0 vendored)
libcurl: 7.86.0-DEV (sys:0.4.59+curl-7.86.0 vendored ssl:OpenSSL/1.1.1q)
os: Ubuntu 22.04 (jammy) [64-bit]

weltensturm avatar Feb 03 '23 20:02 weltensturm

My guess is that home crate only respects USERPROFILE even on WSL.

https://github.com/rust-lang/cargo/blob/82c3bb79e3a19a5164e33819ef81bfc2c984bc56/crates/home/src/windows.rs#L9-L30

I don't really have my Windows close by though. I believe @epage is more helpful. @epage, do you have any experience in WSL with home directory setup?

weihanglo avatar Feb 07 '23 17:02 weihanglo

It works when copying the project to a "native" WSL directory, it's only when the project is in some way under a symlink to /mnt/c/Users/<user>/ or any child directory where the problem occurs. I assume it happens because rust unwraps the symlink path and uses the real/physical path to search all parent directories for configs. USERPROFILE is empty in WSL. I only checked that case after I created this issue, so apart from the edit block I left the description largely as it is, to show how confusing it is from the user side. But it's not as bad as it sounds, should I add a "when project is in a symlink to the windows user directory` to the title?

weltensturm avatar Feb 07 '23 18:02 weltensturm

I assume it happens because rust unwraps the symlink path and uses the real/physical path to search all parent directories for configs

Yes, this is correct (it's unrelated to WSL). std::env::current_dir() calls getcwd on Linux, which resolves symlinks. Cargo never sees the version of the path that contains the symlinks.

arlosi avatar Feb 08 '23 17:02 arlosi

My guess is that home crate only respects USERPROFILE even on WSL.

https://github.com/rust-lang/cargo/blob/82c3bb79e3a19a5164e33819ef81bfc2c984bc56/crates/home/src/windows.rs#L9-L30

I don't really have my Windows close by though. I believe @epage is more helpful. @epage, do you have any experience in WSL with home directory setup?

Can confirm, this resolved for me after creating a USERPROFILE environment variable in WSL that pointed to the right location.

n-tropy247 avatar Aug 01 '23 21:08 n-tropy247

this issue makes me struggled for a very very long time.

Actually, all I wanted is just very simple:
As long as I enter WSL2 environment to build my rust project, cargo should always use WSL2's cargo configuration file, which is located at WSL2:/home/wsl2user/.cargo/config.toml

but currently in WSL2:

  • If my current rust project folder is under non-mnt (not /mnt/). directories, e.g. /home/wsl2user/rustdev/., cargo will always or only use WSL2's cargo configuration file, which is WSL2: /home/wsl2user/.cargo/config.toml

  • If my current rust project folder is under mnt directories /mnt/c/Users/winuser/..., cargo will combine to use host Windows configuration file, which is located at Windows: C:\Users\winuser\.cargo\config.toml, as well as WSL2's configuration file mentioned above.

bingzhux avatar Dec 18 '23 01:12 bingzhux

Forgot to say, home was migrated into rust-lang/cargo repo https://github.com/rust-lang/cargo/pull/11359 last year, so cargo maintainers here do have permissions to update it.

weihanglo avatar Dec 25 '23 05:12 weihanglo

What's the status of this? I tried to add .cargo/config.toml with an [env], but it won't detect those variables either. I'm detecting them via env::var_os. I'm on WSL2.

Update: If I use env::var then this works. Somehow there is a difference between env::var and env::var_os on WSL.

CGMossa avatar Feb 12 '24 14:02 CGMossa

@CGMossa what your encountering sounds like a different problem. If you can create a minimal reproduceable example, please create a new issue with details.

arlosi avatar Feb 12 '24 15:02 arlosi