Packaging workspaces, and crates not published on crates.io
Certain projects pack tens of internal crates in a workspace. Some of them still publish on crates.io, but it's quite a hassle to package them one by one with the single crate process, not to mention maintaining them in sync later; some don't, often seen in projects that build programs - these internal crates see no use outside.
Thus, there is a desire to package such projects as a single source package, and either each library crate as a binary package, or only one or few binary package(s) packing the built program(s).
We are still exploring ways to build them. Recorded here are some existing practices, not team recommendations.
For programs, it doesn't matter if the crates are not published on crates.io. For libraries not on crates.io, however, their package name scheme has yet to be decided, since the librust-*-dev namespace is reserved for libraries from crates.io. Luckily, there is currently no need to.
General setup
This kind of packaging falls back to "traditional" ways in Debian. This assumes you are already familiar with general Debian packaging. Experience with the single crate process isn't strictly needed but is helpful.
- Import upstream source by either cloning the upstream repository,
gbp import-orig
, or ways you prefer. - Prepare the common things in debian/ as usual.
- Check packaging status of dependencies. There is currently no ready-made
tool for this, but you can gather all
[dependencies]
,[dev-dependencies]
, and[build-dependencies]
in Cargo.toml of these internal crates into an empty cargo project, and run cargo-debstatus there. - Add them as
Build-Depends
along withrustc
andcargo
in debian/control. - Choose a build approach: there is dh-rust which seemingly supports workspaces, there is dh-cargo which doesn't yet but works fine for single crates (example), and there is an overly simple approach for programs (example).
- Patch the source as needed.
No need to publish internal crates
This is the easy part. After adding needed dependencies as B-D, patching them to use versions in Debian, patching out unavailable dependencies and feature depending on them, use one of the debhelper buildsystems described above.
Publish internal crates
Consider these situations:
- Crates in workspace are released in lockstep, sharing the same version for each release.
- They only reside in a workspace, but are released in their own pace.
There's not much to say about (1). For (2), though, there is a problem: the
source package, or the workspace, has a version. Each binary package, or crate,
also has their own version. The only known way to achieve this is to
dpkg-gencontrol
/dh_gencontrol
for each binary package; see
rust-curve25519-dalek for an example.
Currently, use dh-rust. dh-cargo has no workspace support yet.
Add a Package
stanza for each of them in debian/control, which Provides
their versioned feature virtual packages. Policy states which are
needed.
Then it's the tiresome work of keeping B-Ds, Package
s, and Depends
in sync.
There hasn't been strong urge to write a tool for this.
Overly simple approach for programs
Pretty simple, but lacks considerations in dh-cargo or dh-rust, and only works for programs, not libraries. Use at your own risk.
Prepare a .cargo/config.toml replacing source.crates-io
to the Debian
registry:
[source.crates-io]
replace-with = 'debian'
[source.debian]
directory = '/usr/share/cargo/registry'
and put it in place before build, and clean after build (in debian/rules):
execute_before_dh_auto_configure:
mkdir -p .cargo
-cp .cargo/config.toml debian/cargo-config.toml.orig
touch .cargo/config.toml
cat debian/cargo-config.toml >> .cargo/config.toml
execute_before_dh_auto_clean:
rm -rf .cargo/config.toml
-cp debian/cargo-config.toml.orig .cargo/config.toml
To follow Multi-Arch, use the variables provided by rustc:
include /usr/share/rustc/architecture.mk
CARGO_BASE_ARGS= --release --target $(DEB_HOST_RUST_TYPE)
override_dh_auto_build:
cargo build $(CARGO_BASE_ARGS)
override_dh_auto_test:
cargo test $(CARGO_BASE_ARGS)