rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

option to specify path to cargo executable

Open DetachHead opened this issue 3 months ago • 10 comments

in my project, cargo is installed to a python virtual environment using https://github.com/konstin/rustup-pypi. this works with the language server thanks to the rust-analyzer.server.path setting:

// .vscode/settings.json
{
    "rust-analyzer.server.path": ".venv/bin/rust-analyzer"
}

however there doesn't seem to be a setting to specify the path to the cargo executable, so i can't use the run/debug buttons in my main.rs:

2025-11-24 23:17:32.911 [error] Cargo invocation has failed: Error: could not launch cargo: Error: spawn cargo ENOENT

DetachHead avatar Nov 24 '25 13:11 DetachHead

You can set the CARGO environment variable to the path you want (for example, via rust-analyzer.server.extraEnv).

ChayimFriedman2 avatar Nov 24 '25 13:11 ChayimFriedman2

hmm that doesn't seem to work:

{
    "rust-analyzer.server.extraEnv": {
        // also tried ".venv/bin/cargo" as well as the full non-relative path
        "CARGO": "${workspaceFolder}/.venv/bin/cargo"
    }
}

i also tried setting the CARGO environment variable in my shell before launching vscode and that didn't work either

DetachHead avatar Nov 26 '25 13:11 DetachHead

Yeah, that variable only works when at least one cargo exists in PATH, because that redirection is done by cargo itself

ShoyuVanilla avatar Nov 26 '25 13:11 ShoyuVanilla

You can probably put some shell script in path that will launch CARGO.

ChayimFriedman2 avatar Nov 28 '25 03:11 ChayimFriedman2

ideally i want to keep all the config isolated to the vscode project without having to change any environment variables globally. i did try modifying the path from within the project settings in vscode like this, but that didn't seem to work either:

{
    "terminal.integrated.env.linux": {
        "PATH": "${workspaceFolder}/.venv/bin:${env:PATH}"
    },
}

DetachHead avatar Nov 28 '25 14:11 DetachHead

Yeah, we don't support placeholders like ${workspaceFolder} or even ${env:PATH} in settings. I think adding an option for cargo executable path sounds plausible, but at the same time, it feels very niche. Normally, most the users will have cargo on their project's cwd or don't {have, need} it at all for some special projects like rust compiler, so I'm not sure how many of them are on the third party, "have cargo and need it but it is not reachable without the exact path". How do you execute cargo for other things like cargo build?

ShoyuVanilla avatar Dec 09 '25 03:12 ShoyuVanilla

I think adding an option for cargo executable path sounds plausible, but at the same time, it feels very niche.

i understand. not many people set up their projects the way i do, but if it helps i'll give some more context to hopefully justify the reasons why i'm doing it this way (in no particular order).

reason 1 - i hate installing things globally

in my experience contributing to open source projects maintained by others, i've always hated how the contributing instructions always involve installing random tools and dependencies globally that i'll never use again. these tools often fail to install for various reasons and when that happens it's often difficult to correctly revert whatever changes i made to my system when i'm done with it.

i hate that the recommended way to install many tools nowadays is by curling and executing an install script that does god knows what irreversible changes to my computer. tools with install scripts often seem to feel so entitled to live permanently on my PC that they don't even provide an easy way to uninstall them. instead i have to find and delete their files manually. i believe rustup does have an uninstall command so it's not as bad, but i'm still strongly against the concept of install scripts in general for many other reasons.

the way i see it, if a tool can't be installed via a package manager (or an installer when i'm forced to use windows) -- really just anything with a standardized way to list/uninstall them -- then it doesn't deserve to be installed on my computer.

reason 2 - i want to make my projects as easy as possible for contributors to set up locally

i maintain two projects targeted at python users but written in languages other than python: tach (rust) and basedpyright (typescript). when i became a maintainer myself i decided that i don't want any potential new contributor to feel the frustrations i felt trying to work on other peoples' projects.

i know many python users don't know any typescript nor do they have nodejs installed. and i think even less of them have any rust experience nor any of the rust tooling installed. i know learning a new language can be very daunting, and the biggest barrier in my experience has been figuring out how to install and configure the various new tools that never seem to work properly by default. my goal is to make this process as seamless as possible, and i feel like i've been successful in this goal for the most part:

  • my projects use uv as their package manager, which many python users are familiar with. but those that don't use uv don't need to worry because it gets installed locally to a venv within the project thanks to pyprojectx (which doesn't need to be installed globally either!)
  • my projects define all tooling for non-python languages as dev dependencies installed from third party wheels on pypi
  • my projects all have vscode config files committed that ensures all of those tools are made available in the PATH and integrated with the IDE automatically. for most of them, this simply means setting "python.terminal.activateEnvInCurrentTerminal" to true in .vscode/settings.json (to answer your question: this works for cargo thanks to rustup-pypi!), but some tools require more hacky solutions

reason 3 - pinning versions

most projects use lockfiles to pin their dependencies, but the tool they use to install those dependencies is rarely pinned itself. this can lead to inconsistent behavior between developers' machines and in the CI if they have different versions of the package manager or some other globally installed tool.

i'm mainly speaking from my experience working on python and typescript projects. i'm still new to rust so correct me if i'm wrong but i believe this isn't really an issue in rust thanks to toolchains? so maybe this point isn't as strong as the others.

"why not use docker?"

in theory devcontainers should solve pretty much all of these problems. but for some reason i've never encountered, nor have i been able to successfully create, a devcontainer that actually works reliably on everybody's machine. i also think docker is overkill for something like this, and the solutions i've implemented in my own projects are much simpler and more reliable.


sorry for the huge wall of text lol, i hope this helps clears things up though. i know what it's like to receive feature requests for some seemingly pointless features with no explanation so i apologize for not providing this context to begin with

DetachHead avatar Dec 09 '25 13:12 DetachHead

Yeah, I understand your points. For the very similar reasons, I use nix and make a flake file per project rather than global installs 😄 Then how do you invoke your cargo commands like cargo build? Do you manually enter the relative path to the cargo executable or does pyprojectx resolves it inside your project directory? If the later is the case, I guess it might work with rust-analyzer as well

ShoyuVanilla avatar Dec 09 '25 13:12 ShoyuVanilla

since cargo is part of the rustup-pypi package installed by uv, that means it's in my PATH whenever the python virtualenv is active. so if i configure vscode to always activate the venv in its terminal, cargo is always availlable:

// .vscode/setttings.json
{
    "python.terminal.activateEnvInCurrentTerminal": true
}
(tach) me@pc:/projects/tach$ type -p cargo
/projects/tach/.venv/bin/cargo
(tach) me@pc:/projects/tach$ cargo build
   Compiling pyo3-build-config v0.27.1
   Compiling pyo3-ffi v0.27.1
   Compiling pyo3-macros-backend v0.27.1
   Compiling pyo3 v0.27.1
   Compiling pyo3-macros v0.27.1
   ...

DetachHead avatar Dec 09 '25 13:12 DetachHead

Oh, I see. So, it might be better to investigate and fix virtualenv is not working with rust-analyzer and its child processes. I may try that but that will take some days since I have some other works to do.

ShoyuVanilla avatar Dec 09 '25 14:12 ShoyuVanilla