Crates.io | cargo-deb |
lib.rs | cargo-deb |
version | 3.6.0 |
created_at | 2017-07-31 23:46:03.490855+00 |
updated_at | 2025-08-22 10:27:12.398024+00 |
description | Make Debian packages (.deb) easily with a Cargo subcommand |
homepage | https://lib.rs/crates/cargo-deb |
repository | https://github.com/kornelski/cargo-deb |
max_upload_size | |
id | 25911 |
size | 411,045 |
This is a Cargo helper command which automatically creates binary Debian packages (.deb
) from Cargo projects.
rustup update # Bookworm's Rust is too outdated, use Trixie or rustup.rs
cargo install cargo-deb
Requires Rust 1.76+, 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.
cargo deb
When you run cargo deb
from the base directory of your Rust/Cargo project, the Debian package will be created in target/debian/<project_name>_<version>-1_<arch>.deb
(or you can change the location with the --output
option).
This package can be installed with dpkg -i target/debian/*.deb
. cargo deb --install
builds and immediately installs the package on the local system.
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
, and homepage
or repository
. For a more complete Debian package, you may also define a new table, [package.metadata.deb]
that contains additional metadata (described below).
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
Debug symbols are stripped from built binaries by default, unless [profile.release] debug
is enabled in Cargo.toml
(debug = "line-tables-only"
is recommended). The --separate-debug-symbols
and --dbgsym
options package debug symbols as separate files installed at /usr/lib/debug/<build-id-or-path>.debug
. This can also be enabled via [package.metadata.deb]
under separate-debug-symbols
.
[package.metadata.deb]
optionsEverything is optional:
--maintainer
on the command line.license-file
is used.$auto
keyword.readme
file is used if it is not provided.--deb-revision
on the command line.required
or optional
.["$auto"]
, which takes binaries built by Cargo (copied to /usr/bin/
) and the package's readme
(copied to usr/share/doc/…
).
source
: the first argument of each asset is the location of that asset in the Rust project. Glob patterns are allowed. Always use target/release/
path prefix for packaging binaries built by Cargo, even if that's not the real path to your target directory. Cargo-deb uses this prefix to detect what to compile, and will replace it with the actual target dir path, taking into account cross-compilation, build profiles, workspaces, CARGO_TARGET_DIR
, custom configs, etc. If you try to "fix" the hardcoded target/release
paths, you will break cargo-deb, and make it package stale files and mishandle debug info.dest
: the second argument is where the file will be copied. If it starts with usr/lib
, it will be changed to usr/lib/$tuple
when multiarch option is enabled.
/
it will be inferred that the target is the directory where the file will be copied.mode
: the third argument is the permissions (octal string) to assign that file.templates
, preinst
, postinst
, prerm
, or postrm
scripts.features
list (default true
).false
). If it is enabled, then cargo deb --no-separate-debug-symbols
can be used to suppress extraction of the debug symbols.false
)./etc
["/not-etc/app/config"]
. You still need to list the files in assets
to have them packaged.release
.Cargo.toml
additions[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 path is special, and gets replaced by cargo-deb with the actual target dir path.
["target/release/cargo-deb", "usr/bin/", "755"],
# both array and object syntaxes are equivalent:
{ source = "README.md", dest = "usr/share/doc/cargo-deb/README", mode = "644"},
]
# assets = ["$auto"] # the default if assets are not specified
--fast
flag uses quicker/lighter compression in the .deb
file. Useful for quick deployment of large packages. --dbgsym
can also improve speed by making two packages in parallel.
--multiarch=same
will use /usr/lib/$debian-target-tuple/
for library paths, allowing library packages for different architectures to co-exist.
[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 appends the variant name to the package name (or you can set the name
in the variant).
To get debug symbols in the package, set in Cargo.toml
:
[profile.release]
debug = "line-tables-only"
# or debug = 1 for fatter debug info
Note: building using the dev
profile is intentionally unsupported. You can specify other profiles with --profile
.
-dbgsym.ddeb
packagecargo deb --dbgsym
Removes debug symbols from the executables, and makes a second -dbgsym.ddeb
package with only /usr/lib/debug/.build-id/*
files. Requires GNU objcopy
tool. The .ddeb
package is a regular deb package that can be installed together with the base .deb
package.
cargo deb --separate-debug-symbols --compress-debug-symbols
Removes debug symbols from the executables, and places them in separate files in /usr/lib/debug/.build-id/*
. Requires GNU objcopy
tool. --compress-debug-symbols
makes the debug symbols compressed internally, taking less space on disk.
When defining a variant it can be useful to also define different assets. If the merge-assets
option is used, cargo-deb
will merge the list of assets provided to the option with the parent asset list. There are three merging strategies, append
, by.dest
, and by.src
.
Note: Using both append
, and a by.*
option are allowed, w/ the former being applied before the latter.
The special "$auto"
entry is not expanded before merging. Explicit paths take precedence over "$auto"
.
merge-assets
# Example parent asset list
[package.metadata.deb]
assets = [
# binary
["target/release/example", "usr/bin/", "755"],
# assets
["assets/*", "var/lib/example", "644"],
["target/release/assets/*", "var/lib/example", "644"],
["3.txt", "var/lib/example/3.txt", "644"],
["3.txt", "var/lib/example/merged.txt", "644"],
]
# Example merging by appending asset list
[package.metadata.deb.variants.mergeappend]
merge-assets.append = [
["4.txt", "var/lib/example/appended/4.txt", "644"]
]
# Example merging by `dest` path
[package.metadata.deb.variants.mergedest]
merge-assets.by.dest = [
["4.txt", "var/lib/example/merged.txt", "644"]
]
# Example merging by `src` path
[package.metadata.deb.variants.mergesrc]
merge-assets.by.src = [
["3.txt", "var/lib/example/merged-2.txt", "644"]
]
# Example merging by appending and by `src` path
[package.metadata.deb.variants.mergeappendandsrc]
merge-assets.append = [
["4.txt", "var/lib/example/appended/4.txt", "644"]
]
merge-assets.by.src = [
["3.txt", "var/lib/example/merged-2.txt", "644"]
]
[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
arguments.dpkg --add-architecture <debian architecture name>
apt-get install pkg-config build-essential crossbuild-essential-<debian architecture name>
pkg-config
. Setting 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 requirements 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
.
cargo deb --target=i686-unknown-linux-gnu
cargo deb --target=x86_64-unknown-linux-gnu --target=aarch64-unknown-linux-gnu
Cross-compiled archives are saved in target/debian/*.deb
. The actual archive path is printed on success. Multipe --target
platforms can be specified at the same time to build them in parallel.
Note that you can't use cross-compilation to build for an older version 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.
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
, -j
, or --timings
. Please use that only for options 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 1.my-custom-version
Overrides the version string generated from the Cargo manifest, including revision. Alternatively, --deb-revision
can be used to change only the suffix.
For maximum logging, use:
cargo deb -vv
RUST_LOG=debug cargo deb -vv
lzma_stream_encoder_mt
errorThis happens when the system-provided LZMA library is too old. Try with a bundled version:
cargo install cargo-deb --features=static-lzma
or use the xz command-line tool by setting the --compress-system
flag.
[!NOTE] cargo-deb uses the xz2 crate that bundles an old safe version of liblzma 5.2 by the original maintainer, and a simple Cargo-based build script. It is unaffected by the CVE-2024-3094.