This is a Cargo helper command which automatically creates binary Debian packages (.deb
) from Cargo projects.
sh
rustup update # Debian's Rust is too outdated, use rustup.rs
cargo install cargo-deb
Requires Rust 1.63+, and optionally dpkg
, dpkg-dev
and liblzma-dev
. Compatible with Ubuntu. If the LZMA dependency causes you headaches, try cargo install cargo-deb --no-default-features
.
If you get a compilation error, run rustup update
! If you get an error running rustup update
, uninstall your rust/cargo package, and install the official Rust instead.
sh
cargo deb
Upon running cargo deb
from the base directory of your Rust project, the Debian package will be created in target/debian/<project_name>_<version>_<arch>.deb
(or you can change the location with the --output
option). This package can be installed with dpkg -i target/debian/*.deb
.
Debug symbols are stripped from the main binary by default, unless [profile.release] debug = true
is set in Cargo.toml
. If cargo deb --separate-debug-symbols
is run, the debug symbols will be packaged as a separate file installed at /usr/lib/debug/<path-to-binary>.debug
.
cargo deb --install
builds and installs the project system-wide.
No configuration is necessary to make a basic package from a Cargo project with a binary. This command obtains basic information it needs from the Cargo.toml
file. It uses Cargo fields: name
, version
, license
, license-file
, description
, readme
, homepage
, and repository
.
For a more complete Debian package, you may also define a new table, [package.metadata.deb]
that contains maintainer
, copyright
, license-file
, changelog
, depends
, conflicts
, breaks
, replaces
, provides
, extended-description
/extended-description-file
, section
, priority
, and assets
.
For a Debian package that includes one or more systemd unit files you may also wish to define a new (inline) table, [package.metadata.deb.systemd-units]
, so that the unit files are automatically added as assets and the units are properly installed. Systemd integration
[package.metadata.deb]
optionsEverything is optional:
license-file
is used.$auto
keyword.readme
file is used if it is not provided.required
or optional
.[[bin]]
(copied to /usr/bin/
) and package readme
(copied to usr/share/doc/…
).
target/release/
in asset paths, even if Cargo is configured to cross-compile or use custom CARGO_TARGET_DIR
. The target dir paths will be automatically corrected./
it will be inferred that the target is the directory where the file will be copied.templates
, preinst
, postinst
, prerm
, or postrm
scripts.features
list (default true
).false
).false
).Cargo.toml
additionstoml
[package.metadata.deb]
maintainer = "Michael Aaron Murphy <mmstickman@gmail.com>"
copyright = "2017, Michael Aaron Murphy <mmstickman@gmail.com>"
license-file = ["LICENSE", "4"]
extended-description = """\
A simple subcommand for the Cargo package manager for \
building Debian packages from Rust projects."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
["target/release/cargo-deb", "usr/bin/", "755"],
["README.md", "usr/share/doc/cargo-deb/README", "644"],
]
--fast
flag uses lighter compression. Useful for very large packages or quick deployment.
[package.metadata.deb.variants.$name]
There can be multiple variants of the metadata in one Cargo.toml
file. --variant=name
selects the variant to use. Options set in a variant override [package.metadata.deb]
options. It automatically adjusts package name.
[package.metadata.deb.systemd-units]
cargo deb
supports cross-compilation. It can be run from any unix-like host, including macOS, provided that the build environment is set up for cross-compilation:
rustup target add i686-unknown-linux-gnu
) and has to be installed for the host system (e.g. apt-get install libc6-dev-i386
). Note that Rust's and Debian's architecture names are different. See rustc --print target-list
for the list of supported values for the --target
argument.dpkg --add-architecture <debian architecture name>
apt-get install pkg-config build-essential crossbuild-essential-<debian architecture name>
PKG_CONFIG_ALLOW_CROSS=1
will not help at all, and will only make things worse.
apt-get install libssl-dev:<debian architecture name>
CC_<target>
variables.
export HOST_CC=gcc
export CC_x86_64_unknown_linux_gnu=/usr/bin/x86_64-linux-gnu-gcc
(correct the target and paths for your OS).cargo/config
by adding [target.<target triple>] strip = { path = "…" } objcopy = { path = "…" }
. Alternatively, use --no-strip
.Yes, these requiremens are onerous. You can also try cross
or cargo zigbuild
, since Zig is way better at cross-compiling, and then run cargo deb --target=… --no-build
.
sh
cargo deb --target=i686-unknown-linux-gnu
Cross-compiled archives are saved in target/<target triple>/debian/*.deb
. The actual archive path is printed on success.
Note that you can't use cross-compilation to build for an older verison of Debian. If you need to support Debian releases older than the host, consider using a container or a VM, or make a completely static binary for MUSL instead.
To get debug symbols, set [profile.release] debug = true
in Cargo.toml
. Building using the dev profile is intentionally unsupported.
cargo deb --separate-debug-symbols
Removes debug symbols from executables and places them as separate files in /usr/lib/debug
. Requires GNU objcopy
tool.
If you would like to handle the build process yourself, you can use cargo deb --no-build
so that the cargo-deb
command will not attempt to rebuild your project.
cargo deb -- <cargo build flags>
Flags after --
are passed to cargo build
, so you can use options such as -Z
, --frozen
, and --locked
. Please use that only for features that cargo-deb
doesn't support natively.
Cargo-deb understands workspaces and can build all crates in the workspace if necessary. However, you must choose one crate to be the source of the package metadata. You can select which crate to build with -p crate_name
or --manifest-path=<path/to/Cargo.toml>
.
cargo deb --deb-version my-custom-version
Overrides the version string generated from the Cargo manifest.
lzma_stream_encoder_mt
errorThis happens when the system-provided LZMA library is too old. Try with a bundled version:
sh
cargo install cargo-deb --features=static-lzma
or fall back to gzip:
sh
cargo install cargo-deb --no-default-features