Unable to build spec file generated by rust2rpm

Hi team! I was trying to package ncspot as an rpm, but it seems like dnf builddep is unable to build and install the cargo crates that this package depends on:

error: Failed build dependencies:
	(crate(chrono/default) >= 0.4.0 with crate(chrono/default) < 0.5.0~) is needed by rust-ncspot-0.10.0-1.fc36.x86_64
	(crate(clap/default) >= 3.1.18 with crate(clap/default) < 4.0.0~) is needed by rust-ncspot-0.10.0-1.fc36.x86_64
	(crate(clipboard/default) >= 0.5.0 with crate(clipboard/default) < 0.6.0~) is needed by rust-ncspot-0.10.0-1.fc36.x86_64
	(crate(crossbeam-channel/default) >= 0.5.0 with crate(crossbeam-channel/default) < 0.6.0~) is needed by rust-ncspot-0.10.0-1.fc36.x86_64
	(crate(cursive) >= 0.18.0 with crate(cursive) < 0.19.0~) is needed by rust-ncspot-0.10.0-1.fc36.x86_64
	(crate(cursive/pancurses-backend) >= 0.18.0 with crate(cursive/pancurses-backend) < 0.19.0~) is needed by rust-ncspot-0.10.0-1.fc36.x86_64
...

I followed the documentation about packaging rust applications for Fedora here, as well as a (slightly outdated) tutorial given in a talk here. I even tried building the rust-ripgrep.spec file shown as an example in the documentation but got a very similar looking error.

Maybe I’m missing some command to build these dependencies or to move them to a place where rpmbuild sees them?

Thanks in advance!

1 Like

dnf builddep does not actually build anything.
It just installs build dependencies from the existing Fedora repositories.

Could it just be that those dependencies are either

  1. not packaged for Fedora at all, or
  2. packaged, but in different version that what ncspot expects?

For example, checking rust-cursive-devel at packages.fedoraproject.org,
you see that it is at version 0.16.3 in all Fedora releases,
while the error you got indicates that ncspot requires a different range.

Solutions to such problems include:

  1. Packaging any missing dependencies.
  2. Updating versions of packages already in Fedora to match ncspot needs.
    You need to be careful that you do not break any existing dependent packages,
    which obviously have a different version range requirements
    — you may need to introduce compatibility packages.
  3. Patching ncspot to be more relaxed about dependency versions
    — often upstreams have not carefully determined the working version range,
    but just inserted something,
    e.g. the latest version at the time they added the dependency.
  4. Patching existing dependees of ncspot dependencies to be more relaxed about dependency versions.

(Note that I have not actually packaged anything for Rust,
so there may be some details that I am missing.)

1 Like

Thank you so much for your timely reply.

I ended up reading about the mock command in this other thread and ended up using it to build the dependencies which were available on the standard repos. Still, some dependencies are not yet packaged for Fedora, so I’ll probably need to package them before I package ncspot (in accordance with your “Solution 1”).

Again, thanks a lot for your help!

Good to hear that you have made progress.
Using mock is definitely a good idea,
as is first targeting Rawhide when packaging for Fedora.
mock makes it easy to build for Rawhide.

The problem in building for Rawhide is,
how to run the built binary to test it.
I use Toolbx for that.
I build on my regular Fedora with mock,
then install the result in a Rawhide toolbox and test there.

If you have any further questions, do not hesitate to ask!

As @oturpe as mentioned, you will need to use mock for building (most) Rust packages. We use pretty modern features of RPM to make packaging Rust crates easier, but that also means that using plain rpmbuild will not work (unless you jump through some hoops). I definitely recommend using mock, and for new packages, targeting rawhide is a good idea, as well, because that’s what’s checked during package review.

PS: The thread you linked here is no longer up-to-date. The build process in Fedora build infrastructure is now the same for Rust packages as for any other Fedora package, and the limitation that crate packages are only available in Rawhide has not been true since Fedora 34.

But Rust packages have, almost since the very beginning, needed to be built with mock (because we use dynamic BuildRequires), this has not changed.

BTW: I recommend that you don’t use the rustls based TLS backend of reqwest (i.e. that you patch ncspot to use the default native-tls backend). rustls is really hard to support for us, it uses a really old BoringSSL fork for crypto, and it’s not supported on all our architectures.

If you have questions regarding Rust packaging, feel free to ping me in the #rust:fedoraproject.org on the fedoraproject matrix server, or in the #fedora-rust channel on irc.libera.chat.

I’m having a similar problem to the above when trying to build the SPEC file generated by rust2rpm for the LAUREL crate.

I’m getting:

No matching package to install: 'crate(gperftools/default) >= 0.0.0'
No matching package to install: 'crate(posix-acl/default) >= 1.0.0'

When I try and build with Mock using the following command line:

mock -r fedora-$(rpm -E %fedora)-x86_64 --sources=. --spec=./rust-laurel.spec

I’ve tried reading through the documentation for rust2rpm but there’s not much out there I can find. I’m assuming that clearly what I need to do here is package the two dependencies that Mock can’t find here, but I’m not sure how to build that into the LAUREL packaging process in order to package the dependencies, install them, and then make them available to the Mock command I’m trying to run.

Any ideas?

In general, one needs to package all dependencies first, get them included in the repos so that they’re available to mock/koji and then proceed to whatever package requires it.

You can do things like chain build where the few packages get built in the required order and are added to the chroot so mock knows about them:

mock --chain ...

Here’s how this works with fedpkg/koji:

1 Like

Thanks - I think chained builds is exactly what I need!

1 Like