VDR plug-in dependencies

In the past, when upgrading Debian VDR and VDR plug-in packages, it could happen, that one or more plug-ins were not updated (maybe because they haven’t been uploaded yet or haven’t migrated to testing). This could be problematic, because the new VDR might have a changed ABI (Application Binary Interface), causing any old plug-ins to be unloadable due to their ABI incompatibility. Such an ABI incompatibility could also happen, when the VDR package was built with any optional patches, but the plug-in wasn’t compiled against the patched VDR headers.

To avoid crashes with such incompatible plug-ins, the wrapper script that starts VDR checked at runtime, if a plug-in matches the “patchlevel” (a string identifier in a custom control field of the Debian package, listing the names of the applied optional patches) and if the plug-in was loadable at all. This check was pretty slow, because it relied on getting the pachtlevel information via dpkg, so we recently introduced some kind of caching, which made the VDR start up procedure even more complicated.

When this topic came up again recently with bug report #489914, I had the idea to replace the weak runtime compatibility test with install time dependency checks using Debians virtual package / “Provides” feature. It’s a pretty simple solution and I’m wondering, why I haven’t thought about this before.

This is how it works: The VDR-Package has a ”Provides: vdr-abi-1.6.0-debian” entry in it’s control file and the VDR plug-ins just have a dependency on ”vdr-abi-1.6.0-debian”. This way you can’t install a plug-in without having a compatible VDR installed and vice versa. Any changes in VDR’s ABI must be reflected in the virtual package name like ”vdr-abi-1.6.0-debian-1” when having added a patch to the Debian package or ”vdr-abi-1.6.1-debian” when a new upstream version introduces a new ABI.

Under the hood, there’s happening a little bit more. With the VDR header package vdr-dev, /usr/share/vdr-dev/abi-version will be installed, which contains the ABI version name used in the Provides-field. It also installs /usr/share/vdr-dev/dependencies.sh which plug-ins may use to create a ${vdr:Depends) substitution variable, that will hold the correct ABI version name. So everything a plug-in has to do, is to have a ”Depends: ${vdr:Depends)” in its control file and to to call dependencies.sh during the build process.

The ABI version name, that the VDR package will use, is specified in debian/abi-version and from there finds it’s way to the “Provides”-field in the control file via the ${vdr:Provides} substition variable. It’s the package maintainers responsibility to change the ABI version name with every ABI changes that might be introduced in a new package release. The C++ ABI compatibility is well documented by the KDE team in “Policies/Binary Compatibility Issues With C++”

As a small safety network, the VDR package will check at build-time, if any of the applied patches (debian/patches) has been modified, by keeping a list of MD5 sums of all patches in debian/.vdr-patches. If a patch changes, the build will break until the md5 sums are manually updated with debian/rules accept-patches. Before doing this, the package maintainer should check, if any of the changed patches may affect the ABI-version and in this case has to modify the ABI version name in debian/abi-version.

This mechanism also supports building VDR in different “patch flavours”. By setting the environment variable “PATCHVARIANT”, a different set of patches from debian/patches can be selected. e.g.;

PATCHVARIANT=multipatch dpkg-buildpackage -tc -uc -us -rfakeroot

This will use the patches listed in debian/patches/00list.multipatch and it will use debian/abi-version.multipatch and debian/.vdr-patches.multipatch. The ABI version of such a patch variant should differ from the “vanilla” ABI version and all other patch variants, e.g.; “vdr-abi-1.6.0-multipatch-2008-07-26”.

The patch variants included in the packages available at e-tobi.net are “multipatch” and “extensions”. The official Debian VDR package will only contain the “multipatch” variant (but only a vanilla VDR is available as binary packages in Debian!).

To build your own patch variant, you have to:

  1. copy debian/patches/00list (or 00list.extensions) to debian/patches.00list.mypatchvariant
  2. enable the patches you would like to use in debian/patches.00list.mypatchvariant by uncommenting/commenting them (keep in mind, that some patches depend on each other and therefore some combination might lead to rejects, that you have to resolve yourself)
  3. PATCHVARIANT=mypatchvariant debian/rules accept-patches
  4. PATCHVARIANT=mypatchvariant dpkg-buildpackage -tc -uc -us -rfakeroot
  5. install the new vdr-dev
  6. build ALL the plug-ins you would like to use

Tags , , ,

Posted in , | Posted on 27 Jul 2008 08:33by Tobi | no comments