User:Schievel

Packaging Rust projects

Rust has it's own package manager cargo, which gentoos cargo.eclass utilizes. This is very convenient for software developers. However it comes with some caveats for maintainers. This section will grow every time I encounter something new thats worth mentioning.

Gentoo has it's own program to make ebuilds out of Rust projects automatically: https://packages.gentoo.org/packages/dev-util/cargo-ebuild

To use cargo ebuild, get the source of the Rust program. This is usually done by cloning the git repository of the program. Then go into that repository and run `cargo ebuild`. Cargo ebuild automatically checks dependencies for vulnerabilities, which takes a while. One can run `cargo ebuild --noaudit` to speed up this process.

If everything goes well, cargo ebuild spits out an ebuild into the rust programs repository folder, which can then moved into a ebuild repository like ::gentoo or the guru.

However, this will only give a blank frame to work with. The homepage and description needs to be added and if the Rust program is not on crates.io the SRC_URI as well.

Cargo ebuild also spits out the licenses, but it can not guarantee that these are correct. So run `cargo license` in the Rust repository to get a list of licenses. Be aware that `cargo license` will give the licenses in SPDX format, which Gentoo does not always uses. So some effort needs to be put into 'translating' them.

Common problems with dependencies

- crates.io dependencies

If all dependencies are fetched from crates.io the ebuild from cargo ebuild works from scratch. Dependencies that are fetched from crates.io are declared like them in cargo.toml of the Rust project:

```

[dependencies]

itertools = "0.10.3"

```

`Cargo ebuild` will put them into the CRATES variable and they are put into the SRC_URI variables via `$('''cargo_crate_uris)` which should already be added by `cargo ebuild`. They are then automatically fetched and unpacked into the right place via cargo.eclass' `cargo_src_unpack`'''

- github/ gitlab etc. dependencies

Sometimes software developers are not happy with the version of a crate on crates.io or a crate is not available there and they want to get it from github instead. Then they declare a dependency in cargo.toml like this:

```

tree-sitter-haxe = { git = " https://github.com/vantreeseba/tree-sitter-haxe ", version = "0.2.2", optional = true }

```

(Be aware that if cargo.toml of a Rust program says something like `tree-sitter-c-sharp = { git = " https://github.com/tree-sitter/tree-sitter-c-sharp ", branch = "master" }` it wants to fetch the latest commit on the master branch of that github repository. This means we can only make a live ebuild out of this package. (is this correct?)

Which means that the release 0.19.0 from the tree-sitter-elixir github repo should be checked out. We can not clone a git repository without git-r3.eclass but we can simulate this in the ebuild. For this example we would put

```

SRC_URI=" https://github.com/vantreeseba/tree-sitter-haxe/archive/v0.2.2.tar.gz "

```

into SRC_URI. The cargo.eclass notices, that is does not end with .crate and will just unpack it like any other thing in SRC_URI into ${WORKDIR}. But we need to tell cargo where to find that dependency. Therefore we patch the cargo.toml file and change the line of that dependency like this:

```

tree-sitter-haxe = { path = "../tree-sitter-haxe-v0.2.2" }

```

The path is relative to the cargo.toml file, so it could be something like `../../tree-sitter-haxe-v0.2.2` as well, if that dependency is not in the top cargo.toml.

The patch points to the dependencies folder in ${WORKDIR}

Writing live ebuilds

Writing live ebuilds for Rust is way easier than writing non-live ones. The first frame of the ebuild can be created via `cargo ebuild` as well. Then set the ebuilds version in the files name to 9999.

Live ebuilds do not need the CRATES variable, so we can remove that. Also SRC_URI is not used, they usually need to fetch the sources via git-r3.eclass or similar.

In `src_unpack` put `cargo_live_src_unpack`. This will fetch the needed dependency crates using cargo.

Problems with live ebuilds

When a Rust project uses unpinned dependencies in their cargo.toml, e.g.

```

tree-sitter-c-sharp = { git = " https://github.com/tree-sitter/tree-sitter-c-sharp ", branch = "master" }

```

cargo will always want to check if that dependency is up do date in later stages of the ebuild. This will cause the error

```

can't update a git repository in the offline mode

```

In this case we can add `cargo_src_configure --frozen` into `src_configure`. This will stop cargo from checking if what it just fetched is up to date.