Rust packaging on Exherbo

At Clever Cloud, we love giving new technologies a try. Since its inception, rust has always been quite appealing and we always wanted to find projects for which rust would be an adequate solution.

Now that rust is mature enough (to our taste), we started giving it a go, and we needed a way to easily package rust software for our distribution of choice: Exherbo.

Rust package manager: cargo

Amongst the tooling shipped with rust is cargo. Cargo allows you to simply build, test and install a package and its dependencies. It's actually very nice to use when developing.

If we were to install software with cargo, there are two solutions:

  • Either we want to install something like a private or local projects and we just
    have to go to the sources directory, where the Cargo.toml file is, and run
    cargo install
  • Or we want to install something publicly available, on
    for example, we can just run cargo install crate_name, crate_name being the actual
    crate (cargo package) name. We could also pass it a git URL as an alternative.

Regarding production environment and system-wide utilities, we want everything to be managed by the distribution package manager, paludis, so we had to hook up those two and try to make them work together as well as possible.

How packaging rust is different from packaging other software

Currently, rust doesn't support installing libraries system-wide as they're not confident enough in the stability of their ABI yet. What that concretely means is that it's not yet possible to install any rust library, and then use it to build dependent stuff. You have to rebuild all the dependencies each time you build a rust binary.

That particular point is the most noticeable difference on the packaging point of view. Instead of building and installing the dependencies, then the dependents, you only install the final product with everything built in.

What a "traditional" install process looks like in a source-based distribution

For traditional packages, the build and install process is composed of several sequential steps, that we can summarize like this, in that order:


This is the step where we download everything, usually the software sources.

This is the only step for which network sandboxing is disabled.


Here we unpack the sources in a sandboxed environment. Network sandboxing is on as well as file system sandboxing for this step and all the steps onwards.


This is an optional phase, not needed by all packages. It's the moment when we generate build-system files if needed and apply patches to the software sources.


We decide there which features we want to enable or not for the build.


Where the actual build happens.


We install the resulting binaries/files in a sandboxed location replicating the / hierarchy.


Once everything gets validated in terms of file system access, everything gets installed to the root file system.

What a rust install process looks like

A rust install pretty much ressembles a traditional one, with one huge exception.

As I said before, cargo install supports either reading a local Cargo.toml, or being passed a crate name or a git URL.

On the other hand, cargo fetch, which is the command that downloads all the dependencies doesn't have these options, it only supports reading a local Cargo.toml and fetching the dependencies listed in it. If libraries were installable system-wide, we wouldn't need this step at all, but since they're not, we have to do this step after unpacking the sources, to be able to access the Cargo.toml.

This has serious implications, it means that we extend the unpack phase with three additional actions:

  • disable the network sandboxing, which is really sad and we should never do that
  • cargo fecth
  • re-enable the network sandboxing

Of course, we don't have to download the dependencies at each reinstall, cargo supports a CARGO_HOME environment variable allowing us to store the downloads in a shared location with all other distfiles.

We'll eventually be able to install libraries system-wide, but I don't see that happening any time soon. The better workaround I could come up with to clean up this hack is to make cargo fetch support being given a crate name or a URL, matching its companion cargo install. Here is the corresponding github issue but I'm not sure whether it will be implemented nor when.

Actual implementation and examples

The implementation of my exlib (which is to exherbo packages what libraries are to software) can be found here.

cargo-watch is a good example of what a rust exherbo package using this exlib looks like. You can see it's fairly trivial and everything is automatic.


À lire également

Up to €100,000 in funding to adopt Hyper Open X technologies

The Hyper Open X consortium, made up of sixteen major French cloud players, has launched anambitious call for projects designed to accelerate the adoption of open source technologies for cloud and edge computing.

Clever Cloud announces international growth strategy and the expansion of leadership team

Nantes, France - Clever Cloud, French creator of Platform as a Service (PaaS) hosting and deployment solutions, announced today its intention to expand internationally, with a particular focus on the African and South Asian markets.
Company Press

Materia KV: our easy-to-use serverless key-value database is available to all

Clever Cloud was born out of a desire to make life easier for developers, by providing them automation tools and interfaces, so that they can concentrate on their applications and sites.