openSUSE:Packaging Rust Software

Jump to: navigation, search


How to package software written in Rust for openSUSE Build Service.

Maintaining/Creating packages that use Rust code

Dependencies

You should install the following packages to help build rust packages for OpenSUSE.

zypper install obs-service-cargo_vendor osc obs-service-tar obs-service-obs_scm \
    obs-service-recompress obs-service-set_version obs-service-format_spec_file \
    obs-service-cargo_audit cargo sudo

Optionally, you can install cargo lock2rpmprovides to help generate the license string.

cargo install cargo-lock2rpmprovides

If you want to cache build artefacts, as of osc-0.173.0 you can use sccache to help reduce repeat build times.

# ~/.config/osc/oscrc
sccache = 1
sccache_uri = file:///var/cache/obs_sccache.tar

Alternately you can use a network sccache

# ~/.config/osc/oscrc
sccache = 1
sccache_uri = redis://127.0.0.1:6379

Setting up the redis cache is beyond the scope of this page.

Creating the Package

You should checkout your blank package with:

osc co home:<username>/package
cd home:<username>/package

A skeleton RPM spec file for a rust package is:

Name:           hellorust
#               This will be set by osc services, that will run after this.
Version:        0.0.0
Release:        0
Summary:        A hello world with a number of the day printer
#               If you know the license, put it's SPDX string here.
#               Alternately, you can use cargo lock2rpmprovides to help generate this.
License:        Unknown
#               Select a group from this link:
#               https://en.opensuse.org/openSUSE:Package_group_guidelines
Group:          Amusements/Games/Other
Url:            https://github.com/Firstyear/hellorust
Source0:        %{name}-%{version}.tar.zst
Source1:        vendor.tar.zst
Source2:        cargo_config
BuildRequires:  cargo-packaging
# Disable this line if you wish to support all platforms.
# In most situations, you will likely only target tier1 arches for user facing components.
ExclusiveArch:  %{rust_tier1_arches}

%description
A hello world with a number of the day printer.

%prep
# The number passed to -a (a stands for "after") should be equivalent to the Source tag number
# of the vendor tarball, 1 in this case (from Source1).
%autosetup -a1
install -D -m 644 %{SOURCE2} .cargo/config
# Remove exec bits to prevent an issue in fedora shebang checking. Uncomment only if required.
# find vendor -type f -name \*.rs -exec chmod -x '{}' \;

%build
%{cargo_build}

%install
# using cargo_install (only supports bindir)
%{cargo_install}
# manual process
# install -D -d -m 0755 %{buildroot}%{_bindir}
# install -m 0755 %{_builddir}/%{name}-%{version}/target/release/hellorust %{buildroot}%{_bindir}/hellorust
 
%check
%{cargo_test}

%files
%{_bindir}/hellorust

%changelog

There are a few commented areas you鈥檒l need to fill in and check. But next we will create a service file that allows OBS to help get our sources and bundle them for us. This should go in a file called _service

<services>
  <service mode="disabled" name="obs_scm">
    // 鉁 URL of the git repo 鉁
    <param name="url">https://github.com/Firstyear/hellorust.git</param>
    <param name="versionformat">@PARENT_TAG@~@TAG_OFFSET@</param>
    <param name="scm">git</param>
    // 鉁 The version tag or branch name from git 鉁
    <param name="revision">v0.1.1</param>
    <param name="match-tag">*</param>
    <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
    <param name="versionrewrite-replacement">\1</param>
    <param name="changesgenerate">enable</param>
    // 鉁 Your email here 鉁
    <param name="changesauthor"> YOUR EMAIL HERE </param>
  </service>
  <service mode="disabled" name="tar" />
  <service mode="disabled" name="recompress">
    <param name="file">*.tar</param>
    <param name="compression">zst</param>
  </service>
  <service mode="disabled" name="set_version"/>
  <service name="cargo_vendor" mode="disabled">
      // 鉁 The name of the project here 鉁
     <param name="srcdir">hellorust</param>
     <param name="compression">zst</param>
     <param name="update">true</param>
  </service>
  <service name="cargo_audit" mode="disabled">
      // 鉁 The name of the project here 鉁
     <param name="srcdir">hellorust</param>
  </service>
</services>

This service file does a lot of the work for us:

  • It will fetch the sources from git, based on the version we set.
  • It will turn them into a tar.zst for us.
  • It will update the changelog for the rpm, and set the correct version in the spec file.
  • It will download our rust dependencies, and then bundle them to vendor.tar.zst.
  • It scans our project for any known vulnerabilities These come from the RustSec advisory database.

You can run this with:

osc service ra

Optionally, you can now run the lock2rpmprovides:

cd hellorust
cargo lock2rpmprovides

This will generate a license string you can copy into the spec file.

You can then add the needed sources and commit to OBS

osc add _service _servicedata cargo_config hellorust-0.1.1~git0.db340ad.tar.zst hellorust.spec vendor.tar.zst
osc ci

From here, you can follow the How to contribute to Factory guide.

Projects with Cargo workspaces

Workspaces is a Cargo feature to build multiple projects from the same git tree. You can make the following changes to your spec to build them in the same project:

BuildRequires:  cargo-packaging >= 1.2.0
[...]
%build
%{cargo_build} --all
[...]
%install
%{cargo_install -p project1}
%{cargo_install -p project2}

Updating your Package

Once your package has been accepted, you can then update it with the following steps:

osc bco devel:project/pkgname
cd home:username:branches:devel:project/pkgname
osc service ra
osc status

Then inspect the changes, and osc rm any old files, and osc add any updated source files.

From there you can then do a build and a ci/sr

osc build
osc ci
osc results
osc sr

References