Multirust-rs integration with tools

Hi!

I have a question regarding multirust-rs. Will it be possible to launch a command of a specific toolchain without multirust run?

For the current multirust running, i.e., ~/.multirust/toolchains/nightly/bin/cargo install rustfmt will not work, because environment variables like CARGO_HOME will not be set.

multirust run is super convenient for command line, but for IntelliJ Rust it will be much easier just to launch cargo binary in a specific path (of course the binary itself can be a wrapper which sets ups necessary environment).

rustup (multirust-rs) does not override $CARGO_HOME so all the bins you install with cargo install will live in ~/.cargo/bin (regardless of which toolchain they are built with). This is also where the rustup command and the rustc and cargo proxy bins live.

This at least avoids the specific issue you mention. Are there other scenarios where rustup needs to behave differently?

Hm, and if I invoke cargo from some toolchain directly, will it use rustc from the same toolchain?

@matklad No it will not.

Aha, and this will make things a little more interesting for IntelliJ Rust. Let me give you some more context about our use case.

To compile code in IntelliJ, the use should configure SDK (software development kit). SDK is basically a path pointing to the location of necessary tools (cargo in the case of Rust), but it also includes sources of the standard library and a supported language version. If the user wants to develop a project with several versions of the language, she can configure several SDKs and switch between them from within IDE.

With the current setup we have the following options.

  1. We can make an SDK pointing to the rustup proxy bins in ~/.cargo/bin, but this will have several disadvantages:
  • the version of a compiler used can silently change, but the IDE needs to know the version to resolve standard library and to provide inspections about deprecated or not yet available features
  • the user will have to use command line to switch toolchains, which may be painful if you are a windows user
  1. We can call rustup run instead of cargo, but not everyone will be using rustup. And I think this will have little annoyances for the end user, like having rustup run in front of every command in the console output.

  2. We can call tools from the toolchains directly, creating the necessary environment ourselves and basically replicating rustup run functionality.

Options 1 and 3 seem the most promising here.

The alternative solution would be to add a level of indirection to rustup :slight_smile: I imagine it like this

# this is a rustup wrapper which uses overrides to determine which toolchain to invoke. 
# This is a public API.
# A user can use `cargo` command to invoke active toolchain
~/.cargo/bin/cargo 

# this is another wrapper which invokes particular toolchain. 
# This is also a public API.
# A user can use `~/.rustup/toolchains/1.10.0/cargo` as a synonym to `rustup run 1.10.0 cargo`
# An IDE can use this path to invoke a particular toolchain
~/.rustup/toolchains/1.10.0/cargo 

# here the real binaries are stored. Completely private API
~/.rustup/impl/toolchains/1.10.0/cargo

Basically, the idea is to be able to run several different toolchains without invoking rustup override.

And yes, the current implementation of SDK in IntelliJ Rust calls a cargo binary from ~/.multirust/toolchains directly, which is completely broken because cargo will pick any rustc which happens to be in PATH :slight_smile:

Do you anticipate this having functionality beyond rustup? If intellij wants to switch SDKs (toolchains in rustup) then rustup provides ways to switch SDKs.

rustup is intended to be used by IDEs for toolchain management (eventually).

If you want to use arbitrary rustup toolchains with minimal rustup integration and without printing rustup run to the console you can use the MULTIRUST_TOOLCHAIN environment variable to set which toolchain you want rustup to use (this will change to RUSTUP_TOOLCHAIN soon). Does that solve this problem?

Thanks! I thinks this environment variable is exactly what I need here.

Why not modify the PATH for the cargo invocation, by adding a path entry the beggining of PATH for the desired rustc entry?

There is a special environment variable RUSTC which you can set for this purpose: https://github.com/rust-lang/cargo/blob/master/src/doc/environment-variables.md#environment-variables-cargo-reads.

Implementing Run Configuration properly is basically on the TODO list at the moment, there are quite a few known issues in that area :slight_smile:

But I believe that there are more environmental variables which has to be set if you want to emulate current multirust (At least CARGO_HOME). I am really looking forward to the new rustup because RUSTUP_TOOLCHAIN will save a lot of headaches (we do a big refactoring in the Cargo are at the moment, btw).

I’m not looking to emulate multirust - not yet at least. In RustDT we only expect Cargo as the SDK tool - but (similar to IntelliJ) you can configure a different Cargo installation per project (as well as other build settings).

I’m not sure yet if this is 100% sufficient for multirust users. I personally haven’t used multirust yet, since I’ve never used any beta or nightly Rust installation, only final releases. I’ll need to check it out at some point though.

@matklad Not sure if this is relevant but you might not be aware that multirust also supports MULTIRUST_TOOLCHAIN.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.