Debian Library Transition Guide

One of the Debian package sets I maintain has multiple soname bumps and binary package name changes. This means that the packages have to go through Debian's NEW queue and we need multiple library transitions.

gmerlin is a "multiformat media player" and library. The reason I package it is that it provides a nice backend for playing back a lot of video formats (basically wrapping ffmpeg in a usable interface) for Gem Apart from the core "player" package, gmerlin is split into a number of libraries (that do the actual work and which is what I'm interested in) - most of which are packaged independently in Debian.

The last release of gmerlin has been about 10 years ago, but it is still (somewhat) actively maintained by Burkhard Plaum. Since the world keeps turning and the dependencies of gmerlin evolve, there have been some recent fixes to prevent bitrot. So I decided to upgrade the packages to the latest SVN snapshot (yes, SVN is not (entirely) dead). The libraries have seen some significant changes, breaking ABI and API compatibility, so it rightfully got a soname bump. This means, that the packages have to go through Debian's NEW queue.

I always forget how to do this, so here's a writeup.

Preparing the packages

That's bog standard Debian packaging procedure.

In our case it's slightly more complicated as the packages are interdepending. sbuild is a great helper here, as it allows me to inject packages into the build (rather than fetching all from Debian) using the --extra-package= flag. Event better, we can inject a directory full of packages (using the same flag). I found that I need to pass the full path (packages in relative paths are not found for whatever reasons).

As always I'm using gbp-buildpackage (which is configured to use sbuild). My ~/.gbp.conf contains something like the following, so I have a nice folder where all the .debs and friends are stored:

1[buildpackage]
2export-dir = ../_build-area/

My directory layout for packaging is something like this:

  • ./_build-area (this is were all the build-artifacts are stored by gbp-buildpackage)
  • ./pkg1 (the source package pkg1; e.g. gavl)
  • ./pkg2 (the source package pkg2; e.g. gmerlin)
  • ./pkg1-debs (here I put the interesting binary packages produced by pkg1 (libraries, and headers) )

So let's build all the interdependent packages:

  1. Build the 1st source package pkg1 (that is: gavl)

    1cd gavl
    2gbp buildpackage
    
  2. Put the new packages needed for the next source package into the pkg1-debs

    1cp ../_build-area/libgavl[0-9]_* libgavl-dev_* ../gavl-debs
    
  3. Build the 2nd source package pkg2 (that is: gmerlin)

    1cd ../gmerlin
    2gbp buildpackage --extra-package=$(realpath ../gavl-debs)
    
  4. Repeat ad nauseam

Upload to experimental

Because we go through NEW (as we introduce new binary packages), the next thing is to upload to experimental. I always have problems with dgit with uploading to experimental/NEW, so I good all dput.

The package versions get a ~exp1 prefix (e.g. 1.0.0-1~exp1), which we will drop once the packages are cleared for upload to unstable (so the package that hits unstable is something like 1.0.0-1 rather than 1.0.0-2).

The packages now await review from the FTP masters, which can take a while.

I was super-lucky this time, as the packages only had to wait for 2 days in the queue. Thanks FTP-masters for your great and relentless work ❤️!

Build reverse dependencies

While waiting for the NEW queue, there is time to make sure that all reverse build dependencies (packages that need our new packages to build), won't break by the upgrade.

There's a super-nice tool named ratt ("Rebuild All The Things") that can be used to do a rebuild of all the reverse dependencies.

The documentation of ratt is abysmal (#1002003, but luckily it's rather simple to use:

1ratt gavl_2.0.0~svn6298-1~exp1_amd64.changes

This will get the sources for all reverse build dependencies and attempt to rebuild them with the deb-files mentioned in the .changes file already installed (so hopefully satisfying the Build-Dependencies instead of the outdated packages).

Unfortunately I found this is too simple for my case (multiple interdepending packages), as it will only inject the packages mentioned in the .changes file. One could probably just hack that file to include all (and only) the new packages, but I went for another route: doing manually whatever ratt does for us.

We can inspect what it does via the -dry_run flag, and notice that it actually just invokes sbuild --extra-package=.... The dry-run flag also lists all the packages it needs to rebuild, so we write down that list and invoke sbuild for each reverse build dependency, injecting all the packages we want to test.

package library success?
frei0r 1.7.0-2 😄
gem 1:0.94-5 💥
liquidsoap 2.0.2-1 😄
ocaml-gavl 0.1.6-1 😄
pd-readanysf 0.43-3 💥

It's only the Pd pakckages that fail, and I'm responsible for them, which is cool as now I can fix the problems I have caused...

Fix the bugs (where it's possible)

As the change introduces FTBFS problems with some of the packages, I really need to prepare some fixes (obviously for my packages; but while I'm it, I should also do so for others)

File bugs for the failing packages

For all the packages that failed to build against our new libraries, we file bugs of severity important (using reportbug).

Something like this:

 1Subject: pd-readanysf: FTBFS with gmerlin-avdecoder 2.0
 2Package: pd-readanysf
 3Version: 0.43-3
 4Severity: important
 5Tags: ftbfs
 6
 7Dear Maintainer,
 8
 9pd-readanysf fails to build from source with the
10gavl/gmerlin/gmerlin-avdecoder 2.0 stack that currently
11sits in experimental.

If I managed to prepare a fix for the FTBFS, the corresponding debdiff should be attached (if the package is maintained by others).

Prepare the library transition

reportbug release.debian.org (and answering the questions), will prepare a stub bug-report to request a new library transition. (including a sample Ben file)

It's required to provide some context, and explain which testing has been done so far.

 1Subject: transition: gavl
 2Package: release.debian.org
 3User: release.debian.org@packages.debian.org
 4Usertags: transition
 5Severity: normal
 6
 7The latest upstream of gavl includes a soname bump of libgavl.
 8The Debian packages have updated their names accordingly.
 9
10The new gavl has been uploaded to experimental and has passed
11the NEW queue.
12I've done test-builds of all immediate reverse-dependencies as
13indicated by
14https://release.debian.org/transitions/html/auto-gavl.html.
15The list of reverse dependencies is:
16- gmerlin/gmerlin-avdecoder/gmerlin-encoder
17- frei0r
18- liquidsoap
19- ocaml-gavl
20
21gmerlin/gmerlin-avdecoder/gmerlin-encoder are sibling projects of gavl.
22Versions compatible with (and requiring) libgavl2 are waiting in
23experimental (and a required library transition will be requested from
24those of these packages that provide libraries will be requested shortly).
25
26As for the other packages (frei0r, ocaml-gavl and liquidsoap),
27I haven't encountered any build problems on any of them.
28I don't expect any runtime problems.
29
30Thanks for your consideration.
31gdasmr
32IOhannes
33
34Ben file:
35
36title = "gavl";
37is_affected = .depends ~ "libgavl1" | .depends ~ "libgavl2";
38is_good = .depends ~ "libgavl2";
39is_bad = .depends ~ "libgavl1";

After that it's time to wait for an ACK from release-time.

Uploading to unstable

I failed the transition bug on 2022-02-07, and five days later on 2022-02-12 I received an ACK from the release-team, suggesting that I should group the transitions of the various source packages together.

Let's do that.

The packages have (practically) no changes, so we only need to:

  • Remove the ~exp1 version suffix (so now the version is something like 1.0.0-1)

  • Add a line to the changelog that says:

    Upload to unstable.

  • Set the distribution to unstable.

After rebuilding all the packages (repeating the --extra-package dance), we can finally upload the packages:

1dgit push-source

And don't forget to push the changes (and tags) to salsa with git push...

Further reading

https://wiki.debian.org/Teams/ReleaseTeam/Transitions