Debian Rust Packaging Policy

Automated Packaging Tools

The "debcargo" automated packaging tool, and the "dh-cargo" buildsystem for debhelper, automate almost all of the requirements of this policy; you should not need to implement most of these requirements manually. This policy documents those requirements, provides accompanying explanation, and specifically highlights any policies not handled automatically.

Package naming

Rust library crates must use the binary package name librust-cratename-version-dev. Rust library crates should use the source package name rust-cratename-version. version is as defined belowe.

If the crate name contains underscores (_), the source and binary package names must replace them with dashes (-); in this case, dh-cargo requires the package's debian/control file to have an X-Cargo-Crate: field in the source section specifying the upstream name of the crate.

For a crate with semantic version (semver) major.minor.patch, the version component of the name must consist of either major (if major != 0) or 0.minor (if major == 0). This supports the Cargo and semver notion of "compatible versions"; see http://doc.crates.io/specifying-dependencies.html#caret-requirements.

Rust applications may use any binary package name; they do not need to include a version in the package name or allow concurrent installation of multiple versions. A source package that builds no Rust library packages may use any source package name; a source package that builds both Rust library packages and Rust application packages must follow the naming rules for its source package name and its library package names.

This policy does not yet specify any policies for "cdylib" crates, though they will need to follow all applicable policies for shared libraries.

Crate features

A library crate must also generate binary packages for every Cargo "feature" it declares, named librust-cratename-version+featurename-dev. Cargo crate names do not allow a plus sign (+) in them, so this package name will not conflict with the package name for any other Rust library crate or feature package. If the feature name contains underscores (_), the corresponding binary package name must replace them with dashes (-).

Each feature package must pull in all the dependencies needed to build a package that depends on that feature of the crate, including any dependencies on other features of the same crate. If a feature package pulls in no additional dependencies, the main librust-cratename-version-dev package can use a versioned Provides to supply that feature package. The librust-cratename-version-dev should normally incorporate any dependencies required to build the default feature of the crate, and use a versioned Provides to supply the librust-cratename-version+default-dev package as well as any feature packages for features that require no additional dependencies beyond default.

Each feature package must have a versioned dependency on the same version of the main librust-cratename-version-dev package. If a feature of the crate depends on another feature of the same crate, the corresponding feature package for the first feature must have a dependency on the same version of the feature package for the second feature.

Feature packages should not contain any files, other than a symlink from /usr/share/doc/packagename to the main library crate package.

Package dependencies

Library packages must include Depends corresponding to the crate and feature dependencies specified in the crate's Cargo.toml file. These dependencies must satisfy the crate's [dependencies] and [build-dependencies] sections, including any architecture-specific or target-specific dependencies; this allows users and packages to cross-compile for other target platforms, including Windows. However, the dependencies need not satisfy the crate's [dev-dependencies], as those may require experimental or nightly tools for testing or code analysis.

The version constraints on those dependencies must ensure that the version satisfies the corresponding version predicates in Cargo.toml, so that the package can build successfully. However, in some situations, you may want to loosen the version predicates in Cargo.toml and the corresponding version constraints in debian/control. In particular, this can arise if the version constraints across multiple such packages would otherwise require multiple versions of a library crate simultaneously (such as two libraries with the same non-zero major version and different minor versions), while loosening the version constraints would allow packaging just the newer version of that library crate. If you think you may need to change a crate's dependencies, please contact pkg-rust-maintainers@lists.alioth.debian.org first. (These cases most commonly arise because Cargo cannot currently express constraints on external non-Rust packages, including the rustc compiler itself; upstream may depend on an older version because they do not want to require a newer rustc compiler. Debian can use the newer compatible version for all such packages, once Debian packages the newer rustc compiler.)

Library crate packages may have Suggests for their feature packages.

Library crates should not, in general, have Build-Depends on other Rust libraries or build tools, as they do not build any Rust code when constructing their binary -dev packages (which only contain source code; see below). Application crates must have Build-Depends on the Rust library and feature packages needed to build, with appropriate version constraints corresponding to the version predicates of that crate's Cargo dependencies.

Library package structure

Library crate packages must ship the source code of the crate in the /usr/share/cargo/registry/cratename-version/ directory.

Motivation: At the time of writing, Rust does not have a stable ABI. So, we can't reasonably ship compiled versions of Rust libraries. Instead, library packages ship source code, and application packages build all the library crates they use from source. We will revisit this point, if the situation changes.

Library crate packages must also ship a .cargo-checksum.json file in that directory. This file must include a key "package", whose value provides the SHA256 checksum of the corresponding upstream .crate file, as an ASCII hex lowercase string. This file must also include a key "files", with either the value {}, or a value providing checksums of the source files in the package in the format expected for a Cargo directory registry. dh-cargo expects the source package to contain this file as debian/cargo-checksum.json.

This format allows using /usr/share/cargo/registry as a Cargo directory registry with directory sources. For more details on how this mechanism works, see http://doc.crates.io/source-replacement.html#directory-sources.

Since the library crate package provides only source code, and no compiled binaries, it should use Architecture: all. This applies even if the library crate only runs on certain target architectures or operating systems; library crates must not use Architecture values other than all. A higher-level library crate or application crate may use an architecture-specific library conditionally, using Cargo conditionals to only require it on the architectures it supports. If an application crate depends unconditionally on a non-portable library crate, that makes the application itself non-portable, and the application can use a correspondingly narrower Architecture field.

Application package build process

Application packages must not allow Cargo to access the network when building. Instead, application packages must use the packaged versions of crate sources, via the corresponding library crate packages, which provide a Cargo directory registry.

Package builds, for both library and application crates, must not access the network when building. In particular, they must not download or check out any sources at build time.

Package builds must set $CARGO_HOME to a directory within the package build directory, to avoid writing to the building user's home directory outside the package build directory.

Packages builds should run Cargo in --verbose mode.

Maintenance

Library crates should generally have pkg-rust-maintainers@lists.alioth.debian.org as the Maintainer, to keep them grouped together, and to simplify transitions and rebuilds. Applications may list any maintainer, but please coordinate with pkg-rust-maintainers@lists.alioth.debian.org when packaging new Rust libraries or applications. Application packages may require bin-NMUs to rebuild with newer versions of Rust libraries.

Upstreaming changes

Packaging a Rust library or application may in some cases require changes to its source code, to integrate better with the Debian ecosystem, comply with Debian policies, or otherwise produce better results with packaging. Whenever possible, prefer to integrate such changes upstream, rather than as patches in Debian (upstream-first approach). Whenever possible, seek to improve the debcargo logic or the upstream crate metadata used by that, rather than patching the resulted generated sources (automation-first approach). This makes the Rust and crates.io ecosystem easier to maintain both upstream and in Debian, and avoids technical debt.

dh-cargo

Rust library and application packages should use dh-cargo, to simplify implementation of the Rust packaging policy, including any future transitions or new policy requirements.