One common way for linux systems to support multiple implementations or versions, e.g., allowing 'vi' to point to either 'vim' or 'nvi', is the 'alternatives' framework. It is managed by 'update-alternatives'.
This is usually handled by distro packagers, and of course it's possible that the rust ecosystem already has its own solution but it wasn't sufficiently triggered when building a downloaded project, but I thought this would be a good place to start and let you push it to the packagers.
The script I used to get my 'ninja' build working follows. I know that the Debian ecosystem has an integrated solution with dh_installalternatives
. This is better for .deb files since it can work with /etc/apt/preferences.d
etc, but this script is a good starting point for the rest of us.
With this 'rustc' and 'cargo' act as expected. If you want to use a different version by default it's easy to call sudo update-alternatives --config rust
(or cargo
) and then select one of the options listed.
!/bin/sh
VERS=1.81
# apt-get install rustc-$VERS clang-18 lld-18 llvm-18 wasi-libc cargo-$VERS
/usr/bin/update-alternatives --force \
--install /usr/bin/rust rust /usr/lib/rust-$VERS 100 \
--slave /usr/bin/rustc rustc /usr/bin/rustc-$VERS \
--slave /usr/bin/rustdoc rustdoc /usr/bin/rustdoc-$VERS \
--slave /usr/bin/rust-clang rust-clang /usr/bin/rust-$VERS-clang \
--slave /usr/bin/rust-lld rust-lld /usr/bin/rust-$VERS-lld \
--slave /usr/bin/rust-llvm-dwp rust-llvm-dwp /usr/bin/rust-$VERS-llvm-dwp \
--slave /usr/share/man/man1/rustc.1.gz rustc.1.gz /usr/share/man/man1/rustc-$VERS.1.gz \
--slave /usr/share/man/man1/rustdoc.1.gz rustdoc.1.gz /usr/share/man/man1/rustdoc-$VERS.1.gz
/usr/bin/update-alternatives --force \
--install /usr/bin/cargo cargo /usr/bin/cargo-$VERS 100 \
--slave /usr/share/man/man1/cargo-add.1.gz cargo-add.1.gz /usr/share/man/man1/cargo-$VERS-add.1.gz \
--slave /usr/share/man/man1/cargo-bench.1.gz cargo-bench.1.gz /usr/share/man/man1/cargo-$VERS-bench.1.gz \
--slave /usr/share/man/man1/cargo-build.1.gz cargo-build.1.gz /usr/share/man/man1/cargo-$VERS-build.1.gz \
--slave /usr/share/man/man1/cargo-check.1.gz cargo-check.1.gz /usr/share/man/man1/cargo-$VERS-check.1.gz \
--slave /usr/share/man/man1/cargo-clean.1.gz cargo-clean.1.gz /usr/share/man/man1/cargo-$VERS-clean.1.gz \
--slave /usr/share/man/man1/cargo-doc.1.gz cargo-doc.1.gz /usr/share/man/man1/cargo-$VERS-doc.1.gz \
--slave /usr/share/man/man1/cargo-fetch.1.gz cargo-fetch.1.gz /usr/share/man/man1/cargo-$VERS-fetch.1.gz \
--slave /usr/share/man/man1/cargo-fix.1.gz cargo-fix.1.gz /usr/share/man/man1/cargo-$VERS-fix.1.gz \
--slave /usr/share/man/man1/cargo-generate-lockfile.1.gz cargo-generate-lockfile.1.gz /usr/share/man/man1/cargo-$VERS-generate-lockfile.1.gz \
--slave /usr/share/man/man1/cargo-help.1.gz cargo-help.1.gz /usr/share/man/man1/cargo-$VERS-help.1.gz \
--slave /usr/share/man/man1/cargo-init.1.gz cargo-init.1.gz /usr/share/man/man1/cargo-$VERS-init.1.gz \
--slave /usr/share/man/man1/cargo-install.1.gz cargo-install.1.gz /usr/share/man/man1/cargo-$VERS-install.1.gz \
--slave /usr/share/man/man1/cargo-locate-project.1.gz cargo-locate-project.1.gz /usr/share/man/man1/cargo-$VERS-locate-project.1.gz \
--slave /usr/share/man/man1/cargo-login.1.gz cargo-login.1.gz /usr/share/man/man1/cargo-$VERS-login.1.gz \
--slave /usr/share/man/man1/cargo-logout.1.gz cargo-logout.1.gz /usr/share/man/man1/cargo-$VERS-logout.1.gz \
--slave /usr/share/man/man1/cargo-metadata.1.gz cargo-metadata.1.gz /usr/share/man/man1/cargo-$VERS-metadata.1.gz \
--slave /usr/share/man/man1/cargo-new.1.gz cargo-new.1.gz /usr/share/man/man1/cargo-$VERS-new.1.gz \
--slave /usr/share/man/man1/cargo-owner.1.gz cargo-owner.1.gz /usr/share/man/man1/cargo-$VERS-owner.1.gz \
--slave /usr/share/man/man1/cargo-package.1.gz cargo-package.1.gz /usr/share/man/man1/cargo-$VERS-package.1.gz \
--slave /usr/share/man/man1/cargo-pkgid.1.gz cargo-pkgid.1.gz /usr/share/man/man1/cargo-$VERS-pkgid.1.gz \
--slave /usr/share/man/man1/cargo-publish.1.gz cargo-publish.1.gz /usr/share/man/man1/cargo-$VERS-publish.1.gz \
--slave /usr/share/man/man1/cargo-remove.1.gz cargo-remove.1.gz /usr/share/man/man1/cargo-$VERS-remove.1.gz \
--slave /usr/share/man/man1/cargo-report.1.gz cargo-report.1.gz /usr/share/man/man1/cargo-$VERS-report.1.gz \
--slave /usr/share/man/man1/cargo-run.1.gz cargo-run.1.gz /usr/share/man/man1/cargo-$VERS-run.1.gz \
--slave /usr/share/man/man1/cargo-rustc.1.gz cargo-rustc.1.gz /usr/share/man/man1/cargo-$VERS-rustc.1.gz \
--slave /usr/share/man/man1/cargo-rustdoc.1.gz cargo-rustdoc.1.gz /usr/share/man/man1/cargo-$VERS-rustdoc.1.gz \
--slave /usr/share/man/man1/cargo-search.1.gz cargo-search.1.gz /usr/share/man/man1/cargo-$VERS-search.1.gz \
--slave /usr/share/man/man1/cargo-test.1.gz cargo-test.1.gz /usr/share/man/man1/cargo-$VERS-test.1.gz \
--slave /usr/share/man/man1/cargo-tree.1.gz cargo-tree.1.gz /usr/share/man/man1/cargo-$VERS-tree.1.gz \
--slave /usr/share/man/man1/cargo-uninstall.1.gz cargo-uninstall.1.gz /usr/share/man/man1/cargo-$VERS-uninstall.1.gz \
--slave /usr/share/man/man1/cargo-update.1.gz cargo-update.1.gz /usr/share/man/man1/cargo-$VERS-update.1.gz \
--slave /usr/share/man/man1/cargo-vendor.1.gz cargo-vendor.1.gz /usr/share/man/man1/cargo-$VERS-vendor.1.gz \
--slave /usr/share/man/man1/cargo-verify-project.1.gz cargo-verify-project.1.gz /usr/share/man/man1/cargo-$VERS-verify-project.1.gz \
--slave /usr/share/man/man1/cargo-version.1.gz cargo-version.1.gz /usr/share/man/man1/cargo-$VERS-version.1.gz \
--slave /usr/share/man/man1/cargo-yank.1.gz cargo-yank.1.gz /usr/share/man/man1/cargo-$VERS-yank.1.gz \
--slave /usr/share/man/man1/cargo.1.gz cargo.1.gz /usr/share/man/man1/cargo-$VERS.1.gz \
--slave /usr/share/bash-completion/completions/cargo completions-cargo /usr/share/bash-completion/completions/cargo-$VERS