Cargo.{toml,lock} equivalent for cargo install

I'm a huge far of declarative, isolated, per-project environments. I base these on Nix flakes (using the oxalica overlay for Rust projects).

The flake.nix file allows me to declare the precise environment configuration for any given project and the corresponding flake.lock pins specific versions used. This pair of files has an obvious correspondence to Cargo.{toml,lock}: cargo takes care of the Rust dependencies of the project, the Nix flake takes care of all other dependencies (including the Rust toolchain).

However, some Rust-based frameworks provide extra tooling in the form of cargo-installable executables (for example Dioxus' dioxus-cli). If I'm lucky, the executable is available in nixpkgs in a version that is compatible with the one I want to use. If it is not, I have to package it up myself, which is usually not terribly difficult, but still a few orders of magnitude more hassle than the utterly trivial cargo install dioxus-cli (or whatever happens to be relevant for the given framework) that the framework's documentation suggests.

The problem with cargo install whatever is that it violates my requirements of the environment being

  • declaratively-defined
  • isolated

So I'm wondering whether there is a way to transfer the burden of declarative and isolated provision of cargo-installable executables in my environment, from Nix to cargo.

Put another way: cargo add foo adds foo to my Cargo.toml (and indirectly Cargo.lock) thereby ensuring that this version of foo is available in some specific version in this project only. Is there something equivalent for cargo install bar?

You can use cargo install --locked my_crate --version x.y.z if my_crate has a Cargo.lock.

Does this ensure that

  • anyone cloning my project's repo will automatically have the my_crate version x.y.z executable available[1]
  • the my_crate version x.y.z executable is available only in the project in which I issue this command[2]

?

If my interpretation of the docs is correct, the --locked option serves to respect my_crate's lock file while installing my_crate, but doesn't address the declarativity and isolation requirements:

  • the cargo install command still has to be invoked by hand
  • the crate's binary is installed globally for this user on this machine

  1. declarative environment requirement ↩︎

  2. isolated environment requirement ↩︎

If that's your goal then you might be better off setting an alias in the .cargo/config.toml of your project (see Configuration - The Cargo Book) to run a crate in your project that does what you need.

I can imagine all manner of tricks to address the automatic provision (declarativity) requirement, but I suspect that the fundamental and insurmountable problem will be the isolation requirement: does cargo install always install user-wide, or is there some way of restricting the install to a single project?

You can set the install path using --root. You still have to add the install location to your PATH though.

So maybe I can add the cargo install and the path setting to the Nix devShell hook.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.