Packaging helpers and tools
Overview
The Rust team uses a very uniform way of packaging Rust crates, supported by
various tools. The full pipeline for simple library or
bin crates published on crates.io
looks like this:
- debcargo-conf monorepo on salsa tracking all package crates
- debcargo used to translate upstream crate to Debian source package
- dh-cargo used by generated
debian/rules
file to drive building of source package - cargo wrapper used by
dh-cargo
to ensurecargo
behaves properly for package build purposes - dh-cargo-built-using used by
dh-cargo
to analyze build artefacts and emitBuilt-Using
andStatic-Built-Using
information - cargo-auto-test used by generated
debian/tests/control
to run upstream test suite via autopkgtest
debcargo-conf
See Packaging a single crate for details.
debcargo
debcargo
is a Debian packaging specific tool for converting a single upstream
crate into a Debian source package.
debcargo package <crate> <version>
consumes the following input:
- upstream
Cargo.toml
file (metadata, dependencies, features) debcargo.toml
config file- an overlay directory containing a partial
debian/
directory
to generate the full corresponding Debian source package.
Currently, the following files are automatically generated:
debian/control
, including translatedBuild-Depends
andDepends
debian/rules
usingdh-cargo
debian/copyright.hint
skeleton for filling in the realdebian/copyright
debian/tests/control
usingcargo-auto-test
By adding files to the overlay directory, it is possible to add additional
parts which are copied verbatim to the generated source package. For files
which would be generated by debcargo itself, the generated file will be
suffixed with .hint
, to allow easy diffing.
The debcargo
package ships a fully commented version of debcargo.toml
in
/usr/share/doc/debcargo/debcargo.toml.example
By default, debcargo
will fetch upstream sources from crates.io
, but it is
possible to point it a local directory instead by specifying crate_src_path
in debcargo.toml
.
debcargo
currently only supports packaging a single crate!
For more complicated packaging scenarios, refer to packaging
processes.
dh-cargo
Small glue wrapper between debcargo
-generated debian/rules
and
debhelper
.
It currently hooks into the following parts of the package build:
dh_auto_configure
: calls the cargo wrapper'sprepare-debian
command to setup cargo in a Debian package build contextdh_auto_test
: calls eithercargo build
orcargo test
, to verify the included Rust source actually buildsdh_auto_install
- for library crates: copies the patched Rust source code into the "library" package
- for binary crates: calls
cargo install
anddh-cargo-built-using
to build the executables and collect information about what gets linked into them
dh-cargo
currently only supports packaging a single crate, and only
supports library or binary crates (or a combination of both)!
For more complicated packaging scnearios, refer to packaging
processes.
cargo-auto-test
cargo-auto-test
is a wrapper around cargo test
for usage in autopkgtests.
It will use the cargo wrapper described below to ensure the tests are run
against packaged test dependencies. debian/tests/control
files generated by
debcargo
might serve as a good example for how to call cargo-auto-test
manually, if desired.
cargo-auto-test
only tests packaged library crates. For other test
scenarios, directly calling cargo test
via the cargo wrapper should work as
well.
cargo wrapper
The cargo
wrapper in /usr/share/cargo/bin/cargo
is a small(ish) python
script injected between the build driver (debian/rules
, meson
, pybuild
,
make
, ..) and the real cargo
.
It requires a few pieces of setup in debian/rules
, see the top of the script
itself and the example in complex packages for details:
- source
dpkg
andrustc
makefile snippets - depending on the build system, prepend
/usr/share/cargo/bin
to$PATH
, or set$CARGO
to/usr/share/cargo/bin/cargo
- export some environment variables
As part of the auto_configure
step of the package build, call the
wrapper's prepare-debian
command to generate a cargo config file and a
fake cargo registry for vendored and/or packaged crates. This step is
required for the wrapper to do its job, and should ensure that subsequent cargo
invocations via the wrapper honor usual Debian packaging policies and
conventions:
- use packaged sources instead of fetching from crates.io
- ensure debug symbols are not stripped out in release mode
- honor
DEB_BUILD_OPTIONS
for optimization, LTO and similar settings
Optionally, as part of the auto_test
step of the package build, trigger
cargo test
via the wrapper (either directly or via your package's main
build system). You might want to pass all the features used by your package, or
test all features.
As part of the auto_build
step of the package build, trigger cargo build --release
via the wrapper (either directly or via your package's main
build system). The resulting binaries should be found in
target/<triplet>/release
.
As part of the auto_install
step of the package build, trigger cargo install
via the wrapper.
The cargo wrapper should be used by every Debian package building Rust code!
dh-cargo-built-using
This helper script analyzes the target/..
directory where cargo
puts
intermediate and final build artifacts, to determine:
- which non-Rust binaries might have been statically linked (via the build log)
- which Rust crates might have been statically linked (via the intermediate artifacts)
The found objects are then mapped back to Debian source packages, their
licenses looked up via debian/copyright
and the corresponding
Static-Built-Using
and Built-Using
substvars are emitted.
In some cases, it might be necessary to patch build.rs
scripts to emit
licensing details for consumption by dh-cargo-built-using
- please follow the
instructions if prompted.
dh-cargo-built-using
needs to be called after building a binary, e.g. after
dh_auto_build
or dh_auto_install
, and passed the binary package name for
which the information should be emitted.
Every package building Rust code should be annoted with Static-Built-Using
information!