Packaging a GNOME rust application


GNOME increasingly uses Rust as language for libraries (e.g. rsvg) and a growing number of GUI programs (e.g. Shortwave). Most of the GUI programs use meson as build system. This page tries to give an introduction how you should package such a program. Note: this explicitly is targeted for programs either endorsed by GNOME or using the GTK-rs bindings. It also works for other programs and libraries (see python-cryptography) though you might need to make adjustments. This is explicitly not intended for crates or binary crates, for those see Teams/RustPackaging.


First you should check if the program you're trying to introduce compiles with the current gtk-rs stack in debian. For instance if the program uses gtk-rs 0.7.x but the current debian one is 0.6.x you can get the source and "downgrade" all affected crates in  Cargo.toml , then run  cargo build  to see if it compiles. Updating the gtk-rs stack involves >44 crates to build and upload one by one so maybe you're in luck if it works with an older version. Additionally, install and run cargo-debstatus on the cloned repo to check if all other dependencies are in debian. If both prerequisites are satisfied you need to "translate" the dependencies from  Cargo.toml  to build-dependencies in  debian/control .

Then you can get the source and prepare the DEP-14 repo as usual.

Mapping rust dependencies to build-dependencies

For instance  adw = {package = "libadwaita", version = "0.4", features  = ["v1_3"]}  translates to librust-libadwaita+v1_3-dev (>= 0.4). To automate this procedure you can build debcargo from this MR and run debcargo deb-dependecies Cargo.toml in the project root. This does not work yet for alpha, beta and rc version as dependencies and workspaces are not yet supported, too. If you have a dependency in Cargo.toml referencing a git url (e.g.  rustdoc-stripper = { git = "" }  replace it with the librust-* debian equivalent in debian/control and patch Cargo.toml with quilt to use a versioned dependency (and hope it compiles). If not, open an issue upstream. librsvg also might get included that way, in that case just add librsvg2-dev as build-dependency in debian/control and you should be good to go.

Add cargo to call the cargo wrapper (and meson if the program uses that).

Patching Cargo.toml

You might need to patch Cargo.toml anyway if the version in debian is newer/older than the one specified. The buildprocess reads Cargo.toml so you need to down- or upgrade the version if it's not matching.


Change the entire file to this:

 #!/usr/bin/make -f

include /usr/share/dpkg/
include /usr/share/dpkg/
include /usr/share/dpkg/
include /usr/share/rustc/
export PATH := /usr/share/cargo/bin:$(PATH)
export CARGO=/usr/share/cargo/bin/cargo
export CARGO_HOME=$(CURDIR)/debian/cargo_home
export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow

        dh $@ 

        rm -rf debian/cargo_registry

        $(CARGO) prepare-debian debian/cargo_registry --link-from-system
        rm -f Cargo.lock

Note: this is assuming that the buildsystem is automatically detected by dh. If that's not the case you'll need to specify it.


If the source is prepared following above steps you should be able to build fully offline. In case you still spot a "Downloading crates" line in the buildlog check the source code if CARGO_HOME gets set at some point. This overrides the one we set so you'll need to patch that (and contact upstream about it, see here).


If you get stuck at some point ask on the #debian-rust IRC channel. Do not attempt update any standalone crate part of the gtk-rs stack because a) most likely, it won't work and b) it will break other programs/crates . Instead either wait until the new version lands in unstable or upgrade everything at once. The whole tree can be found here