6.3 KiB
Cargo B(inary)Install
A helper for distribution and installation of CI built rust binaries in a pseudo-distributed and maybe-one-day secure manner. This is part experiment, part solving a personal problem, and part hope that we can solve / never re-visit this. I hope you find it helpful and, good luck!
To get started using cargo-binstall
, first install the binary (either via cargo install cargo-binstall
or by downloading a pre-compiled release. Once you have installed this you can of course cargo binstall cargo-binstall
to install further versions...
Supported packages can be installed using cargo binstall NAME
where NAME
is the crate.io package name.
Package versions and targets may be specified using the --version
and --target
arguments respectively, and install directory with --install-dir
(this defaults to $HOME/.cargo/bin
, with fall-backs to $HOME/.bin
if unavailable). For additional options please see cargo binstall --help
.
To support binstall
maintainers must add configuration values to Cargo.toml
to allow the tool to locate the appropriate CI-produced binary package for a given version and target. See Supporting Binary Installation for instructions on how to support binstall
in your projects.
Status
Features
- Manifest discovery
- Fetch crate / manifest via crates.io
- Fetch crate / manifest via git
- Use local crate / manifest (
--manifest-path
)
- Package formats
- Tgz
- Tar
- Bin
- Extraction / Transformation
- Extract from subdirectory in archive (ie. support archives with platform or target subdirectories)
- Extract specific files from archive (ie. support single archive with multiple platform binaries)
- Security
- Package signing
- Package verification
Supporting Binary Installation
binstall
works with existing CI-built binary outputs, with configuration via [package.metadata.binstall]
keys in the relevant crate manifest.
When configuring binstall
you can test against a local manifest with --manifest-path=PATH
argument to use the crate and manifest at the provided PATH
, skipping crate discovery and download.
To get started, add a [package.metadata.binstall]
section to your `Cargo.toml. As an example, the default configuration would be:
[package.metadata.binstall]
pkg-url = "{ repo }/releases/download/v{ version }/{ name }-{ target }-v{ version }.{ format }"
bin-dir = "{ name }-{ target }-v{ version }/{ bin }{ format }"
pkg-fmt = "tgz"
With the following configuration keys:
pkg-url
specifies the package download URL for a given target/version, templatedbin-path
specifies the binary path within the package, templated (with an.exe
suffix on windows)pkg-fmt
overrides the package format for download/extraction (defaults to:tgz
)
pkg-url
and bin-path
are templated to support different names for different versions / architectures / etc.
Template variables use the format { VAR }
where VAR
is the name of the variable, with the following variables available:
name
is the name of the crate / packageversion
is the crate version (per--version
and the crate manifest)repo
is the repository linked inCargo.toml
bin
is the name of a specific binary, inferred from the crate configurationtarget
is the rust target name (defaults to your architecture, but can be overridden using the--target
command line option if required().
Defaults
By default binstall
is setup to work with github releases, and expects to find:
- an archive named
{ name }-{ target }-v{ version }.tgz
- so that this does not overwrite different targets or versions when manually downloaded
- located at
{ repo }/releases/download/v{ version }/
- compatible with github tags / releases
- containing a folder named
{ name }-{ target }-v{ version }
- so that prior binary files are not overwritten when manually executing
tar -xvf ...
- so that prior binary files are not overwritten when manually executing
- containing binary files in the form
{ bin }{ format }
(wherebin
is the cargo binary name andformat
is.exe
on windows and empty on other platforms)
If your package already uses this approach, you shouldn't need to set anything.
Examples
For example, the default configuration (as shown above) for a crate called radio-sx128x
(version: v0.14.1-alpha.5
on x86_64 linux) would be interpolated to:
- A download URL of
https://github.com/rust-iot/rust-radio-sx128x/releases/download/v0.14.1-alpha.5/rust-radio-sx128x-x86_64-unknown-linux-gnu-v0.14.1-alpha.5.tgz
- Containing a single binary file
rust-radio-sx128x-x86_64-unknown-linux-gnu-v0.14.1-alpha.5/rust-radio-x86_64-unknown-linux-gnu
- Installed to
$HOME/.cargo/bin/rust-radio-sx128x-v0.14.1-alpha.5
- With a symlink from
$HOME/.cargo/bin/rust-radio-sx128x
If the package name does not match the crate name
As is common with libraries / utilities (and the radio-sx128x
example), this can be overridden by specifying the pkg-url
:
[package.metadata.binstall]
pkg-url = "{ repo }/releases/download/v{ version }/sx128x-util-{ target }-v{ version }.{ format }"
Which provides a download URL of: https://github.com/rust-iot/rust-radio-sx128x/releases/download/v0.14.1-alpha.5/sx128x-util-x86_64-unknown-linux-gnu-v0.14.1-alpha.5.tgz
If the package structure differs from the default
Were the package to contain binaries in the form name-target[.exe]
, this could be overridden using the bin-dir
key:
[package.metadata.binstall]
bin-dir = "{ bin }-{ target }{ format }"
Which provides a binary path of: sx128x-util-x86_64-unknown-linux-gnu[.exe]
. It is worth noting that binary names are inferred from the crate, so long as cargo builds them this should just work.
If you have ideas / contributions or anything is not working the way you expect (in which case, please include an output with --log-level debug
) and feel free to open an issue or PR.