Install multiple versions cargo crate binaries

TLDR; dependency hell -- binary edition

Challege

Suppose, hypotetically, a script needs access to two binaries
Same cargo crate, just different versions

cargo install big_snek --version 2.7.99
cargo install big_snek --version 3.9.99

The user doesn't need access to either so we don't care about them not being on the PATH
(Also, if your answer is "call them big_snek2, big_snek3" then for you, suppose my script needs 1000 versions of the same cargo crate)

Almost-Solution

I know multiple vesions can be installed simultaneously

~/.cargo 

➜ ls -l ./registry/src/*

drwxr-xr-x  15 480 Apr 14 15:33 unicode-normalization-0.1.12/
drwxr-xr-x  15 480 Apr 14 15:11 unicode-normalization-0.1.13/
drwxr-xr-x  16 512 Mar 14 10:32 unicode-normalization-0.1.17/
drwxr-xr-x  14 448 Apr  3 20:01 unicode-segmentation-1.6.0/
drwxr-xr-x  15 480 Mar 31 20:08 unicode-segmentation-1.7.1/
drwxr-xr-x  14 448 Apr 14 15:33 big-snek-2.7.99/
drwxr-xr-x  14 448 Jan 23 16:13 big-snek-3.9.99/

Which is awesome, this is exactly what I was hoping for.
...except... none of them include their binaries. It's only source code

~/.cargo

➜ tree ./registry/src/github.com-1ecc6299db9ec823/md5sum-0.1.0/

./registry/src/github.com-1ecc6299db9ec823/md5sum-0.1.0/
├── Cargo.toml
├── Cargo.toml.orig
├── README.md
└── src
    └── main.rs

_

Workaround

I thought maybe there would be ./registry/bin/ but sadly no.

If needed, I can create a janky solution.

  • move the current binary to a temp location
  • cargo force install big_snek --version 2
  • mkdir ./registry/__bin/* # mirrors structure of the ./registry/src
  • move the bin of the big_snek version to the mirror location
  • (repeat)

But I figured there might be a better solution, and I'd like to discuss what should be the offical answer to handling the binary dependency hell.

You can use the --root option to install the different versions into different directories.

cargo install big_snek --version 2.7.99 --root /foo/bar/snek2/
cargo install big_snek --version 3.9.99 --root /foo/bar/snek3/

The two versions will end up at /foo/bar/snek2/bin/big_snek and /foo/bar/snek3/bin/big_snek.

4 Likes

Great! And in terms of establishing a "best practice" I'm going to propose installing them into
~/.cargo/registry/bin/[package_name]-[full version]

Ex:

cargo install big_snek --version 2.7.99 --root ~/.cargo/registry/bin/big_snek-2.7.99

Maybe later I will make a cargo crate like cargo-show to do this automatically